@revenera/swm-dm-ui
v3.2.3
Published
Dynamic Monetization UI Component Library
Readme
Dynamic Monetization UI
Dynamic Monetization UI is a React component library with TypeScript support that primarily exposes ready-to-use UI pages for embedding into other applications via npm.
Under the hood, Dynamic Monetization UI uses Material UI (MUI v6) as its component library and theming foundation. For more information, see the official MUI v6 documentation: https://v6.mui.com
Contents
How to use Dynamic Monetization UI in your React application
Install the package
npm install @revenera/swm-dm-uiInstall peer dependencies
If you do not already have compatible versions of the peer dependencies (such as React or MUI v6) installed in your project, install them along with the library:
npm install "react@^18.0.0 || ^19.0.0" "react-dom@^18.0.0 || ^19.0.0" @mui/material@^6.4.0 @mui/icons-material@^6.4.0 @mui/x-date-pickers@^7.23.0 @emotion/react@^11.0.0 @emotion/styled@^11.0.0 dayjs@^1.11.0 axios@^1.19.0 yup@^1.0.0 formik@^2.4.6 i18next@^25.6.0 react-i18next@^16.2.4 react-virtualized@^9.22.0If you already have compatible versions of some dependencies (for example, if your app already uses MUI v6), you can omit them from the install command:
Supported versions
| Package | Supported Versions | | ------------------- | ------------------ | | react | ^18.0.0 or ^19.0.0 | | react-dom | ^18.0.0 or ^19.0.0 | | @mui/material | ^6.4.0 | | @mui/icons-material | ^6.4.0 | | @mui/x-date-pickers | ^7.23.0 | | @emotion/react | ^11.0.0 | | @emotion/styled | ^11.0.0 | | dayjs | ^1.11.0 | | axios | ^1.19.0 | | yup | ^1.7.1 | | formik | ^2.4.6 | | react-virtualized | ^9.22.0 | | i18next | ^25.6.0 | | react-i18next | ^16.2.4 |
Basic implementation
The basic implementation provides an out-of-the-box, ready-to-use solution with:
- Default localization (for example,
en) and built-in i18n support - Default styling/theme, so pages render correctly without additional UI setup
- A complete customer journey for the selected flow (for example, Rate Tables or Instances), packaged as a single embeddable React component
Auth headers (apiConfig.headers) are optional
apiConfig.headers is optional by design so you can integrate in either of these common ways:
Proxy backend
- Your React app calls your own backend/proxy endpoints.
- Do not pass bearer tokens in React.
- Omit
apiConfig.headers; your backend uses its own auth mechanism and forwards requests to DM.
Direct DM API calls with bearer token
- Your React app calls DM endpoints directly.
- Pass
Authorization(and any other required headers) viaapiConfig.headers. - Use this when your architecture intentionally allows frontend-managed API tokens.
This flexibility helps adopters choose the model that best fits their security and deployment architecture.
DM Rate Table App
DMRateTableApp provides the complete Rate Table management experience, including:
- Rate Table list/management
- View Rate Table
- Create Rate Table
Embed it as a single component:
import React from 'react';
import { DMRateTableApp } from '@revenera/swm-dm-ui';
export default function App() {
return (
<DMRateTableApp
apiConfig={{
rateTableApiUrl: 'https://example.com/dynamicmonetization/v2/api/rate-tables',
headers: { Authorization: 'Bearer YOUR_BEARER_TOKEN' },
}}
isProducer={true}
/>
);
}DMRateTableApp supported props
| Prop | Type | Required | Description |
| --------------------------- | ------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| apiConfig.rateTableApiUrl | string | Yes | Full URL for the Rate Tables API. |
| apiConfig.headers | Record<string, string> | No | Optional request headers. Use for direct DM calls (for example bearer token); omit when your backend/proxy handles auth. |
| isProducer | boolean | Yes | Enables producer-mode behavior where applicable. |
| locale | string | No | Locale used for i18n (default: "en"). |
| i18Resources | Record<string, any> | No | Consumer provided translations, overrides defaults. |
DM Instances App
DMInstancesApp provides the complete Instances experience, including:
- Instances list
- Instance details overview
- Instance details line items
Embed it as a single component:
import React from 'react';
import { DMInstancesApp } from '@revenera/swm-dm-ui';
export default function App() {
return (
<DMInstancesApp
showLineItemsConsumptionLimits
canEditLineItemsConsumptionLimits
apiConfig={{
instancesApiUrl: 'https://example.com/dynamicmonetization/v2/api/instances',
getLineItemsApiUrl: (id) =>
`https://example.com/dynamicmonetization/v2/api/instances/${id}/line-items`,
getOverviewApiUrl: (id) => `https://example.com/dynamicmonetization/v2/api/instances/${id}`,
getConsumptionLimitsLineItemsApiUrl: (instanceId: string, lineItemId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}/consumption-limits',
getLineItemByIdApiUrl: (instanceId: string, lineItemId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}',
getRequestersForAConsumptionLimitOfALineItemApiUrl: (instanceId: string, lineItemId: string, limitId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}/consumption-limits/${limitId}/requesters`,
headers: { Authorization: 'Bearer YOUR_BEARER_TOKEN' },
}}
/>
);
}DMInstancesApp supported props
| Prop | Type | Required | Description |
| -------------------------------------------------------------- | ----------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| apiConfig.instancesApiUrl | string | Yes | Full URL for the Instances list API. |
| apiConfig.getLineItemsApiUrl | (instanceId: string) => string | Yes | Function returning the full URL for an instance's line items. |
| apiConfig.getOverviewApiUrl | (instanceId: string) => string | Yes | Function returning the full URL for an instance's overview/details. |
| apiConfig.getConsumptionLimitsLineItemsApiUrl | (instanceId: string, lineItemId: string) | No | Function returning the full URL for a line item consumption limits. This props is required if showLineItemsConsumptionLimits is true |
| apiConfig.getRequestersForAConsumptionLimitOfALineItemApiUrl | (instanceId: string, lineItemId: string, limitId: string) | No | Function returning the full URL for requesters being tracked against a consumption limit of a line item. This props is required if showLineItemsConsumptionLimits is true |
| apiConfig.getLineItemByIdApiUrl | (instanceId: string, lineItemId: string) | No | Function returning the full URL for a getting a line item by line item id. |
| apiConfig.headers | Record<string, string> | No | Optional request headers. Use for direct DM calls (for example bearer token); omit when your backend/proxy handles auth. |
| showLineItemsConsumptionLimits | boolean | No | Enable consumption limits for line items view. If this is true, then apiConfig.getConsumptionLimitsLineItemsApiUrl becomes a required prop. |
| canEditLineItemsConsumptionLimits | boolean | No | If true, Edit features will be enabled for line item consumption limits |
| locale | string | No | Locale used for i18n (default: "en"). |
| i18Resources | Record<string, any> | No | Consumer provided translations, overrides defaults. |
End Customer Instance App
DMEndCustomerInstanceApp provides an end-customer view of a single instance.
Embed it as a single component:
import React from 'react';
import { DMEndCustomerInstanceApp } from '@revenera/swm-dm-ui';
export default function App() {
return (
<DMEndCustomerInstanceApp
apiConfig={{
instancesApiUrl: 'https://example.com/dynamicmonetization/v2/api/instances',
getLineItemsApiUrl: (id) =>
`https://example.com/dynamicmonetization/v2/api/instances/${id}/line-items`,
getConsumptionLimitsLineItemsApiUrl: (instanceId: string, lineItemId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}/consumption-limits',
getRequestersForAConsumptionLimitOfALineItemApiUrl: (instanceId: string, lineItemId: string, limitId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}/consumption-limits/${limitId}/requesters`,
getLineItemByIdApiUrl: (instanceId: string, lineItemId: string) =>
`https://example.com/dynamicmonetization/v2/api/instances/${instanceId}/line-items/${lineItemId}',
headers: { Authorization: 'Bearer YOUR_BEARER_TOKEN' },
}}
accountId="test-account-id"
pageTitle="My Entitlements"
showLineItemsConsumptionLimits
canEditLineItemsConsumptionLimits
/>
);
}DMEndCustomerInstanceApp supported props
| Prop | Type | Required | Description |
| -------------------------------------------------------------- | ----------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| apiConfig.getLineItemsApiUrl | (id: string) => string | Yes | Function returning the full URL for the instance's line items. |
| apiConfig.headers | Record<string, string> | No | Optional request headers. Use for direct DM calls (for example bearer token); omit when your backend/proxy handles auth. |
| apiConfig.instancesApiUrl | string | Yes | Full URL for the instances list API. |
| apiConfig.getConsumptionLimitsLineItemsApiUrl | (instanceId: string, lineItemId: string) | No | Function returning the full URL for a line item consumption limits. This props is required if showLineItemsConsumptionLimits is true |
| apiConfig.getRequestersForAConsumptionLimitOfALineItemApiUrl | (instanceId: string, lineItemId: string, limitId: string) | No | Function returning the full URL for requesters being tracked against a consumption limit of a line item. This props is required if showLineItemsConsumptionLimits is true |
| apiConfig.getLineItemByIdApiUrl | (instanceId: string, lineItemId: string) | No | Function returning the full URL for a getting a line item by line item id. |
| accountId | string | Yes | Account Id string. |
| pageTitle | string | No | Optional page title override. |
| showLineItemsConsumptionLimits | boolean | No | Enable consumption limits for line items view. If this is true, then apiConfig.getConsumptionLimitsLineItemsApiUrl becomes a required prop. |
| canEditLineItemsConsumptionLimits | boolean | No | If true, Edit features will be enabled for line item consumption limits |
| locale | string | No | Locale used for i18n (default: "en"). |
| i18Resources | Record<string, any> | No | Consumer provided translations, overrides defaults. |
Customization
If you need more control over styling, routing, composition, or API endpoint configuration than the single "App" components provide, instead of embedding a full flow (DMRateTableApp, DMInstancesApp, etc.), you can embed smaller root and page-level building blocks and configure them inside your application (for example, under your own MUI theme, routes, layouts, authentication, and navigation).
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { ThemeProvider, CssBaseline } from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import {
DMTheme,
DMRateTableRoot,
DMLibraryTranslations,
DMRateTableCreate,
DMRateTableForm,
DMViewRateTables,
DMInstancesRoot,
DMViewInstances,
DMInstanceDetails,
DMEndCustomerInstanceDetails,
} from '@revenera/swm-dm-ui';
import i18n from 'i18next';
import { initReactI18next, I18nextProvider } from 'react-i18next';
import dayjs from 'dayjs';
const RATE_TABLE_URL = 'https://example.com/dynamicmonetization/v2/api/rate-tables';
const INSTANCES_URL = 'https://example.com/dynamicmonetization/v2/api/instances';
const HEADERS = { Authorization: 'Bearer YOUR_BEARER_TOKEN' };
i18n.use(initReactI18next).init({
resources: {
en: { translation: DMLibraryTranslations.en },
fr: { translation: DMLibraryTranslations.fr },
},
lng: 'en',
fallbackLng: 'en',
interpolation: { escapeValue: false },
});
// Example of adding a custom translation key
i18n.addResource('en', 'translation', 'dm.rateTableView.heading', 'Custom Header');
function DMShell({ children }: { children: React.ReactNode }) {
//You can replace DMTheme with your custom MUI theme that extends DMTheme
//to ensure compatibility with DM components while applying your own styling.
return (
<I18nextProvider i18n={i18n}>
<ThemeProvider theme={DMTheme}>
<CssBaseline />
<LocalizationProvider dateAdapter={AdapterDayjs}>{children}</LocalizationProvider>
</ThemeProvider>
</I18nextProvider>
);
}
export default function App() {
return (
<DMShell>
<Routes>
<Route
path="rate-table-root"
element={
<DMRateTableRoot
apiConfig={{ rateTableApiUrl: RATE_TABLE_URL, headers: HEADERS }}
isProducer={true}
/>
}
/>
<Route
path="rate-table-view"
element={
<DMViewRateTables
apiConfig={{ rateTableApiUrl: RATE_TABLE_URL, headers: HEADERS }}
isProducer={true}
onCreateClick={() => alert('Create clicked!')}
onView={() => alert('View clicked!')}
onCopy={() => alert('Copy clicked!')}
/>
}
/>
<Route
path="rate-table-create"
element={
<DMRateTableCreate
apiConfig={{ rateTableApiUrl: RATE_TABLE_URL, headers: HEADERS }}
afterSaveAction={() => alert('Rate table created!')}
onCancelAction={() => alert('Cancelled')}
/>
}
/>
<Route
path="rate-table-form"
element={
<DMRateTableForm
heading="Test Heading"
isEditable={true}
initialValues={{
series: 'Test Series',
effectiveFrom: dayjs(),
version: '1.0',
items: [{ name: 'Item 1', version: '1.0', rate: 100 }],
}}
onSubmit={() => alert('Submitted!')}
onCancel={() => alert('Cancelled')}
onBack={() => alert('Back!')}
loading={false}
error=""
saving={false}
/>
}
/>
<Route
path="instances-root"
element={
<DMInstancesRoot
showLineItemsConsumptionLimits
canEditLineItemsConsumptionLimits
apiConfig={{
instancesApiUrl: INSTANCES_URL,
getLineItemsApiUrl: (id) => `${INSTANCES_URL}/${id}/line-items`,
getOverviewApiUrl: (id) => `${INSTANCES_URL}/${id}`,
getConsumptionLimitsLineItemsApiUrl: (instanceId: string, lineItemId: string) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}/consumption-limits`,
getLineItemByIdApiUrl: (instanceId: string, lineItemId: string) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}`,
getRequestersForAConsumptionLimitOfALineItemApiUrl: (
instanceId: string,
lineItemId: string,
limitId: string,
) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}/consumption-limits/${limitId}/requesters`,
headers: HEADERS,
}}
/>
}
/>
<Route
path="instances-view"
element={
<DMViewInstances
isProducer={true}
apiConfig={{ instancesApiUrl: INSTANCES_URL }}
onCreateClick={() => alert('Create instance clicked!')}
onInstanceIdClick={({ instanceId }) => alert(`Instance ${instanceId} clicked!`)}
/>
}
/>
<Route
path="instances-details"
element={
<DMInstanceDetails
isProducer={true}
apiConfig={{
overviewApiUrl: `${INSTANCES_URL}/instance-id-123`,
lineItemsApiUrl: `${INSTANCES_URL}/instance-id-123/line-items`,
headers: HEADERS,
}}
onBackToList={() => alert('Back to list!')}
hasBackLink={true}
pageTitle="Instance Details"
/>
}
/>
<Route
path="end-customer-instance-details"
element={
<DMEndCustomerInstanceDetails
showLineItemsConsumptionLimits
canEditLineItemsConsumptionLimits
apiConfig={{
instancesApiUrl: INSTANCES_URL,
getLineItemsApiUrl: (id) => `${INSTANCES_URL}/${id}/line-items`,
getConsumptionLimitsLineItemsApiUrl: (instanceId: string, lineItemId: string) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}/consumption-limits`,
getLineItemByIdApiUrl: (instanceId: string, lineItemId: string) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}`,
getRequestersForAConsumptionLimitOfALineItemApiUrl: (
instanceId: string,
lineItemId: string,
limitId: string,
) =>
`${INSTANCES_URL}/${instanceId}/line-items/${lineItemId}/consumption-limits/${limitId}/requesters`,
headers: HEADERS,
}}
accountId="test-account-id"
pageTitle="End Customer Instance Details"
/>
}
/>
</Routes>
</DMShell>
);
}DMProvider
DMProvider is a UI-only context provider for theme, localization, and i18n. API configuration is passed directly to each component — not to DMProvider.
import React from 'react';
import { DMRateTableRoot, DMProvider } from '@revenera/swm-dm-ui';
export default function App() {
return (
<DMProvider locale="en">
<DMRateTableRoot
apiConfig={{
rateTableApiUrl: 'https://example.com/dynamicmonetization/v2/api/rate-tables',
headers: { Authorization: 'Bearer YOUR_BEARER_TOKEN' },
}}
isProducer={true}
/>
</DMProvider>
);
}