From a815e71bfedd1bfbf7e7c3c599c82374609111cf Mon Sep 17 00:00:00 2001 From: jialin Date: Thu, 23 Oct 2025 11:38:12 +0800 Subject: [PATCH] chore: show existing when add file --- package.json | 1 + pnpm-lock.yaml | 22 ++++++ src/components/overlay-scroller/index.tsx | 4 +- src/config/index.ts | 14 ++-- src/locales/en-US/resources.ts | 3 +- src/locales/ja-JP/resources.ts | 4 +- src/locales/ru-RU/resources.ts | 3 +- src/locales/zh-CN/resources.ts | 3 +- src/locales/zh-CN/users.ts | 4 +- src/pages/_components/select-panel/index.tsx | 4 +- .../components/deploy-builtin-modal.tsx | 5 ++ src/pages/llmodels/components/gpu-card.tsx | 6 +- src/pages/llmodels/components/model-item.tsx | 20 ++++- src/pages/llmodels/components/model-tag.tsx | 2 +- src/pages/llmodels/download/index.tsx | 11 ++- src/pages/llmodels/download/target-form.tsx | 79 +++++++++++++++++-- src/pages/llmodels/forms/index.tsx | 20 ++--- .../llmodels/forms/local-path-source.tsx | 1 - src/pages/llmodels/forms/schedule-type.tsx | 8 ++ src/pages/llmodels/hooks/index.ts | 40 +++++++--- .../llmodels/hooks/use-form-initial-values.ts | 7 +- .../resources/components/model-files.tsx | 1 + .../resources/hooks/use-files-columns.tsx | 12 +-- src/pages/users/components/add-modal.tsx | 34 ++++---- src/pages/users/hooks/use-users-columns.tsx | 45 +++++++---- 25 files changed, 256 insertions(+), 97 deletions(-) diff --git a/package.json b/package.json index 9c7360b0..90ad4ec1 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "lodash": "^4.17.21", "mammoth": "^1.8.0", "marked": "^14.1.0", + "minimatch": "^10.0.3", "ml-dataset-iris": "^1.2.1", "ml-pca": "^4.1.1", "monaco-editor": "^0.53.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed637858..9c1f0482 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,6 +126,9 @@ dependencies: marked: specifier: ^14.1.0 version: 14.1.4 + minimatch: + specifier: ^10.0.3 + version: 10.0.3 ml-dataset-iris: specifier: ^1.2.1 version: 1.2.1 @@ -2647,6 +2650,18 @@ packages: - supports-color dev: false + /@isaacs/balanced-match@4.0.1: + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, tarball: https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz} + engines: {node: 20 || >=22} + dev: false + + /@isaacs/brace-expansion@5.0.0: + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==, tarball: https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz} + engines: {node: 20 || >=22} + dependencies: + '@isaacs/balanced-match': 4.0.1 + dev: false + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, tarball: https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz} engines: {node: '>=12'} @@ -11096,6 +11111,13 @@ packages: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==, tarball: https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz} dev: false + /minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==, tarball: https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz} + engines: {node: 20 || >=22} + dependencies: + '@isaacs/brace-expansion': 5.0.0 + dev: false + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, tarball: https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz} dependencies: diff --git a/src/components/overlay-scroller/index.tsx b/src/components/overlay-scroller/index.tsx index 0174723c..73e2fd41 100644 --- a/src/components/overlay-scroller/index.tsx +++ b/src/components/overlay-scroller/index.tsx @@ -20,8 +20,9 @@ export const OverlayScroller: React.FC< maxHeight?: number; style?: React.CSSProperties; children: React.ReactNode; + onScroll?: (e: React.UIEvent) => void; } -> = ({ children, maxHeight, scrollbars, oppositeTheme, style }) => { +> = ({ children, maxHeight, scrollbars, oppositeTheme, style, onScroll }) => { const scroller = React.useRef(null); const { initialize } = useOverlayScroller({ options: { @@ -43,6 +44,7 @@ export const OverlayScroller: React.FC< className="overlay-scroller-wrapper" $maxHeight={maxHeight || 200} hidden={false} + onWheel={onScroll} style={{ paddingInlineStart: 8, paddingInlineEnd: 8, diff --git a/src/config/index.ts b/src/config/index.ts index 0e6c1294..126766ac 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,11 +1,11 @@ -import { PageActionType, StatusType } from './types'; +import { StatusType } from './types'; -export const PageAction: Record = { - CREATE: 'create', - UPDATE: 'update', - VIEW: 'view', - EDIT: 'edit' -}; +export enum PageAction { + CREATE = 'create', + UPDATE = 'update', + VIEW = 'view', + EDIT = 'edit' +} export const StatusColorMap: Record< StatusType, diff --git a/src/locales/en-US/resources.ts b/src/locales/en-US/resources.ts index 45099d64..4d423a87 100644 --- a/src/locales/en-US/resources.ts +++ b/src/locales/en-US/resources.ts @@ -94,5 +94,6 @@ export default { 'resource.register.maos.support': 'Apple Silicon (M series), macOS 14+', 'resource.register.windows.support': 'win 10, win 11', 'resources.model.instance': 'Model Instance', - 'resources.worker.download.privatekey': 'Download Private Key' + 'resources.worker.download.privatekey': 'Download Private Key', + 'resources.modelfiles.form.exsting': 'Existing' }; diff --git a/src/locales/ja-JP/resources.ts b/src/locales/ja-JP/resources.ts index f098f584..e929ec0c 100644 --- a/src/locales/ja-JP/resources.ts +++ b/src/locales/ja-JP/resources.ts @@ -95,7 +95,8 @@ export default { 'resource.register.windows.support': 'win 10, win 11', 'resources.model.instance': 'Model Instance', 'resources.worker.download.privatekey': 'Download Private Key', - 'resources.worker': 'Worker' + 'resources.worker': 'Worker', + 'resources.modelfiles.form.exsting': 'Existing' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== @@ -114,4 +115,5 @@ 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' // ========== End of To-Do List ========== diff --git a/src/locales/ru-RU/resources.ts b/src/locales/ru-RU/resources.ts index c140da9b..a3a91883 100644 --- a/src/locales/ru-RU/resources.ts +++ b/src/locales/ru-RU/resources.ts @@ -93,7 +93,8 @@ export default { 'resource.register.windows.support': 'Windows 10, Windows 11', 'resources.model.instance': 'Модель экземпляра', 'resources.worker.download.privatekey': 'Скачать приватный ключ', - 'resources.worker': 'Worker' + 'resources.worker': 'Worker', + 'resources.modelfiles.form.exsting': 'Существующий' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== diff --git a/src/locales/zh-CN/resources.ts b/src/locales/zh-CN/resources.ts index 5c5674d5..e125af0a 100644 --- a/src/locales/zh-CN/resources.ts +++ b/src/locales/zh-CN/resources.ts @@ -92,5 +92,6 @@ export default { 'resource.register.maos.support': 'M 芯片,macOS 14+', 'resource.register.windows.support': 'win 10, win 11', 'resources.model.instance': '模型实例', - 'resources.worker.download.privatekey': '下载私钥' + 'resources.worker.download.privatekey': '下载私钥', + 'resources.modelfiles.form.exsting': '已存在' }; diff --git a/src/locales/zh-CN/users.ts b/src/locales/zh-CN/users.ts index 072bc787..826092cd 100644 --- a/src/locales/zh-CN/users.ts +++ b/src/locales/zh-CN/users.ts @@ -6,8 +6,8 @@ export default { 'users.table.username': '用户名', 'users.table.role': '角色', 'users.table.status': '状态', - 'users.status.active': '激活', - 'users.status.inactive': '禁用', + 'users.status.active': '启用', + 'users.status.inactive': '停用', 'users.form.active': '激活账户', 'users.form.active.description': '启用或禁用此用户账户', 'users.form.fullname': '全名', diff --git a/src/pages/_components/select-panel/index.tsx b/src/pages/_components/select-panel/index.tsx index 2dbb21b1..b13b4e20 100644 --- a/src/pages/_components/select-panel/index.tsx +++ b/src/pages/_components/select-panel/index.tsx @@ -139,7 +139,7 @@ const SelectPanel: React.FC = ({ selectedKeys.includes(item.key) )} @@ -194,7 +194,7 @@ const SelectPanel: React.FC = ({ {showOptions.length > 0 ? ( = (props) => { >
- - {_.find(modelCategories, { value: model.categories?.[0] }) - ?.label || model.categories?.[0]} - + {model.categories?.length > 0 && + model.categories.map((sItem: string) => { + return ( + + {_.find(modelCategories, { value: sItem })?.label || + sItem} + + ); + })} {maxToken > 0 && ( {maxToken}K context diff --git a/src/pages/llmodels/components/model-tag.tsx b/src/pages/llmodels/components/model-tag.tsx index fbea9a61..35e891bb 100644 --- a/src/pages/llmodels/components/model-tag.tsx +++ b/src/pages/llmodels/components/model-tag.tsx @@ -7,7 +7,7 @@ import { import { Tag } from 'antd'; import { modelCategoriesMap } from '../config'; -const categoryConfig = { +export const categoryConfig = { [modelCategoriesMap.reranker]: { icon: , color: 'cyan', diff --git a/src/pages/llmodels/download/index.tsx b/src/pages/llmodels/download/index.tsx index dd96f07d..7b5cc6c6 100644 --- a/src/pages/llmodels/download/index.tsx +++ b/src/pages/llmodels/download/index.tsx @@ -22,6 +22,7 @@ type AddModalProps = { width?: string | number; hasLinuxWorker?: boolean; workerOptions: any[]; + workersList?: any[]; onOk: (values: FormData) => void; onCancel: () => void; }; @@ -47,7 +48,8 @@ const DownloadModel: React.FC = (props) => { hasLinuxWorker, source, width = 600, - workerOptions + workerOptions, + workersList } = props || {}; const SEARCH_SOURCE = [ modelSourceMap.huggingface_value, @@ -66,7 +68,7 @@ const DownloadModel: React.FC = (props) => { if (source === modelSourceMap.huggingface_value) { const huggingFaceModel = { huggingface_repo_id: selectedModel.name, - huggingface_filename: null + huggingface_filename: fileName || null }; return huggingFaceModel; } @@ -74,7 +76,7 @@ const DownloadModel: React.FC = (props) => { if (source === modelSourceMap.modelscope_value) { const modelScopeModel = { model_scope_model_id: selectedModel.name, - model_scope_file_path: null + model_scope_file_path: fileName || null }; return modelScopeModel; } @@ -238,6 +240,9 @@ const DownloadModel: React.FC = (props) => { ref={form} onOk={handleOk} source={source} + selectedModel={selectedModel} + fileName={fileName} + workersList={workersList} workerOptions={workerOptions} > diff --git a/src/pages/llmodels/download/target-form.tsx b/src/pages/llmodels/download/target-form.tsx index c33a9e77..7b840e88 100644 --- a/src/pages/llmodels/download/target-form.tsx +++ b/src/pages/llmodels/download/target-form.tsx @@ -7,22 +7,64 @@ import { ModelFileFormData as FormData } from '@/pages/resources/config/types'; import { useIntl } from '@umijs/max'; import { Form } from 'antd'; import _ from 'lodash'; -import React, { forwardRef, useImperativeHandle, useMemo } from 'react'; +import { minimatch } from 'minimatch'; +import React, { + forwardRef, + useEffect, + useImperativeHandle, + useMemo +} from 'react'; import { localPathTipsList, modelSourceMap, sourceOptions } from '../config'; +import { useGenerateWorkersModelFileOptions } from '../hooks'; + +type EmptyObject = Record; + +type CascaderOption = { + label: string; + value: string | number; + parent?: boolean; + disabled?: boolean; + index?: number; + children?: CascaderOption[]; +} & Partial; interface TargetFormProps { ref?: any; source: string; - workerOptions: any[]; + workerOptions: CascaderOption<{ state: string }>[]; + workersList?: Global.BaseOption< + number, + { state: string; labels: Record; cluster_id: number } + >[]; + selectedModel?: Record; + fileName?: string; onOk: (values: any) => void; } const TargetForm: React.FC = forwardRef((props, ref) => { - const { onOk, source, workerOptions } = props; + const { + modelFileOptions, + getModelFileList, + generateWorkersModelFileOptions + } = useGenerateWorkersModelFileOptions(); + const { onOk, source, workerOptions, workersList, selectedModel, fileName } = + props; const { getRuleMessage } = useAppUtils(); const intl = useIntl(); const [form] = Form.useForm(); + useEffect(() => { + const init = async () => { + try { + if (workersList && workersList?.length > 0) { + const modelFiles = await getModelFileList(); + generateWorkersModelFileOptions(modelFiles, workersList || []); + } + } catch (error) {} + }; + init(); + }, [workersList]); + useImperativeHandle(ref, () => ({ form })); @@ -33,10 +75,6 @@ const TargetForm: React.FC = forwardRef((props, ref) => { ...data, worker_id: data.worker_id?.[1] }); - console.log('Form Data: ', { - ...data, - worker_id: data.worker_id?.[1] - }); }; const handleOnLocalPathBlur = (e: any) => { @@ -49,6 +87,32 @@ const TargetForm: React.FC = forwardRef((props, ref) => { }); }; + const renderOptionNode = (props: { data: any }) => { + const { data } = props; + const currentWorker = modelFileOptions.find( + (item) => item.value === data.value + ); + + const isExisting = currentWorker?.children?.some((child) => { + const isSameFile = + child.fileName === (fileName || '') || + minimatch(child.fileName || '', fileName || ''); + + return child.repoId === selectedModel?.name && isSameFile; + }); + + return ( + + {data.label} + {isExisting && ( + + ({intl.formatMessage({ id: 'resources.modelfiles.form.exsting' })}) + + )} + + ); + }; + const renderLocalPathFields = () => { return ( <> @@ -136,6 +200,7 @@ const TargetForm: React.FC = forwardRef((props, ref) => { label={intl.formatMessage({ id: 'resources.worker' })} options={workerOptions} showCheckedStrategy="SHOW_CHILD" + optionNode={renderOptionNode} getPopupContainer={(triggerNode) => triggerNode.parentNode} > diff --git a/src/pages/llmodels/forms/index.tsx b/src/pages/llmodels/forms/index.tsx index da276089..dddb6014 100644 --- a/src/pages/llmodels/forms/index.tsx +++ b/src/pages/llmodels/forms/index.tsx @@ -1,3 +1,4 @@ +import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import CollapsePanel from '@/pages/_components/collapse-panel'; import { useIntl } from '@umijs/max'; @@ -122,22 +123,21 @@ const DataForm: React.FC = forwardRef((props, ref) => { const SegmentedTop = useMemo(() => { if ( - [ - modelSourceMap.huggingface_value, - modelSourceMap.modelscope_value - ].includes(source) && - formKey === deployFormKeyMap.deployment + modelSourceMap.local_path_value === source || + action === PageAction.EDIT || + formKey === deployFormKeyMap.catalog ) { return { - top: 50, - offsetTop: 146 + top: 0, + offsetTop: 96 }; } + return { - top: 0, - offsetTop: 96 + top: 50, + offsetTop: 146 }; - }, [source, formKey]); + }, [source, formKey, action]); const handleSumit = () => { form.submit(); diff --git a/src/pages/llmodels/forms/local-path-source.tsx b/src/pages/llmodels/forms/local-path-source.tsx index b6cf1870..6d3e21c3 100644 --- a/src/pages/llmodels/forms/local-path-source.tsx +++ b/src/pages/llmodels/forms/local-path-source.tsx @@ -98,7 +98,6 @@ const LocalPathForm: React.FC = () => { } diff --git a/src/pages/llmodels/forms/schedule-type.tsx b/src/pages/llmodels/forms/schedule-type.tsx index c0cb630a..ce48eb95 100644 --- a/src/pages/llmodels/forms/schedule-type.tsx +++ b/src/pages/llmodels/forms/schedule-type.tsx @@ -94,6 +94,14 @@ const ScheduleTypeForm: React.FC = () => { const handleOnStepReplica = (value: number | null) => { if (value === null) { form.setFieldValue(['gpu_selector', 'gpus_per_replica'], 1); + return; + } + + const isPowerOfTwo = (n: number) => (n & (n - 1)) === 0 && n !== 0; // check power of two + if (!isPowerOfTwo(value)) { + const newValue = Math.pow(2, Math.round(Math.log2(value))); + form.setFieldValue(['gpu_selector', 'gpus_per_replica'], newValue); + onValuesChange?.({}, form.getFieldsValue()); } }; diff --git a/src/pages/llmodels/hooks/index.ts b/src/pages/llmodels/hooks/index.ts index 36fe8102..3382a71c 100644 --- a/src/pages/llmodels/hooks/index.ts +++ b/src/pages/llmodels/hooks/index.ts @@ -25,12 +25,27 @@ export type MessageStatus = { evaluateResult?: EvaluateResult; }; +export interface ModelFileOption { + label: string; + value: number; + labels?: Record; + parent: boolean; + repoId?: string; + fileName?: string; + [key: string]: any; + children?: ModelFileOption[]; +} + export type WarningStausOptions = { lockAfterUpdate?: boolean; override?: boolean; }; -export const useGenerateModelFileOptions = () => { +export const useGenerateWorkersModelFileOptions = () => { + const [modelFileOptions, setModelFileOptions] = useState( + [] + ); + const getModelFileList = async () => { try { const res = await queryModelFilesList({ page: 1, perPage: 100 }); @@ -42,7 +57,7 @@ export const useGenerateModelFileOptions = () => { } }; - const generateModelFileOptions = (list: any[], workerList: any[]) => { + const generateWorkersModelFileOptions = (list: any[], workerList: any[]) => { const workerFields = new Set(['name', 'id', 'ip', 'status']); const workersMap = new Map(); @@ -54,7 +69,7 @@ export const useGenerateModelFileOptions = () => { const result = Array.from(workersMap.values()).map((worker) => ({ label: worker.name, - value: worker.name, + value: worker.id, labels: worker.labels, parent: true, children: list @@ -63,18 +78,16 @@ export const useGenerateModelFileOptions = () => { item.worker_id === worker.id && !!item.resolved_paths?.length ) .map((item) => { - const resolved_paths = - Array.isArray(item.resolved_paths) && item.resolved_paths.length - ? item.resolved_paths[0].split('/') - : []; - const label = - resolved_paths.length > 0 ? resolved_paths.pop() : 'Unknown File'; return { label: item.resolved_paths[0] || '', value: item.resolved_paths[0] || '', - worker_labels: worker.labels, - worker_name: worker.name, parent: false, + repoId: item.huggingface_repo_id || item.model_scope_model_id || '', + fileName: + item.huggingface_filename || + item.model_scope_file_path || + item.local_path || + '', ...item }; }), @@ -95,12 +108,15 @@ export const useGenerateModelFileOptions = () => { return acc; }, []); + setModelFileOptions(result); + return childrenList; }; return { getModelFileList, - generateModelFileOptions + modelFileOptions, + generateWorkersModelFileOptions }; }; diff --git a/src/pages/llmodels/hooks/use-form-initial-values.ts b/src/pages/llmodels/hooks/use-form-initial-values.ts index 229c1d5d..408f3760 100644 --- a/src/pages/llmodels/hooks/use-form-initial-values.ts +++ b/src/pages/llmodels/hooks/use-form-initial-values.ts @@ -15,7 +15,7 @@ import { GPUListItem, ListItem } from '../config/types'; type EmptyObject = Record; -type CascaderOption = { +export type CascaderOption = { label: string; value: string | number; parent?: boolean; @@ -210,7 +210,10 @@ export const useGenerateWorkerOptions = () => { cluster_id: item.cluster_id, state: item.state, label: item.name, - value: item.id + value: item.id, + id: item.id, + labels: item.labels || {}, + name: item.name })) ); setClusterList( diff --git a/src/pages/resources/components/model-files.tsx b/src/pages/resources/components/model-files.tsx index 701c8cc5..917aa64e 100644 --- a/src/pages/resources/components/model-files.tsx +++ b/src/pages/resources/components/model-files.tsx @@ -349,6 +349,7 @@ const ModelFiles = () => { width={downloadModalStatus.width} hasLinuxWorker={downloadModalStatus.hasLinuxWorker} workerOptions={readyWorkers} + workersList={workersList} > { filename: record.huggingface_filename || record.huggingface_repo_id }; } + if (record.source === modelSourceMap.modelscope_value) { return { source: `${source}/${record.model_scope_model_id}`, @@ -169,14 +170,7 @@ const getModelInfo = (record: ListItem) => { filename: record.model_scope_file_path || record.model_scope_model_id }; } - if (record.source === modelSourceMap.ollama_library_value) { - return { - source: `${source}/${record.ollama_library_model_name}`, - repo_id: record.ollama_library_model_name, - title: record.ollama_library_model_name, - filename: record.ollama_library_model_name - }; - } + return { source: `${source}${record.local_path}`, repo_id: record.local_path, @@ -275,7 +269,7 @@ const useFilesColumns = (props: { }, render: (text: string, record: ListItem) => { const modelInfo = getModelInfo(record); - const { repo_id, source } = modelInfo; + const { source } = modelInfo; return ( diff --git a/src/pages/users/components/add-modal.tsx b/src/pages/users/components/add-modal.tsx index 7a87a74d..65acc65e 100644 --- a/src/pages/users/components/add-modal.tsx +++ b/src/pages/users/components/add-modal.tsx @@ -6,7 +6,7 @@ import SealSelect from '@/components/seal-form/seal-select'; import SealSwitch from '@/components/seal-form/seal-switch'; import { PageAction, PasswordReg } from '@/config'; import { PageActionType } from '@/config/types'; -import { useIntl } from '@umijs/max'; +import { useIntl, useModel } from '@umijs/max'; import { Form, Select } from 'antd'; import { useEffect } from 'react'; import { UserRoles, UserRolesOptions } from '../config'; @@ -28,6 +28,7 @@ const AddModal: React.FC = ({ data, onCancel }) => { + const { initialState } = useModel('@@initialState') || {}; const [form] = Form.useForm(); const intl = useIntl(); @@ -125,20 +126,23 @@ const AddModal: React.FC = ({
-
- - name="is_active" - rules={[{ required: false }]} - valuePropName="checked" - > - - -
+ {(data?.id !== initialState?.currentUser?.id || + action === PageAction.CREATE) && ( +
+ + name="is_active" + rules={[{ required: false }]} + valuePropName="checked" + > + + +
+ )}
diff --git a/src/pages/users/hooks/use-users-columns.tsx b/src/pages/users/hooks/use-users-columns.tsx index 264e645d..74a34440 100644 --- a/src/pages/users/hooks/use-users-columns.tsx +++ b/src/pages/users/hooks/use-users-columns.tsx @@ -109,20 +109,37 @@ const useUsersColumns = ({ render: (text: string, record: ListItem) => { return ( <> - - {intl.formatMessage({ - id: record.is_active - ? 'users.status.active' - : 'users.status.inactive' - })} - + {record.is_active ? ( + + {intl.formatMessage({ + id: 'users.status.active' + })} + + ) : ( + + {intl.formatMessage({ + id: 'users.status.inactive' + })} + + )} ); }