Compare commits
No commits in common. "de1bd53f530c936fe28fbdf578bf5f4ab7b6bb0c" and "d928cf45b012b51d0fbce20e54df2a0d64504f3c" have entirely different histories.
de1bd53f53
...
d928cf45b0
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
|
||||||
<g transform="matrix(0.693368,0,0,0.693368,-2.677595,7.413107)">
|
|
||||||
<path d="M42.242,41.686C40.097,43.436 38.293,45.407 36.884,47.522C34.764,46.735 32.364,46.281 29.811,46.281C20.785,46.281 13.661,51.971 13.661,57.382C13.661,57.696 13.806,57.946 14.24,57.946L33.222,57.946C33.166,58.257 33.157,58.571 33.157,58.884C33.157,61.225 33.721,63.516 34.996,65.46L13.183,65.46C7.906,65.46 5.304,62.977 5.304,58.498C5.304,48.147 16.263,38.838 29.811,38.838C34.357,38.838 38.611,39.886 42.242,41.686ZM42.301,22.95C42.301,30.45 36.757,36.469 29.818,36.469C22.879,36.469 17.311,30.505 17.311,22.965C17.311,15.724 22.975,9.655 29.818,9.655C36.652,9.655 42.301,15.654 42.301,22.95ZM24.809,22.965C24.809,26.414 27.104,28.996 29.818,28.996C32.563,28.996 34.835,26.414 34.835,22.95C34.835,19.737 32.49,17.128 29.818,17.128C27.144,17.128 24.809,19.752 24.809,22.965Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M66.701,35.926C74.64,35.926 80.918,29.117 80.918,20.577C80.918,12.267 74.528,5.46 66.701,5.46C58.889,5.46 52.461,12.296 52.461,20.592C52.461,29.124 58.77,35.926 66.701,35.926ZM66.701,28.318C63.142,28.318 60.166,25.025 60.166,20.568C60.166,16.396 63.198,13.068 66.701,13.068C70.212,13.068 73.212,16.374 73.212,20.577C73.212,24.962 70.3,28.318 66.701,28.318ZM47.673,65.412L85.706,65.412C91.705,65.412 94.723,63.301 94.723,58.884C94.723,49.169 82.875,38.829 66.701,38.829C50.496,38.829 38.649,49.169 38.649,58.884C38.649,63.301 41.666,65.412 47.673,65.412ZM48.131,57.805C47.629,57.805 47.476,57.562 47.476,57.216C47.476,53.516 54.602,46.461 66.701,46.461C78.793,46.461 85.895,53.516 85.895,57.216C85.895,57.562 85.75,57.805 85.272,57.805L48.131,57.805Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1314,10 +1314,6 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-editor {
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cm-errorLine {
|
.cm-errorLine {
|
||||||
background-color: color-mix(in srgb, var(--color-error) 15%, transparent);
|
background-color: color-mix(in srgb, var(--color-error) 15%, transparent);
|
||||||
}
|
}
|
||||||
@ -1405,18 +1401,10 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
|
|
||||||
.permission-checkbox[data-state='inherit'] .permission-checkbox-inherit,
|
.permission-checkbox[data-state='inherit'] .permission-checkbox-inherit,
|
||||||
.permission-checkbox[data-state='allow'] .permission-checkbox-allow,
|
.permission-checkbox[data-state='allow'] .permission-checkbox-allow,
|
||||||
.permission-checkbox[data-state='deny'] .permission-checkbox-deny,
|
.permission-checkbox[data-state='deny'] .permission-checkbox-deny {
|
||||||
.permission-checkbox[data-state='mixed'] .permission-checkbox-mixed {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.permission-checkbox-square {
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.permission-checkbox-face .anticon {
|
.permission-checkbox-face .anticon {
|
||||||
display: flex;
|
display: flex;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState, useRef } from 'react'
|
import { useState, useRef } from 'react'
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
||||||
import NewPermissionSetting from './PermissionSettings/NewPermissionSetting'
|
import NewPermissionSettings from './PermissionSettings/NewPermissionSettings'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
@ -19,10 +19,10 @@ const PermissionSettingsList = () => {
|
|||||||
useState(false)
|
useState(false)
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('permissionSetting')
|
const [viewMode, setViewMode] = useViewMode('permissionSettings')
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('permissionSetting')
|
useColumnVisibility('permissionSettings')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
const [showFilterSidebar, setShowFilterSidebar] =
|
||||||
useFilterSidebarVisibility('PermissionSettings')
|
useFilterSidebarVisibility('PermissionSettings')
|
||||||
@ -62,12 +62,12 @@ const PermissionSettingsList = () => {
|
|||||||
<Button>Actions</Button>
|
<Button>Actions</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='permissionSetting' />
|
<ExportListButton objectType='permissionSettings' />
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<SortSidebarButton
|
<SortSidebarButton
|
||||||
@ -88,7 +88,7 @@ const PermissionSettingsList = () => {
|
|||||||
<ObjectTable
|
<ObjectTable
|
||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
showFilterSidebar={showFilterSidebar}
|
||||||
showSortSidebar={showSortSidebar}
|
showSortSidebar={showSortSidebar}
|
||||||
@ -110,7 +110,7 @@ const PermissionSettingsList = () => {
|
|||||||
destroyOnHidden={true}
|
destroyOnHidden={true}
|
||||||
width={700}
|
width={700}
|
||||||
>
|
>
|
||||||
<NewPermissionSetting
|
<NewPermissionSettings
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
setNewPermissionSettingsOpen(false)
|
setNewPermissionSettingsOpen(false)
|
||||||
tableRef.current?.reload()
|
tableRef.current?.reload()
|
||||||
|
|||||||
@ -3,10 +3,10 @@ import ObjectInfo from '../../common/ObjectInfo'
|
|||||||
import NewObjectForm from '../../common/NewObjectForm'
|
import NewObjectForm from '../../common/NewObjectForm'
|
||||||
import WizardView from '../../common/WizardView'
|
import WizardView from '../../common/WizardView'
|
||||||
|
|
||||||
const NewPermissionSetting = ({ onOk, defaultValues }) => {
|
const NewPermissionSettings = ({ onOk, defaultValues }) => {
|
||||||
return (
|
return (
|
||||||
<NewObjectForm
|
<NewObjectForm
|
||||||
type={'permissionSetting'}
|
type={'permissionSettings'}
|
||||||
defaultValues={{ permissions: {}, ...defaultValues }}
|
defaultValues={{ permissions: {}, ...defaultValues }}
|
||||||
>
|
>
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
||||||
@ -16,7 +16,7 @@ const NewPermissionSetting = ({ onOk, defaultValues }) => {
|
|||||||
key: 'required',
|
key: 'required',
|
||||||
content: (
|
content: (
|
||||||
<ObjectInfo
|
<ObjectInfo
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
column={1}
|
column={1}
|
||||||
bordered={false}
|
bordered={false}
|
||||||
isEditing={true}
|
isEditing={true}
|
||||||
@ -31,7 +31,7 @@ const NewPermissionSetting = ({ onOk, defaultValues }) => {
|
|||||||
key: 'summary',
|
key: 'summary',
|
||||||
content: (
|
content: (
|
||||||
<ObjectInfo
|
<ObjectInfo
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
column={1}
|
column={1}
|
||||||
bordered={false}
|
bordered={false}
|
||||||
visibleProperties={{
|
visibleProperties={{
|
||||||
@ -68,10 +68,10 @@ const NewPermissionSetting = ({ onOk, defaultValues }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
NewPermissionSetting.propTypes = {
|
NewPermissionSettings.propTypes = {
|
||||||
onOk: PropTypes.func.isRequired,
|
onOk: PropTypes.func.isRequired,
|
||||||
reset: PropTypes.bool,
|
reset: PropTypes.bool,
|
||||||
defaultValues: PropTypes.object
|
defaultValues: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NewPermissionSetting
|
export default NewPermissionSettings
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Card, Flex, Space, Spin } from 'antd'
|
import { Card, Flex, Space } from 'antd'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
import NotesPanel from '../../common/NotesPanel'
|
||||||
@ -26,17 +26,17 @@ import {
|
|||||||
} from '../../../../database/ObjectModels.js'
|
} from '../../../../database/ObjectModels.js'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
||||||
import PermissionSettingIcon from '../../../Icons/PermissionSettingIcon.jsx'
|
import PermissionSettingsIcon from '../../../Icons/PermissionSettingsIcon.jsx'
|
||||||
|
|
||||||
const PermissionSettingInfo = () => {
|
const PermissionSettingsInfo = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const objectFormRef = useRef(null)
|
const objectFormRef = useRef(null)
|
||||||
const actionHandlerRef = useRef(null)
|
const actionHandlerRef = useRef(null)
|
||||||
const permissionSettingId = new URLSearchParams(location.search).get(
|
const permissionSettingsId = new URLSearchParams(location.search).get(
|
||||||
'permissionSettingId'
|
'permissionSettingsId'
|
||||||
)
|
)
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
'PermissionSettingInfo',
|
'PermissionSettingsInfo',
|
||||||
{
|
{
|
||||||
info: true,
|
info: true,
|
||||||
notes: true,
|
notes: true,
|
||||||
@ -84,8 +84,8 @@ const PermissionSettingInfo = () => {
|
|||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<ObjectActions
|
<ObjectActions
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
id={permissionSettingId}
|
id={permissionSettingsId}
|
||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
objectData={objectFormState.objectData}
|
objectData={objectFormState.objectData}
|
||||||
/>
|
/>
|
||||||
@ -100,12 +100,12 @@ const PermissionSettingInfo = () => {
|
|||||||
updateVisibleState={updateCollapseState}
|
updateVisibleState={updateCollapseState}
|
||||||
/>
|
/>
|
||||||
<UserNotifierToggle
|
<UserNotifierToggle
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
objectData={objectFormState.objectData}
|
objectData={objectFormState.objectData}
|
||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
/>
|
/>
|
||||||
<DocumentPrintButton
|
<DocumentPrintButton
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
objectData={objectFormState.objectData}
|
objectData={objectFormState.objectData}
|
||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
/>
|
/>
|
||||||
@ -138,8 +138,8 @@ const PermissionSettingInfo = () => {
|
|||||||
/>
|
/>
|
||||||
<ObjectTableNavigationButtons
|
<ObjectTableNavigationButtons
|
||||||
disabled={objectFormState.loading || objectFormState.isEditing}
|
disabled={objectFormState.loading || objectFormState.isEditing}
|
||||||
_id={permissionSettingId}
|
_id={permissionSettingsId}
|
||||||
objectType='permissionSetting'
|
objectType='permissionSettings'
|
||||||
showEndingDivider={true}
|
showEndingDivider={true}
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
@ -152,8 +152,8 @@ const PermissionSettingInfo = () => {
|
|||||||
ref={actionHandlerRef}
|
ref={actionHandlerRef}
|
||||||
>
|
>
|
||||||
<ObjectForm
|
<ObjectForm
|
||||||
id={permissionSettingId}
|
id={permissionSettingsId}
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
style={{ height: '100%' }}
|
style={{ height: '100%' }}
|
||||||
ref={objectFormRef}
|
ref={objectFormRef}
|
||||||
setCurrentObject={true}
|
setCurrentObject={true}
|
||||||
@ -176,7 +176,7 @@ const PermissionSettingInfo = () => {
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
indicator={<LoadingOutlined />}
|
indicator={<LoadingOutlined />}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
visibleProperties={{
|
visibleProperties={{
|
||||||
permissions: false
|
permissions: false
|
||||||
@ -184,19 +184,18 @@ const PermissionSettingInfo = () => {
|
|||||||
/>
|
/>
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Permissions Matrix'
|
title='Permission Settings Matrix'
|
||||||
icon={<PermissionSettingIcon />}
|
icon={<PermissionSettingsIcon />}
|
||||||
active={collapseState.matrix}
|
active={collapseState.matrix}
|
||||||
onToggle={(expanded) =>
|
onToggle={(expanded) =>
|
||||||
updateCollapseState('matrix', expanded)
|
updateCollapseState('matrix', expanded)
|
||||||
}
|
}
|
||||||
collapseKey='matrix'
|
collapseKey='matrix'
|
||||||
>
|
>
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined />}>
|
|
||||||
<Card>
|
<Card>
|
||||||
<ObjectProperty
|
<ObjectProperty
|
||||||
{...getModelProperty(
|
{...getModelProperty(
|
||||||
'permissionSetting',
|
'permissionSettings',
|
||||||
'permissions'
|
'permissions'
|
||||||
)}
|
)}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
@ -204,7 +203,6 @@ const PermissionSettingInfo = () => {
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Spin>
|
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
@ -219,8 +217,8 @@ const PermissionSettingInfo = () => {
|
|||||||
>
|
>
|
||||||
<Card>
|
<Card>
|
||||||
<NotesPanel
|
<NotesPanel
|
||||||
_id={permissionSettingId}
|
_id={permissionSettingsId}
|
||||||
type='permissionSetting'
|
type='permissionSettings'
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
@ -240,9 +238,9 @@ const PermissionSettingInfo = () => {
|
|||||||
type='auditLog'
|
type='auditLog'
|
||||||
masterFilter={{
|
masterFilter={{
|
||||||
parent:
|
parent:
|
||||||
getModelByName('permissionSetting').prefix +
|
getModelByName('permissionSettings').prefix +
|
||||||
':' +
|
':' +
|
||||||
permissionSettingId
|
permissionSettingsId
|
||||||
}}
|
}}
|
||||||
visibleColumns={{ _id: false, parent: false }}
|
visibleColumns={{ _id: false, parent: false }}
|
||||||
/>
|
/>
|
||||||
@ -255,4 +253,4 @@ const PermissionSettingInfo = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PermissionSettingInfo
|
export default PermissionSettingsInfo
|
||||||
@ -1,123 +0,0 @@
|
|||||||
import { useState, useRef } from 'react'
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
import NewUserGroup from './UserGroups/NewUserGroup'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import SortSidebarButton from '../common/SortSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import useSortSidebarVisibility from '../hooks/useSortSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const UserGroups = () => {
|
|
||||||
const [newUserGroupOpen, setNewUserGroupOpen] = useState(false)
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('userGroup')
|
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('userGroup')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('UserGroups')
|
|
||||||
|
|
||||||
const [showSortSidebar, setShowSortSidebar] =
|
|
||||||
useSortSidebarVisibility('UserGroups')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New User Group',
|
|
||||||
key: 'newUserGroup',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newUserGroup') {
|
|
||||||
setNewUserGroupOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'} style={{ minHeight: 0 }}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='userGroup'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='userGroup' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<SortSidebarButton
|
|
||||||
active={showSortSidebar}
|
|
||||||
onClick={() => setShowSortSidebar(!showSortSidebar)}
|
|
||||||
/>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
showEndingDivider={true}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
type='userGroup'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
showSortSidebar={showSortSidebar}
|
|
||||||
expandHeight={true}
|
|
||||||
saveFilterInSession={true}
|
|
||||||
saveFilterInUrl={true}
|
|
||||||
useFilterInSession={true}
|
|
||||||
useFilterInUrl={true}
|
|
||||||
saveSortInSession={true}
|
|
||||||
saveSortInUrl={true}
|
|
||||||
useSortInSession={true}
|
|
||||||
useSortInUrl={true}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={newUserGroupOpen}
|
|
||||||
onCancel={() => setNewUserGroupOpen(false)}
|
|
||||||
footer={null}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
width={700}
|
|
||||||
>
|
|
||||||
<NewUserGroup
|
|
||||||
onOk={() => {
|
|
||||||
setNewUserGroupOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={!newUserGroupOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UserGroups
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewUserGroup = ({ onOk, defaultValues }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type={'userGroup'}
|
|
||||||
defaultValues={{ permissions: {}, ...defaultValues }}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='userGroup'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
labelWidth={100}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='userGroup'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
_reference: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
permissions: false
|
|
||||||
}}
|
|
||||||
objectPropertyProps={{ scrollHeight: '320px' }}
|
|
||||||
labelWidth={130}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New User Group'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewUserGroup.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewUserGroup
|
|
||||||
@ -1,265 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Card, Flex, Space, Spin } from 'antd'
|
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import ObjectTableNavigationButtons from '../../common/ObjectTableNavigationButtons.jsx'
|
|
||||||
import ActivityIndicator from '../../common/ActivityIndicator.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
|
||||||
import {
|
|
||||||
getModelProperty,
|
|
||||||
getModelByName
|
|
||||||
} from '../../../../database/ObjectModels.js'
|
|
||||||
import PersonGroupIcon from '../../../Icons/PersonGroupIcon.jsx'
|
|
||||||
import PersonIcon from '../../../Icons/PersonIcon.jsx'
|
|
||||||
|
|
||||||
const UserGroupInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const userGroupId = new URLSearchParams(location.search).get('userGroupId')
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
|
||||||
'UserGroupInfo',
|
|
||||||
{
|
|
||||||
info: true,
|
|
||||||
permissions: true,
|
|
||||||
users: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
editDisabled: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='userGroup'
|
|
||||||
id={userGroupId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'User Group Information' },
|
|
||||||
{ key: 'users', label: 'Users' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='userGroup'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='userGroup'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<ActivityIndicator
|
|
||||||
activities={objectFormState.activities}
|
|
||||||
showStartingDivider={true}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={
|
|
||||||
objectFormState.beingEditedByOther ||
|
|
||||||
objectFormState.loading ||
|
|
||||||
objectFormState.editDisabled
|
|
||||||
}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
<ObjectTableNavigationButtons
|
|
||||||
disabled={objectFormState.loading || objectFormState.isEditing}
|
|
||||||
_id={userGroupId}
|
|
||||||
objectType='userGroup'
|
|
||||||
showEndingDivider={true}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='User Group Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={userGroupId}
|
|
||||||
type='userGroup'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
setCurrentObject={true}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='userGroup'
|
|
||||||
labelWidth='190px'
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
permissions: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Permissions Matrix'
|
|
||||||
icon={<PersonGroupIcon />}
|
|
||||||
active={collapseState.permissions}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('permissions', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='permissions'
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={objectFormState.loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<ObjectProperty
|
|
||||||
{...getModelProperty('userGroup', 'permissions')}
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</Spin>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Users'
|
|
||||||
icon={<PersonIcon />}
|
|
||||||
active={collapseState.users}
|
|
||||||
onToggle={(expanded) => updateCollapseState('users', expanded)}
|
|
||||||
collapseKey='users'
|
|
||||||
>
|
|
||||||
{!userGroupId ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='user'
|
|
||||||
masterFilter={{
|
|
||||||
groups: getModelByName('userGroup').prefix + ':' + userGroupId
|
|
||||||
}}
|
|
||||||
visibleColumns={{ groups: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={userGroupId} type='userGroup' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) => updateCollapseState('auditLogs', expanded)}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{
|
|
||||||
parent: getModelByName('userGroup').prefix + ':' + userGroupId
|
|
||||||
}}
|
|
||||||
visibleColumns={{ _id: false, parent: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UserGroupInfo
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Card, Flex, Space, Spin } from 'antd'
|
import { Card, Flex, Space } from 'antd'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
import NotesPanel from '../../common/NotesPanel'
|
||||||
@ -187,7 +187,6 @@ const UserInfo = () => {
|
|||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
type='user'
|
type='user'
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
labelWidth='190px'
|
|
||||||
visibleProperties={{
|
visibleProperties={{
|
||||||
profileImage: false,
|
profileImage: false,
|
||||||
permissions: false
|
permissions: false
|
||||||
@ -199,17 +198,13 @@ const UserInfo = () => {
|
|||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Permissions Matrix'
|
title='User Permissions'
|
||||||
icon={<PersonIcon />}
|
icon={<PersonIcon />}
|
||||||
active={collapseState.permissions}
|
active={collapseState.permissions}
|
||||||
onToggle={(expanded) =>
|
onToggle={(expanded) =>
|
||||||
updateCollapseState('permissions', expanded)
|
updateCollapseState('permissions', expanded)
|
||||||
}
|
}
|
||||||
collapseKey='permissions'
|
collapseKey='permissions'
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={objectFormState.loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
>
|
>
|
||||||
<Card>
|
<Card>
|
||||||
<ObjectProperty
|
<ObjectProperty
|
||||||
@ -219,7 +214,6 @@ const UserInfo = () => {
|
|||||||
loading={objectFormState.loading}
|
loading={objectFormState.loading}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Spin>
|
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='App Passwords'
|
title='App Passwords'
|
||||||
|
|||||||
@ -14,6 +14,8 @@ const breadcrumbNameMap = {
|
|||||||
developer: 'Developer',
|
developer: 'Developer',
|
||||||
finance: 'Finance',
|
finance: 'Finance',
|
||||||
sales: 'Sales',
|
sales: 'Sales',
|
||||||
|
productcategories: 'Product Categories',
|
||||||
|
permissionSettings: 'Permission Settings',
|
||||||
overview: 'Overview',
|
overview: 'Overview',
|
||||||
info: 'Info',
|
info: 'Info',
|
||||||
design: 'Design',
|
design: 'Design',
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Form } from 'antd'
|
|||||||
import { ApiServerContext } from '../context/ApiServerContext'
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
import { useMessageContext } from '../context/MessageContext'
|
import { useMessageContext } from '../context/MessageContext'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import mergeWith from 'lodash/mergeWith'
|
import merge from 'lodash/merge'
|
||||||
import set from 'lodash/set'
|
import set from 'lodash/set'
|
||||||
import { getModelByName } from '../../../database/ObjectModels'
|
import { getModelByName } from '../../../database/ObjectModels'
|
||||||
|
|
||||||
@ -18,15 +18,6 @@ const buildObjectFromEntries = (entries = []) => {
|
|||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrayReplaceCustomizer = (objValue, srcValue, key) => {
|
|
||||||
if (Array.isArray(srcValue)) {
|
|
||||||
return srcValue
|
|
||||||
}
|
|
||||||
if (key === 'permissions' && srcValue !== undefined) {
|
|
||||||
return srcValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NewObjectForm is a reusable form component for creating new objects.
|
* NewObjectForm is a reusable form component for creating new objects.
|
||||||
* It handles form validation, submission, and error handling logic.
|
* It handles form validation, submission, and error handling logic.
|
||||||
@ -173,16 +164,9 @@ const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
|
|||||||
// Calculate computed values for initial data
|
// Calculate computed values for initial data
|
||||||
const computedEntries = calculateComputedValues(defaultValues, model)
|
const computedEntries = calculateComputedValues(defaultValues, model)
|
||||||
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
||||||
const initialFormData = mergeWith(
|
const initialFormData = merge({}, defaultValues, computedValuesObject)
|
||||||
{},
|
|
||||||
defaultValues,
|
|
||||||
computedValuesObject,
|
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
|
||||||
form.setFieldsValue(initialFormData)
|
form.setFieldsValue(initialFormData)
|
||||||
setObjectData((prev) =>
|
setObjectData((prev) => merge({}, prev, initialFormData))
|
||||||
mergeWith({}, prev, initialFormData, arrayReplaceCustomizer)
|
|
||||||
)
|
|
||||||
return validateForm()
|
return validateForm()
|
||||||
}
|
}
|
||||||
}, [form, defaultValues, calculateComputedValues, model, validateForm])
|
}, [form, defaultValues, calculateComputedValues, model, validateForm])
|
||||||
@ -197,12 +181,7 @@ const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
|
|||||||
setSubmitLoading(true)
|
setSubmitLoading(true)
|
||||||
const computedEntries = calculateComputedValues(objectData, model)
|
const computedEntries = calculateComputedValues(objectData, model)
|
||||||
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
||||||
const computedObjectData = mergeWith(
|
const computedObjectData = merge({}, objectData, computedValuesObject)
|
||||||
{},
|
|
||||||
objectData,
|
|
||||||
computedValuesObject,
|
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
|
||||||
const newObject = await createObject(type, computedObjectData)
|
const newObject = await createObject(type, computedObjectData)
|
||||||
showSuccess('Object created successfully')
|
showSuccess('Object created successfully')
|
||||||
return newObject
|
return newObject
|
||||||
@ -228,12 +207,7 @@ const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
|
|||||||
style={style}
|
style={style}
|
||||||
onValuesChange={(_changedValues, allFormValues) => {
|
onValuesChange={(_changedValues, allFormValues) => {
|
||||||
// Calculate computed values based on current form data
|
// Calculate computed values based on current form data
|
||||||
const currentFormData = mergeWith(
|
const currentFormData = merge({}, objectData || {}, allFormValues)
|
||||||
{},
|
|
||||||
objectData || {},
|
|
||||||
allFormValues,
|
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
|
||||||
const computedEntries = calculateComputedValues(currentFormData, model)
|
const computedEntries = calculateComputedValues(currentFormData, model)
|
||||||
|
|
||||||
if (Array.isArray(computedEntries) && computedEntries.length > 0) {
|
if (Array.isArray(computedEntries) && computedEntries.length > 0) {
|
||||||
@ -255,14 +229,9 @@ const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
|
|||||||
|
|
||||||
// Merge all values (user input + computed values)
|
// Merge all values (user input + computed values)
|
||||||
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
||||||
const allValues = mergeWith(
|
const allValues = merge({}, allFormValues, computedValuesObject)
|
||||||
{},
|
|
||||||
allFormValues,
|
|
||||||
computedValuesObject,
|
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
|
||||||
setObjectData((prev) => {
|
setObjectData((prev) => {
|
||||||
return mergeWith({}, prev, allValues, arrayReplaceCustomizer)
|
return merge({}, prev, allValues)
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -20,13 +20,10 @@ import { useLocation, useNavigate } from 'react-router-dom'
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { useActions } from '../context/ActionsContext'
|
import { useActions } from '../context/ActionsContext'
|
||||||
|
|
||||||
const arrayReplaceCustomizer = (objValue, srcValue, key) => {
|
const arrayReplaceCustomizer = (objValue, srcValue) => {
|
||||||
if (Array.isArray(srcValue)) {
|
if (Array.isArray(srcValue)) {
|
||||||
return srcValue
|
return srcValue
|
||||||
}
|
}
|
||||||
if (key === 'permissions' && srcValue !== undefined) {
|
|
||||||
return srcValue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserId = (user) => user?._id || user
|
const getUserId = (user) => user?._id || user
|
||||||
@ -342,11 +339,10 @@ const ObjectForm = forwardRef(
|
|||||||
model
|
model
|
||||||
)
|
)
|
||||||
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
||||||
const resetFormData = mergeWith(
|
const resetFormData = merge(
|
||||||
{},
|
{},
|
||||||
serverObjectData.current,
|
serverObjectData.current,
|
||||||
computedValuesObject,
|
computedValuesObject
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
)
|
||||||
setIsEditing(false)
|
setIsEditing(false)
|
||||||
isEditingRef.current = false
|
isEditingRef.current = false
|
||||||
@ -474,12 +470,7 @@ const ObjectForm = forwardRef(
|
|||||||
// Calculate and set computed values on initial load
|
// Calculate and set computed values on initial load
|
||||||
const computedEntries = calculateComputedValues(data, model)
|
const computedEntries = calculateComputedValues(data, model)
|
||||||
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
const computedValuesObject = buildObjectFromEntries(computedEntries)
|
||||||
const initialFormData = mergeWith(
|
const initialFormData = merge({}, data, computedValuesObject)
|
||||||
{},
|
|
||||||
data,
|
|
||||||
computedValuesObject,
|
|
||||||
arrayReplaceCustomizer
|
|
||||||
)
|
|
||||||
setObjectData({ ...initialFormData, _isEditing: isEditingRef.current })
|
setObjectData({ ...initialFormData, _isEditing: isEditingRef.current })
|
||||||
form.setFieldsValue(initialFormData)
|
form.setFieldsValue(initialFormData)
|
||||||
setFetchLoading(false)
|
setFetchLoading(false)
|
||||||
@ -837,9 +828,9 @@ const ObjectForm = forwardRef(
|
|||||||
const mergedFormValues = mergeWith(
|
const mergedFormValues = mergeWith(
|
||||||
{},
|
{},
|
||||||
allFormValues,
|
allFormValues,
|
||||||
computedValuesObject,
|
|
||||||
arrayReplaceCustomizer
|
arrayReplaceCustomizer
|
||||||
)
|
)
|
||||||
|
merge(mergedFormValues, computedValuesObject)
|
||||||
|
|
||||||
mergedFormValues._isEditing = isEditingRef.current
|
mergedFormValues._isEditing = isEditingRef.current
|
||||||
|
|
||||||
|
|||||||
@ -11,18 +11,11 @@ const ICON_STYLE = {
|
|||||||
const PermissionCheckbox = ({
|
const PermissionCheckbox = ({
|
||||||
checked = false,
|
checked = false,
|
||||||
indeterminate = false,
|
indeterminate = false,
|
||||||
mixed = false,
|
|
||||||
disabled = false,
|
disabled = false,
|
||||||
onChange
|
onChange
|
||||||
}) => {
|
}) => {
|
||||||
const { token } = theme.useToken()
|
const { token } = theme.useToken()
|
||||||
const state = mixed
|
const state = indeterminate ? 'inherit' : checked ? 'allow' : 'deny'
|
||||||
? 'mixed'
|
|
||||||
: indeterminate
|
|
||||||
? 'inherit'
|
|
||||||
: checked
|
|
||||||
? 'allow'
|
|
||||||
: 'deny'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@ -30,7 +23,7 @@ const PermissionCheckbox = ({
|
|||||||
className='permission-checkbox'
|
className='permission-checkbox'
|
||||||
data-state={state}
|
data-state={state}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
aria-checked={mixed || indeterminate ? 'mixed' : checked}
|
aria-checked={indeterminate ? 'mixed' : checked}
|
||||||
role='checkbox'
|
role='checkbox'
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (disabled || typeof onChange !== 'function') return
|
if (disabled || typeof onChange !== 'function') return
|
||||||
@ -53,12 +46,6 @@ const PermissionCheckbox = ({
|
|||||||
>
|
>
|
||||||
<XMarkIcon style={ICON_STYLE} />
|
<XMarkIcon style={ICON_STYLE} />
|
||||||
</span>
|
</span>
|
||||||
<span
|
|
||||||
className='permission-checkbox-face permission-checkbox-mixed'
|
|
||||||
style={{ backgroundColor: token.colorPrimary }}
|
|
||||||
>
|
|
||||||
<span className='permission-checkbox-square' />
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -66,7 +53,6 @@ const PermissionCheckbox = ({
|
|||||||
PermissionCheckbox.propTypes = {
|
PermissionCheckbox.propTypes = {
|
||||||
checked: PropTypes.bool,
|
checked: PropTypes.bool,
|
||||||
indeterminate: PropTypes.bool,
|
indeterminate: PropTypes.bool,
|
||||||
mixed: PropTypes.bool,
|
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
onChange: PropTypes.func
|
onChange: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,77 +53,6 @@ const cyclePermissionState = (current, inherit) => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizePermissionState = (state, inherit) => {
|
|
||||||
if (!inherit && state === null) return false
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAggregatePermissionState = (states) => {
|
|
||||||
if (states.length === 0) return null
|
|
||||||
const first = states[0]
|
|
||||||
for (let i = 1; i < states.length; i++) {
|
|
||||||
if (states[i] !== first) return 'mixed'
|
|
||||||
}
|
|
||||||
return first
|
|
||||||
}
|
|
||||||
|
|
||||||
const getRowPermissionStates = (permissions, model, actions, inherit) =>
|
|
||||||
actions
|
|
||||||
.filter((action) => modelHasPermissionAction(model, action.name))
|
|
||||||
.map((action) =>
|
|
||||||
normalizePermissionState(
|
|
||||||
getPermissionState(permissions, model.name, action.name),
|
|
||||||
inherit
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const getColumnPermissionStates = (permissions, models, action, inherit) =>
|
|
||||||
models
|
|
||||||
.filter((model) => modelHasPermissionAction(model, action.name))
|
|
||||||
.map((model) =>
|
|
||||||
normalizePermissionState(
|
|
||||||
getPermissionState(permissions, model.name, action.name),
|
|
||||||
inherit
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const setRowPermissionState = (permissions, model, actions, next) => {
|
|
||||||
let nextPermissions = permissions
|
|
||||||
actions.forEach((action) => {
|
|
||||||
if (modelHasPermissionAction(model, action.name)) {
|
|
||||||
nextPermissions = setPermissionState(
|
|
||||||
nextPermissions,
|
|
||||||
model.name,
|
|
||||||
action.name,
|
|
||||||
next
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return nextPermissions
|
|
||||||
}
|
|
||||||
|
|
||||||
const setColumnPermissionState = (permissions, models, action, next) => {
|
|
||||||
let nextPermissions = permissions
|
|
||||||
models.forEach((model) => {
|
|
||||||
if (modelHasPermissionAction(model, action.name)) {
|
|
||||||
nextPermissions = setPermissionState(
|
|
||||||
nextPermissions,
|
|
||||||
model.name,
|
|
||||||
action.name,
|
|
||||||
next
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return nextPermissions
|
|
||||||
}
|
|
||||||
|
|
||||||
const getCheckboxTitle = (state, inherit) => {
|
|
||||||
if (state === 'mixed') return 'Mixed'
|
|
||||||
if (inherit && state === null) return 'Inherit'
|
|
||||||
if (state === true) return 'Allow'
|
|
||||||
return 'Deny'
|
|
||||||
}
|
|
||||||
|
|
||||||
const PermissionsMatrix = ({
|
const PermissionsMatrix = ({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
@ -159,108 +88,23 @@ const PermissionsMatrix = ({
|
|||||||
[disabled, inherit, onChange, permissions]
|
[disabled, inherit, onChange, permissions]
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleCycleRow = useCallback(
|
|
||||||
(model) => {
|
|
||||||
if (disabled || typeof onChange !== 'function') return
|
|
||||||
const aggregate = getAggregatePermissionState(
|
|
||||||
getRowPermissionStates(permissions, model, actions, inherit)
|
|
||||||
)
|
|
||||||
const next = cyclePermissionState(
|
|
||||||
aggregate === 'mixed' ? null : aggregate,
|
|
||||||
inherit
|
|
||||||
)
|
|
||||||
onChange(setRowPermissionState(permissions, model, actions, next))
|
|
||||||
},
|
|
||||||
[actions, disabled, inherit, onChange, permissions]
|
|
||||||
)
|
|
||||||
|
|
||||||
const handleCycleColumn = useCallback(
|
|
||||||
(action) => {
|
|
||||||
if (disabled || typeof onChange !== 'function') return
|
|
||||||
const aggregate = getAggregatePermissionState(
|
|
||||||
getColumnPermissionStates(permissions, models, action, inherit)
|
|
||||||
)
|
|
||||||
const next = cyclePermissionState(
|
|
||||||
aggregate === 'mixed' ? null : aggregate,
|
|
||||||
inherit
|
|
||||||
)
|
|
||||||
onChange(setColumnPermissionState(permissions, models, action, next))
|
|
||||||
},
|
|
||||||
[disabled, inherit, models, onChange, permissions]
|
|
||||||
)
|
|
||||||
|
|
||||||
const renderCheckbox = useCallback(
|
|
||||||
(state, onCycle) => {
|
|
||||||
const mixed = state === 'mixed'
|
|
||||||
const checked = state === true
|
|
||||||
const indeterminate = inherit && state === null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip title={getCheckboxTitle(state, inherit)} arrow={false}>
|
|
||||||
<span>
|
|
||||||
<PermissionCheckbox
|
|
||||||
checked={checked}
|
|
||||||
indeterminate={indeterminate}
|
|
||||||
mixed={mixed}
|
|
||||||
disabled={disabled}
|
|
||||||
onChange={onCycle}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
[disabled, inherit]
|
|
||||||
)
|
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
const modelColumn = {
|
const modelColumn = {
|
||||||
title: '',
|
title: '',
|
||||||
key: 'model',
|
key: 'model',
|
||||||
dataIndex: 'label',
|
dataIndex: 'label',
|
||||||
fixed: isMobile ? undefined : 'left',
|
fixed: isMobile ? undefined : 'left',
|
||||||
width: 248,
|
width: 220,
|
||||||
render: (label, record) => {
|
render: (label, record) => (
|
||||||
const aggregate = getAggregatePermissionState(
|
<Flex align='center' gap='small'>
|
||||||
getRowPermissionStates(permissions, record.model, actions, inherit)
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
align='center'
|
|
||||||
gap='small'
|
|
||||||
justify='space-between'
|
|
||||||
style={{ width: '100%', paddingRight: '10px' }}
|
|
||||||
>
|
|
||||||
<Flex align='center' gap='small' style={{ marginLeft: '6px' }}>
|
|
||||||
{record.icon ? createElement(record.icon) : null}
|
{record.icon ? createElement(record.icon) : null}
|
||||||
{label}
|
{label}
|
||||||
</Flex>
|
</Flex>
|
||||||
<div style={{ paddingBottom: '1px' }}>
|
|
||||||
{renderCheckbox(aggregate, () => {
|
|
||||||
handleCycleRow(record.model)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</Flex>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const actionColumns = actions.map((action) => {
|
const actionColumns = actions.map((action) => ({
|
||||||
const columnAggregate = getAggregatePermissionState(
|
title: <span className='permissions-matrix-header'>{action.label}</span>,
|
||||||
getColumnPermissionStates(permissions, models, action, inherit)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: (
|
|
||||||
<Flex vertical align='center' gap={12} justify='flex-end'>
|
|
||||||
<span className='permissions-matrix-header'>{action.label}</span>
|
|
||||||
<div style={{ paddingBottom: '2px' }}>
|
|
||||||
{renderCheckbox(columnAggregate, () => {
|
|
||||||
handleCycleColumn(action)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</Flex>
|
|
||||||
),
|
|
||||||
key: action.name,
|
key: action.name,
|
||||||
width: 48,
|
width: 48,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@ -273,26 +117,29 @@ const PermissionsMatrix = ({
|
|||||||
record.model.name,
|
record.model.name,
|
||||||
action.name
|
action.name
|
||||||
)
|
)
|
||||||
|
const checked = state === true
|
||||||
|
const indeterminate = inherit && state === null
|
||||||
|
const title = indeterminate ? 'Inherit' : checked ? 'Allow' : 'Deny'
|
||||||
|
|
||||||
return renderCheckbox(state, () => {
|
return (
|
||||||
|
<Tooltip title={title} arrow={false}>
|
||||||
|
<span>
|
||||||
|
<PermissionCheckbox
|
||||||
|
checked={checked}
|
||||||
|
indeterminate={indeterminate}
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={() => {
|
||||||
handleCycle(record.model.name, action.name)
|
handleCycle(record.model.name, action.name)
|
||||||
})
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}))
|
||||||
})
|
|
||||||
|
|
||||||
return [modelColumn, ...actionColumns]
|
return [modelColumn, ...actionColumns]
|
||||||
}, [
|
}, [actions, disabled, handleCycle, inherit, isMobile, permissions])
|
||||||
actions,
|
|
||||||
handleCycle,
|
|
||||||
handleCycleColumn,
|
|
||||||
handleCycleRow,
|
|
||||||
inherit,
|
|
||||||
isMobile,
|
|
||||||
models,
|
|
||||||
permissions,
|
|
||||||
renderCheckbox
|
|
||||||
])
|
|
||||||
|
|
||||||
const dataSource = useMemo(
|
const dataSource = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@ -190,7 +190,7 @@ const TemplateEditor = ({
|
|||||||
<Card
|
<Card
|
||||||
spinning={loading}
|
spinning={loading}
|
||||||
style={style}
|
style={style}
|
||||||
styles={{ body: { height: '100%', padding: '22px' } }}
|
styles={{ body: { height: '100%' } }}
|
||||||
>
|
>
|
||||||
<TemplatePreview
|
<TemplatePreview
|
||||||
objectData={objectData?.testObject}
|
objectData={objectData?.testObject}
|
||||||
@ -208,10 +208,7 @@ const TemplateEditor = ({
|
|||||||
{collapseState.editor == true && (
|
{collapseState.editor == true && (
|
||||||
<Splitter.Panel>
|
<Splitter.Panel>
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined />}>
|
<Spin spinning={loading} indicator={<LoadingOutlined />}>
|
||||||
<Card
|
<Card style={style} styles={{ body: { height: '100%' } }}>
|
||||||
style={style}
|
|
||||||
styles={{ body: { height: '100%', padding: '22px' } }}
|
|
||||||
>
|
|
||||||
<Flex vertical gap={'middle'} style={{ height: '100%' }}>
|
<Flex vertical gap={'middle'} style={{ height: '100%' }}>
|
||||||
<Flex gap={'small'} align={'stretch'}>
|
<Flex gap={'small'} align={'stretch'}>
|
||||||
<Alert
|
<Alert
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import CustomIconSvg from '../../../assets/icons/permissionsettingsicon.svg?react'
|
import CustomIconSvg from '../../../assets/icons/permissionsettingsicon.svg?react'
|
||||||
|
|
||||||
const PermissionSettingIcon = (props) => (
|
const PermissionSettingsIcon = (props) => (
|
||||||
<Icon component={CustomIconSvg} {...props} />
|
<Icon component={CustomIconSvg} {...props} />
|
||||||
)
|
)
|
||||||
|
|
||||||
export default PermissionSettingIcon
|
export default PermissionSettingsIcon
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import Icon from '@ant-design/icons'
|
|
||||||
import CustomIconSvg from '../../../assets/icons/persongroupicon.svg?react'
|
|
||||||
|
|
||||||
const PersonGroupIcon = (props) => <Icon component={CustomIconSvg} {...props} />
|
|
||||||
|
|
||||||
export default PersonGroupIcon
|
|
||||||
@ -38,8 +38,7 @@ import SettingsIcon from './SettingsIcon'
|
|||||||
import AuditLogIcon from './AuditLogIcon'
|
import AuditLogIcon from './AuditLogIcon'
|
||||||
import DeveloperIcon from './DeveloperIcon'
|
import DeveloperIcon from './DeveloperIcon'
|
||||||
import PersonIcon from './PersonIcon'
|
import PersonIcon from './PersonIcon'
|
||||||
import PersonGroupIcon from './PersonGroupIcon'
|
import PermissionSettingsIcon from './PermissionSettingsIcon'
|
||||||
import PermissionSettingIcon from './PermissionSettingIcon'
|
|
||||||
import HostIcon from './HostIcon'
|
import HostIcon from './HostIcon'
|
||||||
import DocumentPrinterIcon from './DocumentPrinterIcon'
|
import DocumentPrinterIcon from './DocumentPrinterIcon'
|
||||||
import DocumentTemplateIcon from './DocumentTemplateIcon'
|
import DocumentTemplateIcon from './DocumentTemplateIcon'
|
||||||
@ -97,8 +96,7 @@ const sidebarIconMap = {
|
|||||||
auditLog: <AuditLogIcon />,
|
auditLog: <AuditLogIcon />,
|
||||||
developer: <DeveloperIcon />,
|
developer: <DeveloperIcon />,
|
||||||
person: <PersonIcon />,
|
person: <PersonIcon />,
|
||||||
userGroup: <PersonGroupIcon />,
|
permissionSettings: <PermissionSettingsIcon />,
|
||||||
permissionSetting: <PermissionSettingIcon />,
|
|
||||||
host: <HostIcon />,
|
host: <HostIcon />,
|
||||||
documentPrinter: <DocumentPrinterIcon />,
|
documentPrinter: <DocumentPrinterIcon />,
|
||||||
documentTemplate: <DocumentTemplateIcon />,
|
documentTemplate: <DocumentTemplateIcon />,
|
||||||
|
|||||||
@ -31,8 +31,7 @@ import { OrderItem } from './models/OrderItem'
|
|||||||
import { Shipment } from './models/Shipment'
|
import { Shipment } from './models/Shipment'
|
||||||
import { AuditLog } from './models/AuditLog'
|
import { AuditLog } from './models/AuditLog'
|
||||||
import { User } from './models/User'
|
import { User } from './models/User'
|
||||||
import { UserGroup } from './models/UserGroup.js'
|
import { PermissionSettings } from './models/PermissionSettings.js'
|
||||||
import { PermissionSetting } from './models/PermissionSetting.js'
|
|
||||||
import { AppPassword } from './models/AppPassword.js'
|
import { AppPassword } from './models/AppPassword.js'
|
||||||
import { NoteType } from './models/NoteType'
|
import { NoteType } from './models/NoteType'
|
||||||
import { Note } from './models/Note'
|
import { Note } from './models/Note'
|
||||||
@ -85,8 +84,7 @@ export const objectModels = [
|
|||||||
Shipment,
|
Shipment,
|
||||||
AuditLog,
|
AuditLog,
|
||||||
User,
|
User,
|
||||||
UserGroup,
|
PermissionSettings,
|
||||||
PermissionSetting,
|
|
||||||
AppPassword,
|
AppPassword,
|
||||||
NoteType,
|
NoteType,
|
||||||
Note,
|
Note,
|
||||||
@ -140,8 +138,7 @@ export {
|
|||||||
Shipment,
|
Shipment,
|
||||||
AuditLog,
|
AuditLog,
|
||||||
User,
|
User,
|
||||||
UserGroup,
|
PermissionSettings,
|
||||||
PermissionSetting,
|
|
||||||
AppPassword,
|
AppPassword,
|
||||||
NoteType,
|
NoteType,
|
||||||
Note,
|
Note,
|
||||||
|
|||||||
@ -1,24 +1,24 @@
|
|||||||
import { createElement, lazy } from 'react'
|
import { createElement, lazy } from 'react'
|
||||||
|
|
||||||
const PermissionSettingInfo = lazy(
|
const PermissionSettingsInfo = lazy(
|
||||||
() =>
|
() =>
|
||||||
import('../../components/Dashboard/Management/PermissionSettings/PermissionSettingInfo')
|
import('../../components/Dashboard/Management/PermissionSettings/PermissionSettingsInfo')
|
||||||
)
|
)
|
||||||
import PermissionSettingIcon from '../../components/Icons/PermissionSettingIcon'
|
import PermissionSettingsIcon from '../../components/Icons/PermissionSettingsIcon'
|
||||||
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
||||||
import EditIcon from '../../components/Icons/EditIcon'
|
import EditIcon from '../../components/Icons/EditIcon'
|
||||||
import CheckIcon from '../../components/Icons/CheckIcon'
|
import CheckIcon from '../../components/Icons/CheckIcon'
|
||||||
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
||||||
import BinIcon from '../../components/Icons/BinIcon'
|
import BinIcon from '../../components/Icons/BinIcon'
|
||||||
|
|
||||||
export const PermissionSetting = {
|
export const PermissionSettings = {
|
||||||
name: 'permissionSetting',
|
name: 'permissionSettings',
|
||||||
label: 'Permission Setting',
|
label: 'Permission Settings',
|
||||||
labelPlural: 'Permission Settings',
|
labelPlural: 'Permission Settings',
|
||||||
url: '/dashboard/management/permissionsettings',
|
url: '/dashboard/management/permissionsettings',
|
||||||
prefix: 'PMS',
|
prefix: 'PMS',
|
||||||
endpoint: 'permissionsettings',
|
endpoint: 'permissionsettings',
|
||||||
icon: PermissionSettingIcon,
|
icon: PermissionSettingsIcon,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
name: 'info',
|
name: 'info',
|
||||||
@ -73,7 +73,7 @@ export const PermissionSetting = {
|
|||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
name: 'info',
|
name: 'info',
|
||||||
content: () => createElement(PermissionSettingInfo)
|
content: () => createElement(PermissionSettingsInfo)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
columns: ['_reference', 'name', 'createdAt', 'updatedAt'],
|
columns: ['_reference', 'name', 'createdAt', 'updatedAt'],
|
||||||
@ -85,7 +85,7 @@ export const PermissionSetting = {
|
|||||||
label: 'ID',
|
label: 'ID',
|
||||||
columnFixed: 'left',
|
columnFixed: 'left',
|
||||||
type: 'id',
|
type: 'id',
|
||||||
objectType: 'permissionSetting',
|
objectType: 'permissionSettings',
|
||||||
showCopy: true,
|
showCopy: true,
|
||||||
columnWidth: 140
|
columnWidth: 140
|
||||||
},
|
},
|
||||||
@ -101,7 +101,7 @@ export const PermissionSetting = {
|
|||||||
label: 'Reference',
|
label: 'Reference',
|
||||||
type: 'reference',
|
type: 'reference',
|
||||||
columnFixed: 'left',
|
columnFixed: 'left',
|
||||||
objectType: 'permissionSetting',
|
objectType: 'permissionSettings',
|
||||||
showCopy: true,
|
showCopy: true,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
columnWidth: 180
|
columnWidth: 180
|
||||||
@ -13,7 +13,6 @@ import EditIcon from '../../components/Icons/EditIcon'
|
|||||||
import CheckIcon from '../../components/Icons/CheckIcon'
|
import CheckIcon from '../../components/Icons/CheckIcon'
|
||||||
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
||||||
import PlusIcon from '../../components/Icons/PlusIcon'
|
import PlusIcon from '../../components/Icons/PlusIcon'
|
||||||
import { calculateUserPermissions } from '../permissions.js'
|
|
||||||
|
|
||||||
export const User = {
|
export const User = {
|
||||||
name: 'user',
|
name: 'user',
|
||||||
@ -93,7 +92,6 @@ export const User = {
|
|||||||
'name',
|
'name',
|
||||||
'username',
|
'username',
|
||||||
'email',
|
'email',
|
||||||
'groups',
|
|
||||||
'permissionSettings',
|
'permissionSettings',
|
||||||
'createdAt',
|
'createdAt',
|
||||||
'updatedAt'
|
'updatedAt'
|
||||||
@ -104,7 +102,6 @@ export const User = {
|
|||||||
'firstName',
|
'firstName',
|
||||||
'lastName',
|
'lastName',
|
||||||
'email',
|
'email',
|
||||||
'groups',
|
|
||||||
'permissionSettings',
|
'permissionSettings',
|
||||||
'createdAt',
|
'createdAt',
|
||||||
'updatedAt',
|
'updatedAt',
|
||||||
@ -181,19 +178,11 @@ export const User = {
|
|||||||
columnWidth: 300,
|
columnWidth: 300,
|
||||||
type: 'email'
|
type: 'email'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'groups',
|
|
||||||
label: 'Groups',
|
|
||||||
type: 'objectList',
|
|
||||||
objectType: 'userGroup',
|
|
||||||
span: 2,
|
|
||||||
columnWidth: 250
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'permissionSettings',
|
name: 'permissionSettings',
|
||||||
label: 'Permission Settings',
|
label: 'Permission Settings',
|
||||||
type: 'objectList',
|
type: 'objectList',
|
||||||
objectType: 'permissionSetting',
|
objectType: 'permissionSettings',
|
||||||
span: 2,
|
span: 2,
|
||||||
columnWidth: 250
|
columnWidth: 250
|
||||||
},
|
},
|
||||||
@ -204,8 +193,7 @@ export const User = {
|
|||||||
inherit: false,
|
inherit: false,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
span: 2,
|
span: 2,
|
||||||
columnWidth: 200,
|
columnWidth: 200
|
||||||
value: calculateUserPermissions
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'profileImage',
|
name: 'profileImage',
|
||||||
|
|||||||
@ -1,142 +0,0 @@
|
|||||||
import { createElement, lazy } from 'react'
|
|
||||||
|
|
||||||
const UserGroupInfo = lazy(
|
|
||||||
() => import('../../components/Dashboard/Management/UserGroups/UserGroupInfo')
|
|
||||||
)
|
|
||||||
import PersonGroupIcon from '../../components/Icons/PersonGroupIcon'
|
|
||||||
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
|
|
||||||
import EditIcon from '../../components/Icons/EditIcon'
|
|
||||||
import CheckIcon from '../../components/Icons/CheckIcon'
|
|
||||||
import XMarkIcon from '../../components/Icons/XMarkIcon'
|
|
||||||
import BinIcon from '../../components/Icons/BinIcon'
|
|
||||||
import { calculateUserGroupPermissions } from '../permissions.js'
|
|
||||||
|
|
||||||
export const UserGroup = {
|
|
||||||
name: 'userGroup',
|
|
||||||
label: 'User Group',
|
|
||||||
labelPlural: 'User Groups',
|
|
||||||
url: '/dashboard/management/usergroups',
|
|
||||||
prefix: 'UGP',
|
|
||||||
icon: PersonGroupIcon,
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
name: 'info',
|
|
||||||
type: 'page',
|
|
||||||
pageName: 'info',
|
|
||||||
label: 'Info',
|
|
||||||
default: true,
|
|
||||||
row: true,
|
|
||||||
icon: InfoCircleIcon
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'edit',
|
|
||||||
type: 'page',
|
|
||||||
pageName: 'info',
|
|
||||||
label: 'Edit',
|
|
||||||
row: true,
|
|
||||||
icon: EditIcon,
|
|
||||||
visible: (objectData) => {
|
|
||||||
return !(objectData?._isEditing && objectData?._isEditing == true)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'cancelEdit',
|
|
||||||
label: 'Cancel Edits',
|
|
||||||
type: 'page',
|
|
||||||
pageName: 'info',
|
|
||||||
icon: XMarkIcon,
|
|
||||||
visible: (objectData) => {
|
|
||||||
return objectData?._isEditing && objectData?._isEditing == true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'finishEdit',
|
|
||||||
label: 'Save Edits',
|
|
||||||
type: 'page',
|
|
||||||
pageName: 'info',
|
|
||||||
icon: CheckIcon,
|
|
||||||
visible: (objectData) => {
|
|
||||||
return objectData?._isEditing && objectData?._isEditing == true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
name: 'delete',
|
|
||||||
type: 'page',
|
|
||||||
pageName: 'info',
|
|
||||||
label: 'Delete',
|
|
||||||
icon: BinIcon,
|
|
||||||
danger: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
pages: [
|
|
||||||
{
|
|
||||||
name: 'info',
|
|
||||||
content: () => createElement(UserGroupInfo)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
columns: ['_reference', 'name', 'permissionSettings', 'createdAt', 'updatedAt'],
|
|
||||||
filters: ['name', 'permissionSettings', 'createdAt', 'updatedAt', '_reference'],
|
|
||||||
sorters: ['name', 'createdAt', '_id', 'updatedAt'],
|
|
||||||
properties: [
|
|
||||||
{
|
|
||||||
name: '_id',
|
|
||||||
label: 'ID',
|
|
||||||
columnFixed: 'left',
|
|
||||||
type: 'id',
|
|
||||||
objectType: 'userGroup',
|
|
||||||
showCopy: true,
|
|
||||||
columnWidth: 140
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'createdAt',
|
|
||||||
label: 'Created At',
|
|
||||||
type: 'dateTime',
|
|
||||||
readOnly: true,
|
|
||||||
columnWidth: 175
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '_reference',
|
|
||||||
label: 'Reference',
|
|
||||||
columnFixed: 'left',
|
|
||||||
type: 'reference',
|
|
||||||
objectType: 'userGroup',
|
|
||||||
showCopy: true,
|
|
||||||
readOnly: true,
|
|
||||||
columnWidth: 180
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'updatedAt',
|
|
||||||
label: 'Updated At',
|
|
||||||
type: 'dateTime',
|
|
||||||
readOnly: true,
|
|
||||||
columnWidth: 175
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'name',
|
|
||||||
label: 'Name',
|
|
||||||
columnFixed: 'left',
|
|
||||||
required: true,
|
|
||||||
type: 'text',
|
|
||||||
columnWidth: 200
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'permissionSettings',
|
|
||||||
label: 'Permission Settings',
|
|
||||||
type: 'objectList',
|
|
||||||
objectType: 'permissionSetting',
|
|
||||||
span: 2,
|
|
||||||
columnWidth: 250
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'permissions',
|
|
||||||
label: 'Permissions',
|
|
||||||
type: 'permissionsMatrix',
|
|
||||||
inherit: false,
|
|
||||||
readOnly: true,
|
|
||||||
span: 2,
|
|
||||||
columnWidth: 200,
|
|
||||||
value: calculateUserGroupPermissions
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
export const applyPermissionSettingsList = (settingsList = []) => {
|
|
||||||
const permissions = {}
|
|
||||||
|
|
||||||
for (const setting of settingsList) {
|
|
||||||
const matrix = setting?.permissions
|
|
||||||
if (!matrix || typeof matrix !== 'object' || Array.isArray(matrix)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [modelName, actions] of Object.entries(matrix)) {
|
|
||||||
if (!actions || typeof actions !== 'object' || Array.isArray(actions)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (!permissions[modelName]) {
|
|
||||||
permissions[modelName] = {}
|
|
||||||
}
|
|
||||||
for (const [actionName, value] of Object.entries(actions)) {
|
|
||||||
if (value === true || value === false) {
|
|
||||||
permissions[modelName][actionName] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Object.keys(permissions[modelName]).length === 0) {
|
|
||||||
delete permissions[modelName]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissions
|
|
||||||
}
|
|
||||||
|
|
||||||
export const calculateUserPermissions = (objectData = {}) =>
|
|
||||||
applyPermissionSettingsList([
|
|
||||||
...(objectData.groups || []),
|
|
||||||
...(objectData.permissionSettings || [])
|
|
||||||
])
|
|
||||||
|
|
||||||
export const calculateUserGroupPermissions = (objectData = {}) =>
|
|
||||||
applyPermissionSettingsList(objectData.permissionSettings)
|
|
||||||
@ -125,15 +125,9 @@ const managementSidebarItems = [
|
|||||||
label: 'Users',
|
label: 'Users',
|
||||||
path: '/dashboard/management/users'
|
path: '/dashboard/management/users'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'userGroups',
|
|
||||||
iconKey: 'userGroup',
|
|
||||||
label: 'User Groups',
|
|
||||||
path: '/dashboard/management/usergroups'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'permissionSettings',
|
key: 'permissionSettings',
|
||||||
iconKey: 'permissionSetting',
|
iconKey: 'permissionSettings',
|
||||||
label: 'Permission Settings',
|
label: 'Permission Settings',
|
||||||
path: '/dashboard/management/permissionsettings'
|
path: '/dashboard/management/permissionsettings'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -43,9 +43,6 @@ const NoteInfo = lazy(
|
|||||||
() => import('../components/Dashboard/Management/Notes/NoteInfo.jsx')
|
() => import('../components/Dashboard/Management/Notes/NoteInfo.jsx')
|
||||||
)
|
)
|
||||||
const Users = lazy(() => import('../components/Dashboard/Management/Users.jsx'))
|
const Users = lazy(() => import('../components/Dashboard/Management/Users.jsx'))
|
||||||
const UserGroups = lazy(
|
|
||||||
() => import('../components/Dashboard/Management/UserGroups.jsx')
|
|
||||||
)
|
|
||||||
const PermissionSettings = lazy(
|
const PermissionSettings = lazy(
|
||||||
() => import('../components/Dashboard/Management/PermissionSettings.jsx')
|
() => import('../components/Dashboard/Management/PermissionSettings.jsx')
|
||||||
)
|
)
|
||||||
@ -98,11 +95,6 @@ const ManagementRoutes = [
|
|||||||
<Route key='vendors' path='management/vendors' element={<Vendors />} />,
|
<Route key='vendors' path='management/vendors' element={<Vendors />} />,
|
||||||
<Route key='hosts' path='management/hosts' element={<Hosts />} />,
|
<Route key='hosts' path='management/hosts' element={<Hosts />} />,
|
||||||
<Route key='users' path='management/users' element={<Users />} />,
|
<Route key='users' path='management/users' element={<Users />} />,
|
||||||
<Route
|
|
||||||
key='usergroups'
|
|
||||||
path='management/usergroups'
|
|
||||||
element={<UserGroups />}
|
|
||||||
/>,
|
|
||||||
<Route
|
<Route
|
||||||
key='permissionsettings'
|
key='permissionsettings'
|
||||||
path='management/permissionsettings'
|
path='management/permissionsettings'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user