import { FormItem, FormLayout } from '@formily/antd-v5'; import { ArrayField } from '@formily/core'; import { connect, useField, useForm } from '@formily/react'; import { useCollectionManager, useCollectionManager_deprecated, useCompile, useCollectionRecord, useRecord, } from '@nocobase/client'; import { Checkbox, Table, Tag } from 'antd'; import { isEmpty } from 'lodash'; import React, { createContext } from 'react'; import { useTranslation } from 'react-i18next'; import { useAvailableActions } from './AvailableActions'; import { ScopeSelect } from './ScopeSelect'; import { useStyles } from './style'; const toActionMap = (arr: any[]) => { const obj = {}; arr?.forEach?.((action) => { if (action.name) { obj[action.name] = action; obj[action.name]['scope'] = isEmpty(action.scope) ? null : action.scope; } }); return obj; }; export const RoleResourceCollectionContext = createContext({}); RoleResourceCollectionContext.displayName = 'RoleResourceCollectionContext'; export const RolesResourcesActions = connect((props) => { const { styles } = useStyles(); // const { onChange } = props; const onChange = (values) => { const items = values.map((item) => { return { ...item, scope: isEmpty(item.scope) ? null : item.scope, }; }); props.onChange(items); }; const form = useForm(); const roleCollection = useRecord(); const availableActions = useAvailableActions(); const { getCollection, getCollectionFields } = useCollectionManager_deprecated(); const collection = getCollection(roleCollection.collectionName); const collectionFields = getCollectionFields(roleCollection.collectionName); const compile = useCompile(); const { t } = useTranslation(); const field = useField(); const actionMap: any = toActionMap(field.value || []); const inAction = (actionName, fieldName) => { const action = actionMap?.[actionName]; if (!action) { return false; } return action?.fields?.includes(fieldName); }; const availableActionsWithFields = availableActions.filter((action) => action.allowConfigureFields); const fieldPermissions = collectionFields ?.filter((field) => field.interface) ?.map((field) => { const permission = { ...field }; for (const action of availableActionsWithFields) { permission[action.name] = inAction(action.name, field.name); } return permission; }); const toggleAction = (actionName: string) => { if (actionMap[actionName]) { delete actionMap[actionName]; } else { actionMap[actionName] = { name: actionName, fields: collectionFields?.filter((field) => field.interface)?.map?.((item) => item.name), }; } onChange(Object.values(actionMap)); }; const setScope = (actionName, scope) => { if (!actionMap[actionName]) { toggleAction(actionName); actionMap[actionName]['scope'] = scope; } else { actionMap[actionName]['scope'] = scope; onChange(Object.values(actionMap)); } }; const allChecked = {}; for (const action of availableActionsWithFields) { allChecked[action.name] = collectionFields?.filter((field) => field.interface)?.length === actionMap?.[action.name]?.fields?.length; } return (
compile(value), }, { dataIndex: 'onNewRecord', title: t('Action type'), render: (onNewRecord) => onNewRecord ? ( {t('Action on new records')} ) : ( {t('Action on existing records')} ), }, { dataIndex: 'enabled', title: t('Allow'), render: (enabled, action) => ( { toggleAction(action.name); }} /> ), }, { dataIndex: 'scope', title: t('Data scope'), render: (value, action) => !action.onNewRecord && ( { setScope(action.name, scope); }} /> ), }, ]} dataSource={availableActions?.map((item) => { let enabled = false; let scope = null; if (actionMap[item.name]) { enabled = true; if (!item.onNewRecord) { scope = actionMap[item.name]['scope']; } } return { ...item, enabled, scope, }; })} />
compile(value), }, ...availableActionsWithFields.map((action) => { const checked = allChecked?.[action.name]; return { dataIndex: action.name, title: ( <> { const item = actionMap[action.name] || { name: action.name, }; if (checked) { item.fields = []; } else { item.fields = collectionFields?.map?.((item) => item.name); } actionMap[action.name] = item; onChange(Object.values(actionMap)); }} />{' '} {compile(action.displayName)} ), render: (checked, field) => ( { const item = actionMap[action.name] || { name: action.name, }; const fields: string[] = item.fields || []; if (checked) { const index = fields.indexOf(field.name); fields.splice(index, 1); } else { fields.push(field.name); } item.fields = fields; actionMap[action.name] = item; onChange(Object.values(actionMap)); }} /> ), }; }), ]} /> ); });