import { ActionContextProvider, RecordProvider, SchemaComponent, useAPIClient, useResourceActionContext, } from '@nocobase/client'; import { Menu, Empty, Dropdown, App, Tag, Row, Col, Spin } from 'antd'; import { TagOutlined, MoreOutlined } from '@ant-design/icons'; import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useACLTranslation } from './locale'; import { Schema } from '@formily/react'; import { RolesManagerContext } from './RolesManagerProvider'; import { roleEditSchema } from './schemas/roles'; import { useLoadMoreObserver } from './hooks/load-more-observer'; export const RolesMenu: React.FC & { Item: React.FC<{ item: any; onEdit: () => void }>; } = () => { const { t } = useACLTranslation(); const { data, mutate } = useResourceActionContext(); const [visible, setVisible] = useState(false); const [record, setRecord] = useState(null); const { role, setRole } = useContext(RolesManagerContext); const [roles, setRoles] = useState([]); const [loading, setLoading] = useState(false); const api = useAPIClient(); const loadMore = useCallback(async () => { const meta = data?.meta; if (!meta || meta.page >= meta.totalPage) { return; } setLoading(true); const res = await api.resource('roles').list({ page: meta.page + 1, pageSize: meta.pageSize, filter: { 'name.$ne': 'root', }, showAnonymous: true, sort: ['createdAt'], appends: [], }); mutate(res?.data || {}); setLoading(false); }, [data]); const { lastItem, setLastItem } = useLoadMoreObserver({ loadMore }); const handleSelect = ({ key }) => { setRole(roles.find((item: any) => item.name === key)); }; useEffect(() => { if (!roles[0]) { return; } setRole(roles[0]); }, [roles, setRole]); useEffect(() => { if (!data?.data?.length) { return; } const ref = React.createRef(); setLastItem(ref); if (data.meta?.page > 1) { setRoles((prev) => prev.concat(data.data)); } else { setRoles(data.data); } }, [data, setLastItem]); const items = useMemo( () => roles.map((item: any, index: number) => ({ key: item.name, label: index === roles.length - 1 ? (
{ setVisible(true); setRecord(item); }} />
) : ( { setVisible(true); setRecord(item); }} /> ), })), [roles, lastItem], ); return ( <> {roles.length ? ( }] : [])]} selectedKeys={[role?.name]} onSelect={handleSelect} /> ) : ( )} ); }; RolesMenu.Item = function DepartmentTreeItem({ item, onEdit }) { const { t } = useACLTranslation(); const { refreshAsync } = useResourceActionContext(); const { modal, message } = App.useApp(); const api = useAPIClient(); const deleteDepartment = () => { modal.confirm({ title: t('Delete'), content: t('Are you sure you want to delete it?'), onOk: async () => { await api.resource('roles').destroy({ filterByTk: item.name }); message.success(t('Deleted successfully')); await refreshAsync(); }, }); }; const handleClick = ({ key, domEvent }) => { domEvent.stopPropagation(); switch (key) { case 'edit': onEdit(); break; case 'delete': deleteDepartment(); } }; const title = Schema.compile(item.title, { t }); return ( {title} {item.default ? ( {t('Default')} ) : null} ); };