@wim4you/davinci.react.library
v1.0.8
Published
The `ActionBar` is a customizable React component designed to provide a toolbar with common actions such as edit, save, cancel, delete, publish, request approval, and more. Built with Material-UI, it integrates seamlessly with React applications and suppo
Readme
@wim4you/davinci.react.library
ActionBar Component
The ActionBar is a customizable React component designed to provide a toolbar with common actions such as edit, save, cancel, delete, publish, request approval, and more. Built with Material-UI, it integrates seamlessly with React applications and supports permission-based action rendering, approval workflows, and custom actions.
Installation
To use the ActionBar component, ensure you have the required dependencies installed:
npm install @mui/material @mui/icons-material material-ui-confirm react-router-domEnsure you have a peer dependency of React and React DOM installed.
Usage
The ActionBar component is a functional React component that renders a toolbar with action buttons based on provided props. It supports edit mode toggling, approval workflows, and custom actions.
Basic Example
import React, { useState } from 'react';
import { ActionBar } from './ActionBar';
import { ApprovalStatusEnum } from './enums/ApprovalEnums';
const MyComponent = () => {
const [editMode, setEditMode] = useState(false);
return (
<ActionBar
objectId="123"
backURL="/list"
userPermissions={[1, 2]}
actions={{
back: { enabled: true },
edit: { enabled: true, permissionKey: 1 },
delete: { enabled: true, permissionKey: 2 },
requestApproval: { enabled: true, permissionKey: 1 },
publish: { enabled: true, permissionKey: 1 },
newVersion: { enabled: true, permissionKey: 1 },
}}
editProps={{
editMode,
setEditMode,
defaultEditMode: false,
}}
approvalProps={{
entityKey: 'entity-123',
entityType: 'document',
approvalStatus: ApprovalStatusEnum.New,
}}
onPersist={() => console.log('Persist action triggered')}
onCancel={() => console.log('Cancel action triggered')}
onDelete={() => console.log('Delete action triggered')}
onPublish={() => console.log('Publish action triggered')}
onNewVersion={() => console.log('New version action triggered')}
onRefresh={() => console.log('Refresh action triggered')}
/>
);
};
export default MyComponent;Adding Custom Actions
You can pass custom React nodes to the customActions prop to extend the toolbar:
import React, { useState } from 'react';
import { ActionBar } from './ActionBar';
import { IconButton } from '@mui/material';
import { StarTwoTone } from '@mui/icons-material';
const MyComponent = () => {
const [editMode, setEditMode] = useState(false);
const customActions = (
<IconButton title="Favorite">
<StarTwoTone />
</IconButton>
);
return (
<ActionBar
editProps={{ editMode, setEditMode }}
customActions={customActions}
// ... other props
/>
);
};Props
The ActionBar component accepts the following props:
| Prop | Type | Description | Required | Default |
|-------------------|-----------------------------------|-----------------------------------------------------------------------------|----------|---------|
| disabled | boolean | Disables all action buttons in the toolbar. | No | false |
| objectId | string \| number | Identifier for the object being acted upon. | No | - |
| backURL | string | URL to navigate to when the back button is clicked. | No | - |
| baseUrl | string | Base URL for API requests (used in approval workflows). | No | - |
| userPermissions | number[] | Array of user permission keys to check against action permissions. | No | - |
| actions | Object | Configuration for action buttons (see IAction interface below). | No | - |
| editProps | Object | Configuration for edit mode (see editProps details below). | Yes | - |
| approvalProps | Object | Configuration for approval workflows (see approvalProps details below). | No | - |
| onToList | CallableFunction | Callback for navigating to the list view. | No | - |
| onPersist | CallableFunction | Callback triggered when saving changes. | No | - |
| onCancel | CallableFunction | Callback triggered when canceling edit mode. | No | - |
| onRevokeVersion | CallableFunction | Callback triggered when revoking a version. | No | - |
| onNewVersion | CallableFunction | Callback triggered when creating a new version. | No | - |
| onPublish | CallableFunction | Callback triggered when publishing. | No | - |
| onDelete | CallableFunction | Callback triggered when deleting an item. | No | - |
| onRefresh | CallableFunction | Callback triggered when refreshing the data. | No | - |
| customActions | ReactNode | Custom React nodes to render additional action buttons. | No | - |
IAction Interface
Each action in the actions prop follows this interface:
| Property | Type | Description | Required | Default |
|-----------------|--------------------------|-----------------------------------------------------------------------------|----------|---------|
| enabled | boolean | Whether the action is enabled. | Yes | - |
| permissionKey | number \| 'none' | Permission key required to enable the action. Use 'none' for no permission check. | No | - |
| tooltip | string | Tooltip text for the action button. | No | - |
editProps Object
| Property | Type | Description | Required | Default |
|--------------------|--------------------|-----------------------------------------------------------------------------|----------|---------|
| onEdit | CallableFunction | Callback triggered when edit mode changes. | No | - |
| defaultEditMode | boolean | Initial edit mode state. | No | false |
| editMode | boolean | Current edit mode state. | Yes | - |
| setEditMode | (value: boolean) => void | Function to update the edit mode state. | Yes | - |
approvalProps Object
| Property | Type | Description | Required | Default |
|------------------|--------------------------|-----------------------------------------------------------------------------|----------|---------|
| onChanged | CallableFunction | Callback triggered after an approval request is made. | No | - |
| entityKey | string | Unique key for the entity in the approval workflow. | Yes | - |
| entityType | string | Type of entity for the approval workflow (e.g., 'document'). | Yes | - |
| approvalStatus | ApprovalStatusEnum | Current approval status (New, PendingApproval, Approved, Rejected). | Yes | - |
Approval Status Enum
The ApprovalStatusEnum defines the possible approval states:
enum ApprovalStatusEnum {
New = 'New',
PendingApproval = 'PendingApproval',
Approved = 'Approved',
Rejected = 'Rejected',
}Permission Handling
The userHasPermission utility function checks if a user has the required permission to perform an action:
userHasPermission(userPermissions: number[] | undefined, objPermission: number | 'none' | undefined): booleanAPIConnect and useAPIConnect
The APIConnect object and useAPIConnect hook provide utilities for making HTTP requests in a React application, integrating with Axios for API communication. They handle authentication via bearer tokens, support cancellation of requests, and include features like paged list retrieval, file uploads, and snackbar notifications for user feedback. These utilities are designed to work with a data product key and session-based authentication.
Installation
To use APIConnect and useAPIConnect, ensure you have the required dependencies installed:
npm install axios universal-cookieEnsure you have a peer dependency of React and React DOM installed for the useAPIConnect hook. Additionally, ensure GlobalContent is set up in your application to provide SessionGetProduct and snackbar functionality.
APIConnect Object
The APIConnect object provides methods for making HTTP requests (GET, POST, PUT, DELETE, and file uploads) with built-in support for authentication and cancellation.
Usage
Basic Example
import { APIConnect } from './APIConnect';
// Fetch a paged list
const fetchData = async () => {
try {
const data = await APIConnect.getPagedList({
dataProductKey: 'product-key',
baseurl: 'https://api.example.com',
url: '/items',
pageIndex: 0,
pageSize: 10,
filter: 'active',
globalSearch: 'search term',
columnFilters: [{ column: 'name', value: 'test' }],
sorting: [{ column: 'name', direction: 'asc' }],
});
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
// Post data
const postData = async () => {
try {
const response = await APIConnect.post({
baseurl: 'https://api.example.com',
url: '/items',
body: { name: 'New Item' },
});
console.log('Posted:', response);
} catch (error) {
console.error('Error posting data:', error);
}
};Methods
The APIConnect object provides the following methods: getPagedList Fetches a paged list of items with filtering, sorting, and search capabilities.
Parameters:
| Parameter | Type | Description | Required |
|------------------|----------|-----------------------------------------------------------------------------|----------|
| dataProductKey | string | Key for the data product. | No |
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| expand | string | Fields to expand in the response. | No |
| pageIndex | number | Page index for pagination (0-based). | No |
| pageSize | number | Number of items per page. | No |
| filter | string | General filter string. | No |
| globalSearch | string | Global search term. | No |
| columnFilters | Array | Array of column-specific filters (e.g., [{ column: 'name', value: 'test' }]). | No |
| sorting | Array | Array of sorting rules (e.g., [{ column: 'name', direction: 'asc' }]). | No |
| payload | any | Additional payload data. | No |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data. getSelectItems Fetches a list of items for use in select inputs, with search and query parameters.
getSelectItems({ baseurl, url, search, queryparams }, cancel = false): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|---------------|----------|----------------------------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| search | string | Search term for filtering items. | No |
| queryparams | string | Additional query parameters (e.g., &key=value). | No |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data. get Performs a GET request to fetch data.
get({ baseurl, url }, cancel = false): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|-----------|----------|---------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data.
post Performs a POST request to create data.
post({ baseurl, url, body }, cancel = false): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|-----------|----------|---------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| body | any | Data to send in the request body. | No |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data.
put Performs a PUT request to update data.
put({ baseurl, url, body }, cancel = false): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|-----------|----------|---------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| body | any | Data to send in the request body. | No |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data.
delete Performs a DELETE request to remove data.
delete({ baseurl, url }, cancel = false): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|-----------|----------|---------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| cancel | boolean | Enable request cancellation. | No |
Returns:
Promise - The API response data. fileUpload Performs a POST request to upload a file, with progress tracking.
fileUpload({ baseurl, url, body }, onProgress?: CallableFunction): Promise<any>Parameters:
| Parameter | Type | Description | Required |
|-------------|--------------------|----------------------------------------------------------|----------|
| baseurl | string | Base URL for the API request. | Yes |
| url | string | Endpoint URL for the request. | Yes |
| body | any | File data (e.g., FormData) to send in the request body. | Yes |
| onProgress| CallableFunction | Callback to track upload progress (percentage). | No |
useAPIConnect Hook
The useAPIConnect hook provides a React hook-based interface for making HTTP requests with loading and error state management, integrated with a snackbar for user feedback.
Usage
Example
import React from 'react';
import { useAPIConnect } from './APIConnect';
const MyComponent = () => {
const { loading, error, makeRequest } = useAPIConnect({ baseURL: 'https://api.example.com' });
const fetchData = async () => {
try {
const data = await makeRequest('/items', 'get', undefined, undefined, 'none');
console.log(data);
} catch (err) {
console.error('Error:', err);
}
};
const postData = async () => {
try {
const data = await makeRequest('/items', 'post', { name: 'New Item' }, undefined, 'onBoth');
console.log('Posted:', data);
} catch (err) {
console.error('Error:', err);
}
};
return (
<div>
<button onClick={fetchData} disabled={loading}>Fetch Data</button>
<button onClick={postData} disabled={loading}>Post Data</button>
{loading && <p>Loading...</p>}
{error && <p>Error: {error}</p>}
</div>
);
};
export default MyComponent;Hook Parameters
useAPIConnect<T>({ baseURL }: UseAPIConnectProps)Parameters:
| Parameter | Type | Description | Required |
|-----------|----------|---------------------------------------|----------|
| baseURL | string | Base URL for all API requests. | Yes |
returns:
|Property|Type|Description| |---|---|---| |loading|boolean|Indicates if a request is in progress.| |error| string or null| Error message from the last failed request, if any.| |makeRequest| (url: string, method: HttpMethod, requestData?: Record<string, any>, customConfig?: AxiosRequestConfig, messages?: Messages, cancel?: boolean, silent?: boolean) => Promise |Function to make an API request.|
makeRequest Parameters
| Parameter | Type | Description | Required | Default |
|----------------|--------------------|-----------------------------------------------------------------------------|----------|---------|
| url | string | Endpoint URL for the request. | Yes | - |
| method | HttpMethod | HTTP method (get, post, put, delete). | Yes | - |
| requestData | Record<string, any> | Data to send as query parameters or request body. | No | - |
| customConfig | AxiosRequestConfig | Custom Axios configuration to override defaults. | No | - |
| messages | Messages | Controls snackbar notifications (none, onError, onSuccess, onBoth). | No | none |
| cancel | boolean | Enable request cancellation. | No | false |
| silent | boolean | Suppress snackbar notifications. | No | false |
Returns: Promise - The API response data.
Authentication
Both APIConnect and useAPIConnect use a bearer token retrieved from a cookie (login.davinci.accesstoken) via the getToken function. The token is included in the Authorization header of all requests. Additionally, a Dataproduct-Key header is included, sourced from SessionGetProduct() or userProduct.product?.key.
Cancellation
Both utilities support request cancellation using Axios's AbortController. Pass cancel: true to enable cancellation for a request. The defineCancelApiObject utility creates cancellation handlers for each API method or hook instance.
Notes
- Error Handling: Errors are logged to the console (except for 401 errors) and rejected as promises. For useAPIConnect, errors are also stored in the error state and displayed via the snackbar.
- Snackbar Integration: The useAPIConnect hook uses the snackbar from useGlobalContent to show success/error messages. Configure messages to control when notifications appear.
- File Uploads: The fileUpload method supports progress tracking via the onProgress callback, useful for displaying upload progress bars.
- Dependencies: Ensure GlobalContent provides SessionGetProduct for APIConnect and snackbar/userProduct for useAPIConnect.
Troubleshooting
No token found: Verify that the login.davinci.accesstoken cookie is set and accessible. Requests not cancelling: Ensure cancel: true is passed and defineCancelApiObject is correctly set up. Snackbar not showing: Check that useGlobalContent provides a valid snackbar object and messages is not set to none. CORS issues: Ensure the API server allows requests from your application's origin and includes appropriate CORS headers.
For further assistance, refer to the Axios documentation or universal-cookie documentation.
Authenticate
The Authenticate module provides a RequireAuth React component and utility functions (authorized and getPermissions) for handling authentication and authorization in a React application. The RequireAuth component protects routes by checking user authentication and permissions, redirecting to login or unauthorized pages as needed. It integrates with cookies for token management, JWT decoding for user information, and the APIConnect module for fetching permissions.
Installation
To use the Authenticate module, ensure you have the required dependencies installed:
npm install react-router-dom universal-cookie jwt-decode @mui/materialEnsure you have a peer dependency of React and React DOM installed. Additionally, ensure the APIConnect module is set up in your application for fetching permissions and the ResourcesContext from BrandProvider is configured to provide a waiting background image.
Usage
The RequireAuth component is used to protect routes by checking if the user is authenticated and has the required permissions for a specific group. If the user is not authenticated, they are redirected to the /login page. If authenticated but lacking the required permissions, they are redirected to the /unauthorized page. While permissions are being fetched, a loading UI is displayed.
Basic Example
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { RequireAuth } from './Authenticate';
import ProtectedPage from './ProtectedPage';
import LoginPage from './LoginPage';
import UnauthorizedPage from './UnauthorizedPage';
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route
path="/protected"
element={
<RequireAuth groupKey="my-app-group" allowedPermissions={[1, 2]}>
<ProtectedPage />
</RequireAuth>
}
/>
<Route path="/login" element={<LoginPage />} />
<Route path="/unauthorized" element={<UnauthorizedPage />} />
</Routes>
</BrowserRouter>
);
};
export default App;Props
The RequireAuth component accepts the following props:
| Prop | Type | Description | Required |
|---------------------|------------|-----------------------------------------------------------------------------|----------|
| groupKey | string | The key identifying the permission group to check. | Yes |
| allowedPermissions| number[] | Array of permission keys the user must have to access the protected route. | Yes |
Functions
authorized Checks if the user is authenticated by verifying the presence of a login.davinci.accesstoken cookie.
authorized(): booleanReturns: boolean - true if the access token cookie exists, false otherwise.
getPermissions Fetches user permissions for a specific group from the backend or retrieves them from cookies. If not found in cookies, it makes an API call to authorize/user/basepermissions and caches the results in cookies with a 30-minute expiration.
getPermissions(groupKey: string): Promise<any>|Parameter|Type|Description|Required| |---|---|---|---| | 'groupKey' |'string'|The key identifying the permission group.|Yes|
Returns: Promise - The user's permission keys for the specified group, or null if not found.
Notes
- Authentication: The module uses a login.davinci.accesstoken cookie to store the JWT access token. Ensure this cookie is set during login.
- Permissions Caching: Permissions are cached in cookies with a 30-minute expiration to reduce API calls. The cookie key format is ${userKey}.davinci.${groupKey}.
- JWT Decoding: The jwt-decode library is used to extract the userKey from the JWT token for permission lookup.
- Loading UI: While permissions are being fetched, a styled Grid component is displayed using a background image from ResourcesContext. Ensure ResourcesContext provides waiting_background.
- Redirects: Unauthenticated users are redirected to /login, and authenticated users without required permissions are redirected to /unauthorized. The state.from property preserves the original location for potential redirection after login.
- Dependencies: The APIConnect module is required for fetching permissions. Ensure it is correctly configured with the base URL (VITE_WEBAPI_DATATEAM_BASE_URL).
Troubleshooting
- Redirects to /login: Verify that the login.davinci.accesstoken cookie is set and valid.
- Redirects to /unauthorized: Ensure the user has at least one of the allowedPermissions for the specified groupKey.
- Loading UI persists: Check that the APIConnect.get call to authorize/user/basepermissions returns successfully and that cookies are being set correctly.
- No background image: Confirm that ResourcesContext provides a valid waiting_background URL.
- CORS issues: Ensure the API server allows requests from your application's origin and includes appropriate CORS headers.
For further assistance, refer to the React Router documentation, universal-cookie documentation, jwt-decode documentation, or Material-UI documentation.
