fix: admin can not delete own

This commit is contained in:
jialin
2025-10-23 17:09:30 +08:00
parent a815e71bfe
commit bf57290197
12 changed files with 57 additions and 18 deletions
+4
View File
@@ -270,6 +270,10 @@
gap: 16px;
}
.gap-4 {
gap: 4px;
}
.color-white-tertiary {
color: var(--color-white-tertiary);
}
+3
View File
@@ -41,6 +41,9 @@ export default function useTableRowSelection() {
selectedRowKeys,
selectedRows,
enableSelection: true,
getCheckboxProps: (record: Record<string, any>) => ({
disabled: record.disabled
}),
clearSelections,
onChange: onSelectChange,
removeSelectedKeys,
+2 -1
View File
@@ -95,5 +95,6 @@ export default {
'resource.register.windows.support': 'win 10, win 11',
'resources.model.instance': 'Model Instance',
'resources.worker.download.privatekey': 'Download Private Key',
'resources.modelfiles.form.exsting': 'Existing'
'resources.modelfiles.form.exsting': 'Downloaded',
'resources.modelfiles.form.added': 'Added'
};
+4 -2
View File
@@ -96,7 +96,8 @@ export default {
'resources.model.instance': 'Model Instance',
'resources.worker.download.privatekey': 'Download Private Key',
'resources.worker': 'Worker',
'resources.modelfiles.form.exsting': 'Existing'
'resources.modelfiles.form.exsting': 'Downloaded',
'resources.modelfiles.form.added': 'Added'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -115,5 +116,6 @@ export default {
// 13. 'resources.model.instance': 'Model Instance',
// 14. 'resources.worker.download.privatekey': 'Download Private Key',
// 15. 'resources.worker': 'Worker',
// 16. 'resources.modelfiles.form.exsting': 'Existing'
// 16. 'resources.modelfiles.form.exsting': 'Downloaded',
// 17. 'resources.modelfiles.form.added': 'Added'
// ========== End of To-Do List ==========
+4 -1
View File
@@ -94,9 +94,12 @@ export default {
'resources.model.instance': 'Модель экземпляра',
'resources.worker.download.privatekey': 'Скачать приватный ключ',
'resources.worker': 'Worker',
'resources.modelfiles.form.exsting': 'Существующий'
'resources.modelfiles.form.exsting': 'Downloaded',
'resources.modelfiles.form.added': 'Added'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'resources.worker': 'Worker',
// 2. 'resources.modelfiles.form.exsting': 'Downloaded',
// 3. 'resources.modelfiles.form.added': 'Added'
// ========== End of To-Do List ==========
+2 -1
View File
@@ -93,5 +93,6 @@ export default {
'resource.register.windows.support': 'win 10, win 11',
'resources.model.instance': '模型实例',
'resources.worker.download.privatekey': '下载私钥',
'resources.modelfiles.form.exsting': '已存在'
'resources.modelfiles.form.exsting': '已下载',
'resources.modelfiles.form.added': '已添加'
};
@@ -2,7 +2,7 @@ import { PageAction } from '@/config';
import { PageActionType } from '@/config/types';
import useAppUtils from '@/hooks/use-app-utils';
import SelectPanel from '@/pages/_components/select-panel';
import { queryModelsList } from '@/pages/llmodels/apis';
import { queryMyModels } from '@/pages/llmodels/apis';
import { useIntl } from '@umijs/max';
import { Divider, Form, Radio } from 'antd';
import { useEffect, useState } from 'react';
@@ -38,7 +38,7 @@ const AllowModelsForm: React.FC<{
const getModelList = async () => {
try {
const res = await queryModelsList(queryParams);
const res = await queryMyModels(queryParams);
const options = res.items.map((item) => item.name);
if (action === PageAction.EDIT && currentData) {
const list = new Set([
@@ -186,11 +186,11 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
item.title.toLowerCase().includes(inputValue.toLowerCase())
}
render={(item) => (
<span className="flex-center gap-8">
<span className="flex-center gap-4">
<span>{item.title}</span>
<span className="text-tertiary">
{item.is_admin
? `(${intl.formatMessage({ id: 'models.table.admin' })})`
? `[${intl.formatMessage({ id: 'models.table.admin' })}]`
: ''}
</span>
</span>
+8 -3
View File
@@ -52,6 +52,7 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
const { getRuleMessage } = useAppUtils();
const intl = useIntl();
const [form] = Form.useForm();
const localPath = Form.useWatch('local_path', form);
useEffect(() => {
const init = async () => {
@@ -95,18 +96,22 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
const isExisting = currentWorker?.children?.some((child) => {
const isSameFile =
child.fileName === (fileName || '') ||
child.fileName === (fileName || localPath || '') ||
minimatch(child.fileName || '', fileName || '');
return child.repoId === selectedModel?.name && isSameFile;
return child.repoId === (selectedModel?.name || '') && isSameFile;
});
const localeId = localPath
? 'resources.modelfiles.form.added'
: 'resources.modelfiles.form.exsting';
return (
<span>
{data.label}
{isExisting && (
<span className="text-tertiary m-l-4">
({intl.formatMessage({ id: 'resources.modelfiles.form.exsting' })})
[{intl.formatMessage({ id: localeId })}]
</span>
)}
</span>
@@ -133,6 +133,7 @@ const ModelFiles = () => {
).pop()
);
// select the worker current model file is downloaded to.
const targetWorker = _.find(workersList, { value: record.worker_id })
?.labels?.['worker-name'];
+14 -3
View File
@@ -3,7 +3,8 @@ import AutoTooltip from '@/components/auto-tooltip';
import DropdownButtons from '@/components/drop-down-buttons';
import IconFont from '@/components/icon-font';
import icons from '@/components/icon-font/icons';
import { useIntl } from '@umijs/max';
import { useIntl, useModel } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import { Tag } from 'antd';
import type { SortOrder } from 'antd/es/table/interface';
import { ColumnsType } from 'antd/lib/table';
@@ -35,6 +36,16 @@ const useUsersColumns = ({
sortOrder
}: ColumnsHookProps): ColumnsType<ListItem> => {
const intl = useIntl();
const { initialState } = useModel('@@initialState') || {};
const setActions = useMemoizedFn((record: ListItem) => {
return actionList.filter((action) => {
if (initialState?.currentUser?.id === record.id) {
return action.key !== 'delete';
}
return true;
});
});
return useMemo(() => {
return [
@@ -168,13 +179,13 @@ const useUsersColumns = ({
span: 3,
render: (text, record) => (
<DropdownButtons
items={actionList}
items={setActions(record)}
onSelect={(val) => handleSelect(val, record)}
/>
)
}
];
}, [sortOrder, intl, handleSelect]);
}, [sortOrder, intl, handleSelect, setActions]);
};
export default useUsersColumns;
+11 -3
View File
@@ -5,10 +5,10 @@ import { PageAction } from '@/config';
import type { PageActionType } from '@/config/types';
import useTableFetch from '@/hooks/use-table-fetch';
import { PageContainer } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { useIntl, useModel } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import { Button, ConfigProvider, message, Table } from 'antd';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import NoResult from '../_components/no-result';
import { createUser, deleteUser, queryUsersList, updateUser } from './apis';
import AddModal from './components/add-modal';
@@ -35,6 +35,7 @@ const Users: React.FC = () => {
contentForDelete: 'users.table.user'
});
const { initialState } = useModel('@@initialState') || {};
const intl = useIntl();
const [openAddModalStatus, setOpenAddModalStatus] = useState<{
action: PageActionType;
@@ -155,6 +156,13 @@ const Users: React.FC = () => {
sortOrder
});
const dataList = useMemo(() => {
return dataSource.dataList.map((item) => ({
...item,
disabled: initialState?.currentUser?.id === item.id
}));
}, [dataSource.dataList, initialState?.currentUser?.id]);
return (
<>
<PageContainer
@@ -182,7 +190,7 @@ const Users: React.FC = () => {
<ConfigProvider renderEmpty={renderEmpty}>
<Table
columns={columns}
dataSource={dataSource.dataList}
dataSource={dataList}
rowSelection={rowSelection}
loading={dataSource.loading}
rowKey="id"