@rytass/wms-module-react
v0.2.0
Published
Rytass WMS Module — React components, hooks, Apollo client factory and GraphQL operations for warehouse management
Maintainers
Readme
@rytass/wms-module-react
Drop-in React UI for the Rytass Warehouse Management System (WMS) — full admin screens (loaders, materials, locations, inventory list / count / movement, receive / ship orders, change history, maps, label search), context providers, generic hooks, an Apollo Client factory and pre-generated typed GraphQL operations.
Pair with @rytass/wms-module-graphql on the server side. Works with both the Next.js 15 Pages Router and App Router — you pick the matching router bridge at the app root (see below).
Install
yarn add @rytass/wms-module-react
# peer deps
yarn add react react-dom next @apollo/client graphql \
@mezzanine-ui/core @mezzanine-ui/system @mezzanine-ui/react @mezzanine-ui/icons \
react-hook-form @hookform/error-message @hookform/resolvers yup nuqs lodash luxonRouter support — Pages and App Router since v0.2.0. Components no longer import
next/routerdirectly; navigation is injected through aWmsRouterProvider. Mount the bridge that matches your app:
- Pages Router →
@rytass/wms-module-react/router/pages(WmsPagesRouterProvider)- App Router →
@rytass/wms-module-react/router/app(WmsAppRouterProvider)Migrating from v0.1.x (breaking): v0.1.x reached into
next/routerautomatically. From v0.2.0 you must wrap the tree in one of the two bridges (below) — without it, components throwuseWmsRouter must be used within a WmsRouterProvider. Also pick the matchingNuqsAdapter(nuqs/adapters/next/pagesvs.../app).
Next.js setup
Add the package to Next's transpilePackages so its CSS Modules and ESM bundles are processed:
// next.config.js
module.exports = {
transpilePackages: [
'@mezzanine-ui/core',
'@mezzanine-ui/system',
'@mezzanine-ui/react',
'@mezzanine-ui/icons',
'@rytass/wms-module-react',
],
rewrites: async () => [
{
source: '/graphql',
destination: `${process.env.API_URL ?? 'http://localhost:7103'}/graphql`,
},
],
};Mounting the providers
The provider stack is identical across both routers — only the router bridge and the NuqsAdapter import path differ.
Pages Router
// pages/_app.tsx
import '@mezzanine-ui/core/style/index.css';
import { AppProps } from 'next/app';
import { ApolloProvider } from '@apollo/client/react';
import CalendarConfigProviderDayjs from '@mezzanine-ui/react/Calendar/CalendarConfigProviderDayjs';
import { NuqsAdapter } from 'nuqs/adapters/next/pages';
import WmsPagesRouterProvider from '@rytass/wms-module-react/router/pages';
import {
ApolloClient,
DialogProvider,
InventoryActionsProvider,
ModalProvider,
} from '@rytass/wms-module-react';
export default function App({ Component, pageProps }: AppProps) {
return (
<ApolloProvider client={ApolloClient}>
<CalendarConfigProviderDayjs>
<NuqsAdapter>
<WmsPagesRouterProvider>
<InventoryActionsProvider>
<DialogProvider>
<ModalProvider>
<Component {...pageProps} />
</ModalProvider>
</DialogProvider>
</InventoryActionsProvider>
</WmsPagesRouterProvider>
</NuqsAdapter>
</CalendarConfigProviderDayjs>
</ApolloProvider>
);
}App Router
Put the whole stack in a single 'use client' providers component and render it from the root layout. Swap the bridge for WmsAppRouterProvider and the adapter for nuqs/adapters/next/app:
// app/providers.tsx
'use client';
import { ReactNode } from 'react';
import { ApolloProvider } from '@apollo/client/react';
import CalendarConfigProviderDayjs from '@mezzanine-ui/react/Calendar/CalendarConfigProviderDayjs';
import { NuqsAdapter } from 'nuqs/adapters/next/app';
import WmsAppRouterProvider from '@rytass/wms-module-react/router/app';
import {
ApolloClient,
DialogProvider,
InventoryActionsProvider,
ModalProvider,
} from '@rytass/wms-module-react';
export default function Providers({ children }: { children: ReactNode }) {
return (
<ApolloProvider client={ApolloClient}>
<CalendarConfigProviderDayjs>
<NuqsAdapter>
<WmsAppRouterProvider>
<InventoryActionsProvider>
<DialogProvider>
<ModalProvider>{children}</ModalProvider>
</DialogProvider>
</InventoryActionsProvider>
</WmsAppRouterProvider>
</NuqsAdapter>
</CalendarConfigProviderDayjs>
</ApolloProvider>
);
}// app/layout.tsx
import '@mezzanine-ui/core/style/index.css';
import { ReactNode } from 'react';
import Providers from './providers';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}A runnable reference lives in apps/example-app-router.
ApolloClient is a ready-to-use singleton that POSTs to /graphql (use the rewrite above to forward to your backend). Need a custom configuration? Call createApolloClient() instead and wire your own links / cache.
Mounting pages
Each WMS screen is exported as a default-named component. Drop them into a route shell:
// Pages Router — pages/loaders-management/index.tsx
import { LoadersManagement } from '@rytass/wms-module-react';
export default function LoadersManagementPage() {
return <LoadersManagement />;
}// App Router — app/loaders-management/page.tsx
import { LoadersManagement } from '@rytass/wms-module-react';
export default function LoadersManagementPage() {
return <LoadersManagement />;
}The barrel ships a 'use client' directive, so importing a page into an App Router server component automatically marks the re-exported subtree as a client boundary — no extra 'use client' needed in your shell. Dynamic detail screens read their route param ([id]) through the active bridge, so the App Router file lives at e.g. app/receive-inventory-orders/[id]/edit/page.tsx.
Available top-level pages: ChangeHistory, InventoryCount, InventoryList, InventoryMovement, LabelSearch, LoadersManagement, LocationsManagement, Maps, MaterialsManagement, ReceiveInventoryOrders, ShipInventoryOrders. Dynamic-route detail screens: CreateLoader, EditReceiveInventoryOrder, ViewReceiveInventoryOrder, EditShipInventoryOrder, ViewShipInventoryOrder, EditTransferOrder.
Route constants
The lib hard-codes the route paths in the NextPath enum and useRoutes() hook (used to build the sidebar). For v0.1.0, consumers must mount the page components at the same URL paths the lib expects. A future version will accept a routing strategy hook.
import { NextPath, useRoutes } from '@rytass/wms-module-react';
// NextPath.LOADERSMANAGEMENT === '/loaders-management'GraphQL operations
All typed mutations / queries / fragments are pre-generated as TypedDocumentNodes and re-exported from the package root. Consumers do not need to run graphql-codegen:
import { useLoadersQuery, AggregatedStockFragment } from '@rytass/wms-module-react';Known issues for standalone consumers
@mezzanine-ui/react (a peer dependency) ships JavaScript files written in ESM syntax but does not set "type": "module" in its package.json, and its files import lodash subpaths without explicit .js extensions (e.g. import compact from 'lodash/compact'). This combination fails Node's ESM resolver when this lib (which is "type": "module") imports Mezzanine UI at SSR time on a fresh npm-installed Next.js app.
The Rytass internal monorepo does not hit this because apps/client builds the lib from source through a tsconfig path alias — Next.js's webpack therefore transpiles Mezzanine UI alongside the consumer code, and webpack's resolver tolerates the missing extensions. For a standalone consumer that npm installs us, you currently need one of:
- Use yarn workspaces with hoisting and run the consumer through Nx (mirrors the Rytass setup).
- Wait for Mezzanine UI to publish a corrected ESM build.
- Pre-bundle Mezzanine UI into the consumer's app using
next.config.jstranspilePackagesplus a custom webpackresolve.extensionAlias(still does not fully cover the SSRnext startpage-data-collection step).
Track upstream progress via the Mezzanine UI repo.
Generic hooks
useColumnWidthPersistence, useFormCancel, usePreviousValue, useRoutes, useFetchAllOptions, useFetchMoreOptions, useInsertOption, useSortTable, useTablePageState, useTablePageTotal — useful for custom screens that follow the same conventions as the bundled pages.
Documentation
Full documentation is shipped inside this package under the docs/ directory (available after npm install):
| Document | Description |
|---|---|
| docs/integration-guide.md | Step-by-step wiring guide for NestJS + Next.js consumers |
| docs/api-reference.md | Complete export catalog with signatures and usage examples |
GitHub hosted links (always up-to-date):
- Integration Guide — §5 Frontend setup
- Integration Guide — §6 Pages Router shell pattern
- Integration Guide — §7 Apollo client wiring
- Integration Guide — §8 Authentication / authorization
- API Reference — @rytass/wms-module-react
License
MIT
