diff --git a/CHANGELOG.md b/CHANGELOG.md index db7eba3f70..c88842d58f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.6.10](https://github.com/nocobase/nocobase/compare/v1.6.9...v1.6.10) - 2025-03-25 + +### 🐛 Bug Fixes + +- **[client]** + - Unable to use 'Current User' variable when adding a link page ([#6536](https://github.com/nocobase/nocobase/pull/6536)) by @zhangzhonghe + + - field assignment with null value is ineffective ([#6549](https://github.com/nocobase/nocobase/pull/6549)) by @katherinehhh + + - `yarn doc` command error ([#6540](https://github.com/nocobase/nocobase/pull/6540)) by @gchust + + - Remove the 'Allow multiple selection' option from dropdown single-select fields in filter forms ([#6515](https://github.com/nocobase/nocobase/pull/6515)) by @zhangzhonghe + + - Relational field's data range linkage is not effective ([#6530](https://github.com/nocobase/nocobase/pull/6530)) by @zhangzhonghe + +- **[Collection: Tree]** Migration issue for plugin-collection-tree ([#6537](https://github.com/nocobase/nocobase/pull/6537)) by @2013xile + +- **[Action: Custom request]** Unable to download UTF-8 encoded files ([#6541](https://github.com/nocobase/nocobase/pull/6541)) by @2013xile + ## [v1.6.9](https://github.com/nocobase/nocobase/compare/v1.6.8...v1.6.9) - 2025-03-23 ### 🐛 Bug Fixes diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 3c8127159c..8d31b47137 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -5,6 +5,25 @@ 格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/), 并且本项目遵循 [语义化版本](https://semver.org/spec/v2.0.0.html)。 +## [v1.6.10](https://github.com/nocobase/nocobase/compare/v1.6.9...v1.6.10) - 2025-03-25 + +### 🐛 修复 + +- **[client]** + - 添加链接页面时,无法使用“当前用户”变量 ([#6536](https://github.com/nocobase/nocobase/pull/6536)) by @zhangzhonghe + + - 字段赋值对字段进行“空值”赋值无效 ([#6549](https://github.com/nocobase/nocobase/pull/6549)) by @katherinehhh + + - `yarn doc` 命令报错 ([#6540](https://github.com/nocobase/nocobase/pull/6540)) by @gchust + + - 筛选表单中,移除下拉单选字段的“允许多选”选项 ([#6515](https://github.com/nocobase/nocobase/pull/6515)) by @zhangzhonghe + + - 关系字段的数据范围联动不生效 ([#6530](https://github.com/nocobase/nocobase/pull/6530)) by @zhangzhonghe + +- **[数据表:树]** 树表插件的迁移脚本问题 ([#6537](https://github.com/nocobase/nocobase/pull/6537)) by @2013xile + +- **[操作:自定义请求]** 无法下载utf8编码的文件 ([#6541](https://github.com/nocobase/nocobase/pull/6541)) by @2013xile + ## [v1.6.9](https://github.com/nocobase/nocobase/compare/v1.6.8...v1.6.9) - 2025-03-23 ### 🐛 修复 diff --git a/lerna.json b/lerna.json index 7ecf319f79..23e6020e76 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "npmClient": "yarn", "useWorkspaces": true, "npmClientArgs": ["--ignore-engines"], diff --git a/packages/core/acl/package.json b/packages/core/acl/package.json index cc9cd3f043..bc56252d00 100644 --- a/packages/core/acl/package.json +++ b/packages/core/acl/package.json @@ -1,13 +1,13 @@ { "name": "@nocobase/acl", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/resourcer": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/resourcer": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "minimatch": "^5.1.1" }, "repository": { diff --git a/packages/core/actions/package.json b/packages/core/actions/package.json index 2178fc6ccb..38dc5e54f6 100644 --- a/packages/core/actions/package.json +++ b/packages/core/actions/package.json @@ -1,14 +1,14 @@ { "name": "@nocobase/actions", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/cache": "1.7.0-alpha.4", - "@nocobase/database": "1.7.0-alpha.4", - "@nocobase/resourcer": "1.7.0-alpha.4" + "@nocobase/cache": "1.7.0-beta.9", + "@nocobase/database": "1.7.0-beta.9", + "@nocobase/resourcer": "1.7.0-beta.9" }, "repository": { "type": "git", diff --git a/packages/core/app/package.json b/packages/core/app/package.json index 2641761a27..5e313604bd 100644 --- a/packages/core/app/package.json +++ b/packages/core/app/package.json @@ -1,17 +1,17 @@ { "name": "@nocobase/app", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/database": "1.7.0-alpha.4", - "@nocobase/preset-nocobase": "1.7.0-alpha.4", - "@nocobase/server": "1.7.0-alpha.4" + "@nocobase/database": "1.7.0-beta.9", + "@nocobase/preset-nocobase": "1.7.0-beta.9", + "@nocobase/server": "1.7.0-beta.9" }, "devDependencies": { - "@nocobase/client": "1.7.0-alpha.4" + "@nocobase/client": "1.7.0-beta.9" }, "repository": { "type": "git", diff --git a/packages/core/auth/package.json b/packages/core/auth/package.json index 1a40429580..e9f3bc982c 100644 --- a/packages/core/auth/package.json +++ b/packages/core/auth/package.json @@ -1,16 +1,16 @@ { "name": "@nocobase/auth", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/actions": "1.7.0-alpha.4", - "@nocobase/cache": "1.7.0-alpha.4", - "@nocobase/database": "1.7.0-alpha.4", - "@nocobase/resourcer": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/actions": "1.7.0-beta.9", + "@nocobase/cache": "1.7.0-beta.9", + "@nocobase/database": "1.7.0-beta.9", + "@nocobase/resourcer": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "@types/jsonwebtoken": "^8.5.8", "jsonwebtoken": "^8.5.1" }, diff --git a/packages/core/build/package.json b/packages/core/build/package.json index 5c6db52633..640469707d 100644 --- a/packages/core/build/package.json +++ b/packages/core/build/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/build", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "Library build tool based on rollup.", "main": "lib/index.js", "types": "./lib/index.d.ts", diff --git a/packages/core/cache/package.json b/packages/core/cache/package.json index 1bbfc03f88..d140f17eb7 100644 --- a/packages/core/cache/package.json +++ b/packages/core/cache/package.json @@ -1,12 +1,12 @@ { "name": "@nocobase/cache", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/lock-manager": "1.7.0-alpha.4", + "@nocobase/lock-manager": "1.7.0-beta.9", "bloom-filters": "^3.0.1", "cache-manager": "^5.2.4", "cache-manager-redis-yet": "^4.1.2" diff --git a/packages/core/cli/package.json b/packages/core/cli/package.json index fc1e5c98ea..9cccced612 100644 --- a/packages/core/cli/package.json +++ b/packages/core/cli/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/cli", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./src/index.js", @@ -8,7 +8,7 @@ "nocobase": "./bin/index.js" }, "dependencies": { - "@nocobase/app": "1.7.0-alpha.4", + "@nocobase/app": "1.7.0-beta.9", "@types/fs-extra": "^11.0.1", "@umijs/utils": "3.5.20", "chalk": "^4.1.1", @@ -25,7 +25,7 @@ "tsx": "^4.19.0" }, "devDependencies": { - "@nocobase/devtools": "1.7.0-alpha.4" + "@nocobase/devtools": "1.7.0-beta.9" }, "repository": { "type": "git", diff --git a/packages/core/client/package.json b/packages/core/client/package.json index f1e6a6bb57..66f15cedf8 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/client", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "lib/index.js", "module": "es/index.mjs", @@ -27,9 +27,9 @@ "@formily/reactive-react": "^2.2.27", "@formily/shared": "^2.2.27", "@formily/validator": "^2.2.27", - "@nocobase/evaluators": "1.7.0-alpha.4", - "@nocobase/sdk": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/evaluators": "1.7.0-beta.9", + "@nocobase/sdk": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "ahooks": "^3.7.2", "antd": "5.24.2", "antd-style": "3.7.1", diff --git a/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx b/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx index 038e8c1192..f6c9704fb9 100644 --- a/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx +++ b/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx @@ -102,44 +102,46 @@ export const SettingsCenterConfigure = () => { expandable={{ defaultExpandAllRows: true, }} - columns={[ - { - dataIndex: 'title', - title: t('Plugin name'), - render: (value) => { - return compile(value); + columns={ + [ + { + dataIndex: 'title', + title: t('Plugin name'), + render: (value) => { + return compile(value); + }, }, - }, - { - dataIndex: 'accessible', - title: ( - <> - { - const values = allAclSnippets.map((v) => '!' + v); - if (!allChecked) { - await resource.remove({ - values, - }); - } else { - await resource.add({ - values, - }); - } - refresh(); - message.success(t('Saved successfully')); - }} - />{' '} - {t('Accessible')} - - ), - render: (_, record) => { - const checked = !snippets.includes('!' + record.aclSnippet); - return handleChange(checked, record)} />; + { + dataIndex: 'accessible', + title: ( + <> + { + const values = allAclSnippets.map((v) => '!' + v); + if (!allChecked) { + await resource.remove({ + values, + }); + } else { + await resource.add({ + values, + }); + } + refresh(); + message.success(t('Saved successfully')); + }} + />{' '} + {t('Accessible')} + + ), + render: (_, record) => { + const checked = !snippets.includes('!' + record.aclSnippet); + return handleChange(checked, record)} />; + }, }, - }, - ] as TableProps['columns']} + ] as TableProps['columns'] + } dataSource={settings .filter((v) => { return v.isTopLevel !== false; diff --git a/packages/core/client/src/acl/Configuration/MenuConfigure.tsx b/packages/core/client/src/acl/Configuration/MenuConfigure.tsx index 7726dcb00d..2ab40c0f4d 100644 --- a/packages/core/client/src/acl/Configuration/MenuConfigure.tsx +++ b/packages/core/client/src/acl/Configuration/MenuConfigure.tsx @@ -121,40 +121,42 @@ export const MenuConfigure = () => { expandable={{ defaultExpandAllRows: true, }} - columns={[ - { - dataIndex: 'title', - title: t('Menu item title'), - }, - { - dataIndex: 'accessible', - title: ( - <> - { - if (allChecked) { - await resource.set({ - values: [], - }); - } else { - await resource.set({ - values: allUids, - }); - } - refresh(); - message.success(t('Saved successfully')); - }} - />{' '} - {t('Accessible')} - - ), - render: (_, schema: { uid: string }) => { - const checked = uids.includes(schema.uid); - return handleChange(checked, schema)} />; + columns={ + [ + { + dataIndex: 'title', + title: t('Menu item title'), }, - }, - ] as TableProps['columns']} + { + dataIndex: 'accessible', + title: ( + <> + { + if (allChecked) { + await resource.set({ + values: [], + }); + } else { + await resource.set({ + values: allUids, + }); + } + refresh(); + message.success(t('Saved successfully')); + }} + />{' '} + {t('Accessible')} + + ), + render: (_, schema: { uid: string }) => { + const checked = uids.includes(schema.uid); + return handleChange(checked, schema)} />; + }, + }, + ] as TableProps['columns'] + } dataSource={translateTitle(items)} /> ); diff --git a/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx b/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx index 7bceb4e67e..3dab660bf7 100644 --- a/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx +++ b/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx @@ -105,48 +105,50 @@ export const RolesResourcesActions = connect((props) => { className={antTableCell} size={'small'} pagination={false} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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); + columns={ + [ + { + dataIndex: 'displayName', + title: t('Action display name'), + render: (value) => 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); }} /> ), - }, - ] as TableProps['columns']} + }, + { + dataIndex: 'scope', + title: t('Data scope'), + render: (value, action) => + !action.onNewRecord && ( + { + setScope(action.name, scope); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let enabled = false; let scope = null; @@ -169,60 +171,62 @@ export const RolesResourcesActions = connect((props) => { className={antTableCell} pagination={false} dataSource={fieldPermissions} - columns={[ - { - dataIndex: ['uiSchema', 'title'], - title: t('Field display name'), - render: (value) => compile(value), - }, - ...availableActionsWithFields.map((action) => { - const checked = allChecked?.[action.name]; - return { - dataIndex: action.name, - title: ( - <> + columns={ + [ + { + dataIndex: ['uiSchema', 'title'], + title: t('Field display name'), + render: (value) => 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) { - item.fields = []; + const index = fields.indexOf(field.name); + fields.splice(index, 1); } else { - item.fields = collectionFields?.map?.((item) => item.name); + fields.push(field.name); } + item.fields = fields; 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)); - }} - /> - ), - }; - }), - ] as TableProps['columns']} + /> + ), + }; + }), + ] as TableProps['columns'] + } /> diff --git a/packages/core/client/src/acl/Configuration/StrategyActions.tsx b/packages/core/client/src/acl/Configuration/StrategyActions.tsx index 1f97af946c..4efa5a8716 100644 --- a/packages/core/client/src/acl/Configuration/StrategyActions.tsx +++ b/packages/core/client/src/acl/Configuration/StrategyActions.tsx @@ -55,62 +55,64 @@ export const StrategyActions = connect((props) => { size={'small'} pagination={false} rowKey={'name'} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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) => ( - { - if (enabled) { - delete scopes[action.name]; - } else { - scopes[action.name] = 'all'; - } - onChange(toFieldValue(scopes)); - }} - /> - ), - }, - { - dataIndex: 'scope', - title: t('Data scope'), - render: (scope, action) => - !action.onNewRecord && ( - { + scopes[action.name] = value; + onChange(toFieldValue(scopes)); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let scope = 'all'; let enabled = false; diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index 1c7f80dd47..9dfead7b02 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -167,7 +167,7 @@ export function useCollectValuesToSubmit() { if (parsedValue !== null && parsedValue !== undefined) { assignedValues[key] = transformVariableValue(parsedValue, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); @@ -203,6 +203,12 @@ export function useCollectValuesToSubmit() { ]); } +function interpolateVariables(str: string, scope: Record): string { + return str.replace(/\{\{\s*([a-zA-Z0-9_$-.]+?)\s*\}\}/g, (_, key) => { + return scope[key] !== undefined ? String(scope[key]) : ''; + }); +} + export const useCreateActionProps = () => { const filterByTk = useFilterByTk(); const record = useCollectionRecord(); @@ -219,11 +225,20 @@ export const useCreateActionProps = () => { const collectValues = useCollectValuesToSubmit(); const action = record.isNew ? actionField.componentProps.saveMode || 'create' : 'update'; const filterKeys = actionField.componentProps.filterKeys?.checked || []; + const localVariables = useLocalVariables(); + const variables = useVariables(); return { async onClick() { const { onSuccess, skipValidator, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {}; - const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {}; + const { + manualClose, + redirecting, + redirectTo: rawRedirectTo, + successMessage, + actionAfterSuccess, + } = onSuccess || {}; + if (!skipValidator) { await form.submit(); } @@ -241,6 +256,15 @@ export const useCreateActionProps = () => { : undefined, updateAssociationValues, }); + let redirectTo = rawRedirectTo; + if (rawRedirectTo) { + const { exp, scope: expScope } = await replaceVariables(rawRedirectTo, { + variables, + localVariables: [...localVariables, { name: '$record', ctx: new Proxy(data?.data?.data, {}) }], + }); + redirectTo = interpolateVariables(exp, expScope); + } + if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) { setVisible?.(false); } @@ -338,7 +362,7 @@ export const useAssociationCreateActionProps = () => { if (parsedValue) { assignedValues[key] = transformVariableValue(parsedValue, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); @@ -588,7 +612,13 @@ export const useCustomizeUpdateActionProps = () => { skipValidator, triggerWorkflows, } = actionSchema?.['x-action-settings'] ?? {}; - const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {}; + const { + manualClose, + redirecting, + redirectTo: rawRedirectTo, + successMessage, + actionAfterSuccess, + } = onSuccess || {}; const assignedValues = {}; const waitList = Object.keys(originalAssignedValues).map(async (key) => { const value = originalAssignedValues[key]; @@ -605,7 +635,7 @@ export const useCustomizeUpdateActionProps = () => { if (parsedValue) { assignedValues[key] = transformVariableValue(parsedValue, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); @@ -614,7 +644,7 @@ export const useCustomizeUpdateActionProps = () => { if (skipValidator === false) { await form.submit(); } - await resource.update({ + const result = await resource.update({ filterByTk, values: { ...assignedValues }, // TODO(refactor): should change to inject by plugin @@ -622,6 +652,16 @@ export const useCustomizeUpdateActionProps = () => { ? triggerWorkflows.map((row) => [row.workflowKey, row.context].filter(Boolean).join('!')).join(',') : undefined, }); + + let redirectTo = rawRedirectTo; + if (rawRedirectTo) { + const { exp, scope: expScope } = await replaceVariables(rawRedirectTo, { + variables, + localVariables: [...localVariables, { name: '$record', ctx: new Proxy(result?.data?.data?.[0], {}) }], + }); + redirectTo = interpolateVariables(exp, expScope); + } + if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) { setVisible?.(false); } @@ -708,7 +748,7 @@ export const useCustomizeBulkUpdateActionProps = () => { if (parsedValue) { assignedValues[key] = transformVariableValue(parsedValue, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); @@ -913,7 +953,13 @@ export const useUpdateActionProps = () => { skipValidator, triggerWorkflows, } = actionSchema?.['x-action-settings'] ?? {}; - const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {}; + const { + manualClose, + redirecting, + redirectTo: rawRedirectTo, + successMessage, + actionAfterSuccess, + } = onSuccess || {}; const assignedValues = {}; const waitList = Object.keys(originalAssignedValues).map(async (key) => { const value = originalAssignedValues[key]; @@ -930,7 +976,7 @@ export const useUpdateActionProps = () => { if (parsedValue) { assignedValues[key] = transformVariableValue(parsedValue, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); @@ -952,7 +998,7 @@ export const useUpdateActionProps = () => { actionField.data = field.data || {}; actionField.data.loading = true; try { - await resource.update({ + const result = await resource.update({ filterByTk, values: { ...values, @@ -971,6 +1017,15 @@ export const useUpdateActionProps = () => { if (callBack) { callBack?.(); } + let redirectTo = rawRedirectTo; + if (rawRedirectTo) { + const { exp, scope: expScope } = await replaceVariables(rawRedirectTo, { + variables, + localVariables: [...localVariables, { name: '$record', ctx: new Proxy(result?.data?.data?.[0], {}) }], + }); + redirectTo = interpolateVariables(exp, expScope); + } + if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) { setVisible?.(false); } diff --git a/packages/core/client/src/collection-manager/action-hooks.ts b/packages/core/client/src/collection-manager/action-hooks.ts index cac488e796..422c207fc5 100644 --- a/packages/core/client/src/collection-manager/action-hooks.ts +++ b/packages/core/client/src/collection-manager/action-hooks.ts @@ -157,6 +157,8 @@ export const useCollectionFilterOptions = (collection: any, dataSource?: string) const option = { name: field.name, title: field?.uiSchema?.title || field.name, + label: field?.uiSchema?.title || field.name, + value: field.name, schema: field?.uiSchema, operators: operators?.filter?.((operator) => { diff --git a/packages/core/client/src/locale/it-IT.json b/packages/core/client/src/locale/it-IT.json index 4f5249f667..e033da14c3 100644 --- a/packages/core/client/src/locale/it-IT.json +++ b/packages/core/client/src/locale/it-IT.json @@ -1,847 +1,1084 @@ -{ - "Display <1><0>10<1>20<2>50<3>100 items per page": "Visualizza <1><0>10<1>20<2>50<3>100 articoli per pagina", - "Meet <1><0>All<1>Any conditions in the group": "Soddisfa<1><0>Tutte<1>Qualsiasicondizioni nel gruppo", - "Open in<1><0>Modal<1>Drawer<2>Window": "Apri in<1><0>Modale<1>Cassetto<2>Finestra", - "{{count}} filter items": "{{Count}} filtri elementi", - "{{count}} more items": "{{Count}} altri elementi", - "Total {{count}} items": "{{count}} elementi totali", - "Today": "Oggi", - "Yesterday": "Ieri", - "Tomorrow": "Domani", - "Month": "Mese", - "Week": "Settimana", - "This week": "Questa settimana", - "This month": "Questo mese", - "This year": "Quest'anno", - "Next year": "Anno prossimo", - "Last week": "Settimana scorsa", - "Next week": "Prossima settimana", - "Last month": "Mese scorso", - "Next month": "Mese prossimo", - "Last quarter": "Ultimo trimestre", - "This quarter": "Questo trimestre", - "Next quarter": "Prossimo trimestre", - "Last year": "Anno scorso", - "Last 7 days": "Ultimi 7 giorni", - "Last 30 days": "Ultimi 30 giorni", - "Last 90 days": "Ultimi 90 giorni", - "Next 7 days": "Prossimi 7 giorni", - "Next 30 days": "Prossimi 30 giorni", - "Next 90 days": "Prossimi 90 giorni", - "Work week": "Settimana lavorativa", - "Day": "Giorno", - "Agenda": "Agenda", - "Date": "Data", - "Time": "Tempo", - "Event": "Evento", - "None": "Nessuno", - "Unconnected": "Non collegato", - "System settings": "Impostazioni di sistema", - "System title": "Titolo del sistema", - "Settings": "Impostazioni", - "Logo": "Logo", - "Add menu item": "Aggiungi voce di menu", - "Page": "Pagina", - "Name": "Nome", - "Icon": "Icona", - "Group": "Gruppo", - "Link": "Collegamento", - "Save conditions": "Salva condizioni", - "Edit menu item": "Modifica voce di menu", - "Move to": "Passa a", - "Insert left": "Inserisci a sinistra", - "Insert right": "Inserire a destra", - "Insert inner": "Inserire dentro", - "Delete": "Eliminare", - "Disassociate": "Dissociare", - "Disassociate record": "Dissociare record", - "Are you sure you want to disassociate it?": "Sei sicuro di voler dissociare?", - "UI editor": "Editor UI", - "Collection": "Raccolta", - "Collection selector": "Selettore di raccolta", - "Providing certain collections as options for users, typically used in polymorphic or inheritance scenarios": "Fornire alcune raccolte come opzioni per gli utenti, in genere utilizzati negli scenari polimorfici o ereditari", - "Collections & Fields": "Raccolte e campi", - "All collections": "Tutte le raccolte", - "Add category": "Aggiungi categoria", - "Enable child collections": "Abilita raccolte figlie", - "Allow adding records to the current collection": "Consenti l'aggiunta di record alla raccolta corrente", - "Delete category": "Elimina categoria", - "Edit category": "Modifica categoria", - "Collection category": "Categoria raccolta", - "Collection template": "Modello raccolta", - "Sort": "Ordina", - "Categories": "Categorie", - "Visible": "Visibile", - "Read only": "Solo lettura", - "Easy reading": "Lettura facile", - "Hidden": "Nascosto", - "Hidden(reserved value)": "Nascosto (valore riservato)", - "Not required": "Non richiesto", - "Value": "Valore", - "Disabled": "Disabilitato", - "Enabled": "Abilitato", - "Problematic": "Con problemi", - "Setting": "Impostazioni", - "On": "Acceso", - "Off": "Spento", - "Empty": "Vuoto", - "Linkage rule": "Regola di collegamento", - "Linkage rules": "Regole di collegamento", - "Condition": "Condizione", - "Properties": "Proprietà", - "Add linkage rule": "Aggiungi regola di collegamento", - "Add property": "Aggiungi proprietà", - "Category name": "Nome della categoria", - "Roles & Permissions": "Ruoli e autorizzazioni", - "Edit profile": "Modifica profilo", - "Change password": "Cambia password", - "Old password": "Vecchia password", - "New password": "Nuova password", - "Switch role": "Cambia ruolo", - "Super admin": "Super Admin", - "Language": "Lingua", - "Allow sign up": "Consenti iscrizione", - "Enable SMS authentication": "Abilita autenticazione SMS", - "Sign out": "Disconnessione", - "Cancel": "Annulla", - "Submit": "Invia", - "Close": "Chiudi", - "Set the data scope": "Imposta l'ambito dei dati", - "Set data loading mode": "Imposta modalità di caricamento dei dati", - "Load all data when filter is empty": "Carica tutti i dati quando il filtro è vuoto", - "Do not load data when filter is empty": "Non caricare i dati quando il filtro è vuoto", - "Data loading mode": "Modalità di caricamento dei dati", - "Data blocks": "Blocchi dati", - "Filter blocks": "Blocchi filtro", - "Table": "Tabella", - "Table OID(Inheritance)": "Tabella OID (eredità)", - "Form": "Modulo", - "List": "Elenco", - "Grid Card": "Scheda griglia", - "pixels": "pixel", - "Screen size": "Dimensione dello schermo", - "Display title": "Visualizza titolo", - "Set the count of columns displayed in a row": "Imposta conteggio delle colonne visualizzate in una riga", - "Column": "Colonna", - "Phone device": "Telefono", - "Tablet device": "Tablet", - "Desktop device": "Desktop", - "Large screen device": "Schermo di grandi dimensioni", - "Collapse": "Comprimi", - "Select data source": "Seleziona origine dati", - "Calendar": "Calendario", - "Delete events": "Elimina eventi", - "This event": "Questo evento", - "This and following events": "Questo e seguenti eventi", - "All events": "Tutti gli eventi", - "Delete this event?": "Eliminare questo evento?", - "Delete Event": "Elimina evento", - "Kanban": "Kanban", - "Gantt": "Gantt", - "Create gantt block": "Crea blocco Gantt", - "Progress field": "Campo avanzamento", - "Time scale": "Scala del tempo", - "Hour": "Ora", - "Quarter of day": "Quarto del giorno", - "Half of day": "Metà del giorno", - "Year": "Anno", - "QuarterYear": "Quarto dell' anno", - "Select grouping field": "Seleziona campo di raggruppamento", - "Media": "Media", - "Markdown": "Markdown", - "Wysiwyg": "Wysiwyg", - "Chart blocks": "Blocchi grafici", - "Column chart": "Grafico a colonne", - "Bar chart": "Grafico a barre", - "Line chart": "Grafico a linee", - "Pie chart": "Grafico a torta", - "Area chart": "Grafico ad area", - "Other chart": "Altro grafico", - "Other blocks": "Altri blocchi", - "In configuration": "In configurazione", - "Chart title": "Titolo grafico", - "Chart type": "Tipo grafico", - "Chart config": "Configurazione grafico", - "Templates": "Modelli", - "Select template": "Seleziona modello", - "Action logs": "Registri eventi", - "Create template": "Crea modello", - "Edit markdown": "Modifica Markdown", - "Add block": "Aggiungi blocco", - "Add new": "Aggiungi nuovo", - "Add record": "Aggiungi record", - "Add child": "Aggiungi figlio", - "Collapse all": "Comprimi tutto", - "Expand all": "Espandi tutto", - "Expand/Collapse": "Espandi/Comprimi", - "Default collapse": "Comprimi di default", - "Tree table": "Tabella struttura ad albero", - "Custom field display name": "Nome visualizzato campo personalizzato ", - "Display fields": "Visualizza campi", - "Edit record": "Modifica record", - "Delete menu item": "Elimina voce di menu", - "Add page": "Aggiungi pagina", - "Add group": "Aggiungi gruppo", - "Add link": "Aggiungi link", - "Insert above": "Inserisci sopra", - "Insert below": "Inserisci sotto", - "Save": "Salva", - "Delete block": "Elimina blocco", - "Are you sure you want to delete it?": "Sei sicuro di volerlo eliminare?", - "This is a demo text, **supports Markdown syntax**.": "Questo è un testo demo, ** supporta la sintassi di Markdown **.", - "Filter": "Filtro", - "Connect data blocks": "Collega blocchi di dati", - "Action type": "Tipo di azione", - "Actions": "Azioni", - "Insert": "Inserisci", - "Insert if not exists": "Inserisci se non esiste", - "Insert if not exists, or update": "Inserisci se non esiste o aggiorna", - "Determine whether a record exists by the following fields": "Determina se un record esiste dai seguenti campi", - "Update": "Aggiorna", - "Update record": "Aggiorna record", - "View": "Visualizza", - "View record": "Visualizza record", - "Refresh": "Refresh", - "Data changes": "Modifiche ai dati", - "Field name": "Nome campo", - "Before change": "Prima delle modifiche", - "After change": "Dopo le modifiche", - "Delete record": "Elimina record", - "Delete collection": "Elimina raccolta", - "Create collection": "Crea raccolta", - "Collection display name": "Nome visualizzato raccolta", - "Collection name": "Nome raccolta", - "Inherits": "Eredita", - "Primary key, unique identifier, self growth": "Chiave primaria, identificatore univoco, auto-incremento", - "Store the creation user of each record": "Memorizza l'utente della creazione di ogni record", - "Store the last update user of each record": "Memorizza l'ultimo utente di aggiornamento di ogni record", - "Store the creation time of each record": "Memorizza l'orario di creazione di ogni record", - "Store the last update time of each record": "Memorizza l'ultimo orario di aggiornamento di ogni record", - "More options": "Più opzioni", - "Records can be sorted": "I record possono essere ordinati", - "Calendar collection": "Raccolta calendario", - "General collection": "Raccolta generale", - "Connect to database view": "Connetti alla vista del database", - "Sync from database": "Sincronizza dal database", - "Source collections": "Sorgente raccolte", - "Field source": "Sorgente campo", - "Preview": "Anteprima", - "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "Generato casualmente e può essere modificato. Supporta lettere, numeri e underscore, deve iniziare con una lettera.", - "Edit": "Modifica", - "Edit collection": "Modifica raccolta", - "Configure fields": "Configura campi", - "Configure columns": "Configura colonne", - "Edit field": "Modifica campo", - "Override": "Forza", - "Override field": "Forza campo", - "Configure fields of {{title}}": "Configura campi di {{title}}", - "Association fields filter": "Filtro associazione campi", - "PK & FK fields": "Campi PK e FK", - "Association fields": "Campi associazione", - "Choices fields": "Campi scelte", - "System fields": "Campi di sistema", - "General fields": "Campi generali", - "Inherited fields": "Campi ereditati", - "Parent collection fields": "Campi raccolta padre", - "Basic": "Di base", - "Single line text": "Testo a riga singola", - "Long text": "Testo lungo", - "Phone": "Telefono", - "Email": "E-mail", - "Number": "Numero", - "Integer": "Intero", - "Percent": "Percentuale", - "Password": "Password", - "Advanced type": "Avanzato", - "Choices": "Scelte", - "Checkbox": "Casella di controllo", - "Single select": "Selezione singola", - "Multiple select": "Selezione multipla", - "Radio group": "Gruppo radio", - "Checkbox group": "Gruppo cassella di controllo", - "China region": "Regione cinese", - "Date & Time": "Data e ora", - "Datetime": "DateTime", - "Relation": "Relazione", - "Link to": "Collegamento a", - "Link to description": "Utilizzato per creare relazioni tra raccolte in modo rapido e compatibile con gli scenari più comuni. Adatto per un uso da non sviluppatore. Se presente come campo, è una selezione a discesa utilizzata per selezionare i record dalla raccolta di destinazione. Una volta creato, genererà contemporaneamente i campi associati dell'attuale raccolta nella raccolta di destinazione.", - "Sub-table": "Sotto-tabella", - "Sub-details": "Sotto-dettagli", - "Sub-form(Popover)": "Sotto-modulo (Popover)", - "System info": "Informazioni di sistema", - "Created at": "Creato il", - "Last updated at": "Ultimo aggiornamento il", - "Created by": "Creato da", - "Last updated by": "Ultimo aggiornamento da", - "Add field": "Aggiungi campo", - "Field display name": "Nome visualizzato campo", - "Field type": "Tipo campo", - "Field interface": "Interfaccia campo", - "Date format": "Formato data", - "Year/Month/Day": "Anno/Mese/Giorno", - "Year-Month-Day": "Anno-Mese-Giorno", - "Day/Month/Year": "Giorno/Mese/Anno", - "Show time": "Mostra orario", - "Time format": "Formato tempo", - "12 hour": "12 ore", - "24 hour": "24 ore", - "Relationship type": "Tipo di relazione", - "Inverse relationship type": "Tipo di relazione inversa", - "Source collection": "Raccolta sorgente", - "Source key": "Chiave sorgente", - "Target collection": "Raccolta di destinazione", - "Through collection": "Attraverso la raccolta", - "Target key": "Chiave di destinazione", - "Foreign key": "Chiave esterna", - "One to one": "Uno a uno", - "One to many": "Uno a molti", - "Many to one": "Molti a uno", - "Many to many": "Molti a molti", - "Foreign key 1": "Chiave esterna 1", - "Foreign key 2": "Chiave esterna 2", - "One to one description": "Usato per creare relazioni one-to-one. Ad esempio, un utente ha un profilo.", - "One to many description": "Utilizzato per creare una relazione da uno a molti. Ad esempio, un paese avrà molte città e una città può essere solo in un paese. Se presente come campo, è una sotto-tabella che mostra i record della raccolta associata. Se creato, un campo molti-a-uno viene generato automaticamente nella raccolta associata.", - "Many to one description": "Utilizzato per creare relazioni molti-a-uno. Ad esempio, una città può appartenere a un solo paese e un paese può avere molte città. Se presente come campo, è una selezione a discesa utilizzata per selezionare il record dalla raccolta associata. Una volta creato, un campo da uno a molti viene generato automaticamente nella raccolta associata.", - "Many to many description": "Utilizzato per creare relazioni molti-a-molti. Ad esempio, uno studente avrà molti insegnanti e un insegnante avrà molti studenti. Se presente come campo, è una selezione a discesa utilizzata per selezionare i record dalla raccolta associata.", - "Generated automatically if left blank": "Generato automaticamente se lasciato vuoto", - "Display association fields": "Visualizza campi di associazione", - "Display field title": "Visualizza titolo campo", - "Field component": "Componente campo", - "Allow multiple": "Consenti multipli", - "Quick upload": "Caricamento rapido", - "Select file": "Seleziona file", - "Subtable": "Sotto-tabella", - "Sub-form": "Sotto-modulo", - "Field mode": "Modalità campo", - "Allow add new data": "Consenti aggiunta nuovi dati", - "Record picker": "Record Picker", - "Toggles the subfield mode": "Attiva la modalità Subfield", - "Selector mode": "Modalità selettore", - "Subtable mode": "Modalità sotto-tabella", - "Subform mode": "Modalità sotto-modulo", - "Block title": "Titolo blocco", - "Pattern": "Modello", - "Operator": "Operatore", - "Editable": "Modificabile", - "Readonly": "Solo lettura", - "Easy-reading": "Lettura facile", - "Add filter": "Aggiungi filtro", - "Add filter group": "Aggiungi gruppo di filtri", - "Comparision": "Confronto", - "is": "è", - "is not": "non lo è", - "contains": "contiene", - "does not contain": "non contiene", - "starts with": "inizia con", - "not starts with": "non inizia con", - "ends with": "termina con", - "not ends with": "non termina con", - "is empty": "è vuoto", - "is not empty": "non è vuoto", - "Edit chart": "Modifica grafico", - "Filterable fields": "Campi filtrabili", - "Edit button": "Modifica pulsante", - "Hide": "Nascondi", - "Enable actions": "Abilita azioni", - "Import": "Importa", - "Export": "Esporta", - "Customize": "Personalizza", - "Custom": "Personalizzato", - "Function": "Funzione", - "Popup form": "Modulo Popup", - "Flexible popup": "Popup flessibile", - "Configure actions": "Configura azioni", - "Display order number": "Visualizza numero ordinamento", - "Enable drag and drop sorting": "Abilita l'ordinamento con drag and drop", - "Triggered when the row is clicked": "Attivato quando si fa clic sulla riga", - "Add tab": "Aggiungi scheda", - "Disable tabs": "Disabilita schede", - "Details": "Dettagli", - "Edit form": "Modifica modulo", - "Create form": "Crea modulo", - "Form (Edit)": "Modulo (modifica)", - "Form (Add new)": "Modulo (aggiungi nuovo)", - "Edit tab": "Modifica scheda", - "Relationship blocks": "Blocchi di relazione", - "Select record": "Seleziona Record", - "Display name": "Visualizza nome", - "Select icon": "Seleziona icona", - "Custom column name": "Nome colonna personalizzato", - "Edit description": "Modifica descrizione", - "Required": "Richiesto", - "Unique": "Univoco", - "Primary": "Primario", - "Auto increment": "Incremento automatico", - "Label field": "Campo etichetta", - "Default is the ID field": "L'impostazione predefinita è il campo ID", - "Set default sorting rules": "Imposta regole di ordinamento predefinite", - "Set validation rules": "Imposta regole di convalida", - "Max length": "Lunghezza massima", - "Min length": "Lunghezza minima", - "Maximum": "Massimo", - "Minimum": "Minimo", - "Max length must greater than min length": "La lunghezza massima deve essere maggiore della lunghezza minima", - "Min length must less than max length": "La lunghezza minima deve essere inferiore della lunghezza massima", - "Maximum must greater than minimum": "Il massimo deve essere maggiore del minimo", - "Minimum must less than maximum": "Il minimo deve essere minore del massimo", - "Validation rule": "Regola di convalida", - "Add validation rule": "Aggiungi regola di convalida", - "Format": "Formato", - "Regular expression": "Espressione regolare", - "Error message": "Messaggio di errore", - "Length": "Lunghezza", - "The field value cannot be greater than ": "Il valore del campo non può essere maggiore di", - "The field value cannot be less than ": "Il valore del campo non può essere inferiore a", - "The field value is not an integer number": "Il valore del campo non è un numero intero", - "Set default value": "Imposta valore predefinito", - "Default value": "Valore predefinito", - "is before": "è prima", - "is after": "è dopo", - "is on or after": "a partire dal", - "is on or before": "entro il", - "is between": "è tra", - "Upload": "Upload", - "Select level": "Seleziona livello", - "Province": "Provincia", - "City": "Città", - "Area": "Zona", - "Street": "Strada", - "Village": "Villaggio", - "Must select to the last level": "Deve selezionare all'ultimo livello", - "Move {{title}} to": "Sposta {{title}} a", - "Target position": "Posizione di destinazione", - "After": "Dopo", - "Before": "Prima", - "Add {{type}} before \"{{title}}\"": "Aggiungi {{type}} prima di \"{{title}}\"", - "Add {{type}} after \"{{title}}\"": "Aggiungi {{type}} dopo \"{{title}}\"", - "Add {{type}} in \"{{title}}\"": "Aggiungi {{type}} in \"{{title}}\"", - "Original name": "Nome originale", - "Custom name": "Nome personalizzato", - "Custom Title": "Titolo personalizzato", - "Options": "Opzioni", - "Option value": "Valore opzione", - "Option label": "Etichetta opzione", - "Color": "Colore", - "Background Color": "Colore sfondo", - "Text Align": "Allineamento testo", - "Add option": "Aggiungi opzione", - "Related collection": "Raccolta correlata", - "Allow linking to multiple records": "Consenti ​collegamento a più record", - "Configure calendar": "Configura calendario", - "Title field": "Campo titolo", - "Custom title": "Titolo personalizzato", - "Daily": "Quotidiano", - "Weekly": "Settimanale", - "Monthly": "Mensile", - "Yearly": "Annuale", - "Repeats": "Ripeti", - "Show lunar": "Mostra lunare", - "Start date field": "Campo data di inizio", - "End date field": "Campo data di fine", - "Navigate": "Naviga", - "Title": "Titolo", - "Description": "Descrizione", - "Select view": "Seleziona vista", - "Reset": "Reset", - "Importable fields": "Campi importabili", - "Exportable fields": "Campi esportabili", - "Saved successfully": "Salvataggio riuscito", - "Nickname": "Soprannome", - "Sign in": "Registrazione", - "Sign in via account": "Accedi tramite account", - "Sign in via phone": "Accedi via telefono", - "Create an account": "Crea un account", - "Sign up": "Iscrizione", - "Confirm password": "Conferma password", - "Log in with an existing account": "Accedi con account esistente", - "Signed up successfully. It will jump to the login page.": "Registrazione riuscita. Reindirizzamento alla pagina di accesso.", - "Password mismatch": "Password non corretta", - "Users": "Utenti", - "Verification code": "Codice di verifica", - "Send code": "Invia codice", - "Retry after {{count}} seconds": "Riprova dopo {{count}} secondi", - "Roles": "Ruoli", - "Add role": "Aggiungi ruolo", - "Role name": "Nome ruolo", - "Configure": "Configura", - "Configure permissions": "Configura permessi", - "Edit role": "Modifica ruolo", - "Action permissions": "Permessi su azioni", - "Menu permissions": "Permessi su menu", - "Menu item name": "Nome voce di menu", - "Allow access": "Consenti accesso", - "Action name": "Nome azione", - "Allow action": "Consenti azione", - "Action scope": "Ambito azione", - "Operate on new data": "Operare su nuovi dati", - "Operate on existing data": "Operare su dati esistenti", - "Yes": "Si", - "No": "No", - "Red": "Rosso", - "Magenta": "Magenta", - "Volcano": "Vulcano", - "Orange": "Arancione", - "Gold": "Oro", - "Lime": "Lime", - "Green": "Verde", - "Cyan": "Ciano", - "Blue": "Blu", - "Geek blue": "Geek Blue", - "Purple": "Viola", - "Default": "Predefinito", - "Add card": "Aggiungi scheda", - "edit title": "modifica titolo", - "Turn pages": "Volta pagine", - "Others": "Altri", - "Other records": "Altri record", - "Save as template": "Salva come modello", - "Save as block template": "Salva come modello blocco", - "Block templates": "Modelli blocco", - "Block template": "Modello blocco", - "Convert reference to duplicate": "Converti ​​riferimento a duplicato", - "Template name": "Nome modello", - "Block type": "Tipo blocco", - "No blocks to connect": "Nessun blocco per connettersi", - "Action column": "Colonna azioni", - "Records per page": "Record per pagina", - "(Fields only)": "(Solo campi)", - "Button title": "Titolo pulsante", - "Button icon": "Icona pulsante", - "Submitted successfully": "Invio riuscito", - "Operation succeeded": "L'operazione è riuscita", - "Operation failed": "Operazione non riuscita", - "Open mode": "Modalità aperta", - "Popup size": "Dimensione popup", - "Small": "Piccolo", - "Middle": "Medio", - "Large": "Grande", - "Size": "Misura", - "Oversized": "Oversize", - "Auto": "Auto", - "Object Fit": "Adattato all'oggetto", - "Cover": "Cover", - "Fill": "Riempi", - "Contain": "Contiene", - "Scale Down": "Ridimensiona", - "Menu item title": "Titolo voce di menu", - "Menu item icon": "Icona voce di menu", - "Target": "Destinazione", - "Position": "Posizione", - "Insert before": "Inserire prima", - "Insert after": "Inserire dopo", - "UI Editor": "Editor UI", - "ASC": "Asc", - "DESC": "Desc", - "Add sort field": "Aggiungi campo di ordinamento", - "ID": "ID", - "Identifier for program usage. Support letters, numbers and underscores, must start with an letter.": "Identificatore per l'utilizzo del programma. Supporta lettere, numeri e underscore, deve iniziare con una lettera.", - "Drawer": "Cassetto", - "Dialog": "Dialogo", - "Delete action": "Elimina azione", - "Custom column title": "Titolo colonna personalizzata", - "Column title": "Titolo colonna", - "Original title: ": "Titolo originale: ", - "Delete table column": "Elimina colonna della tabella", - "Skip required validation": "Salta convalida richiesta", - "Form values": "Valori modulo", - "Fields values": "Valori campi", - "The field has been deleted": "Il campo è stato eliminato", - "When submitting the following fields, the saved values are": "Quando si inviano i seguenti campi, i valori salvati sono", - "After successful submission": "Dopo un invio riuscito", - "Then": "Poi", - "Stay on current page": "Resta sulla pagina corrente", - "Redirect to": "Reindirizza a", - "Save action": "Salva azione", - "Exists": "Esiste", - "Add condition": "Aggiungi condizione", - "Add condition group": "Aggiungi gruppo di condizioni", - "exists": "esiste", - "not exists": "non esiste", - "Style": "Stile", - "=": "=", - "≠": "≠", - ">": ">", - "≥": "≥", - "<": "<", - "≤": "≤", - "Role UID": "Ruolo UID", - "Precision": "Precisione", - "Expression": "Espressione", - "Rich Text": "Testo ricco", - "Junction collection": "Raccolta giunzione", - "Leave it blank, unless you need a custom intermediate table": "Lascialo vuoto, a meno che tu non abbia bisogno di una tabella intermedia personalizzata", - "Fields": "Campi", - "Edit field title": "Modifica titolo campo", - "Field title": "Titolo campo", - "Original field title: ": "Titolo campo originale:", - "Edit tooltip": "Modifica suggerimento", - "Delete field": "Elimina campo", - "Select collection": "Seleziona raccolta", - "Blank block": "Blocco vuoto", - "Duplicate template": "Modello duplicato", - "Reference template": "Modello di riferimento", - "Create calendar block": "Crea blocco calendario", - "Create kanban block": "Crea blocco kanban", - "Grouping field": "Campo di raggruppamento", - "Single select and radio fields can be used as the grouping field": "I campi di selezione singoli e radio possono essere utilizzati come campo di raggruppamento", - "Tab name": "Nome della scheda", - "Current record blocks": "Blocchi record attuale", - "Popup message": "Messaggio popup", - "Delete role": "Elimina ruolo", - "Role display name": "Nome visualizzato ruolo", - "Default role": "Ruolo predefinito", - "All collections use general action permissions by default; permission configured individually will override the default one.": "Tutte le raccolte utilizzano i permessi di operazioni generali per impostazione predefinita; I permessi configurati individualmente sovrascriveranno quelli predefiniti.", - "Allows configuration of the whole system, including UI, collections, permissions, etc.": "Consente la configurazione dell'intero sistema, tra cui interfaccia utente, raccolte, permessi, ecc.", - "New menu items are allowed to be accessed by default.": "È possibile accedere a nuove voci di menu per impostazione predefinita.", - "Global permissions": "Permessi globali", - "General permissions": "Permessi generali", - "Global action permissions": "Permessi operazioni globali", - "General action permissions": "Permessi operazioni generali", - "Plugin settings permissions": "Permessi impostazioni plugin", - "Allow to desgin pages": "Consenti progettazione pagine", - "Allow to manage plugins": "Consenti gestione plugin", - "Allow to configure plugins": "Consenti configurazione plugin", - "Allows to configure interface": "Consente di configurare l'interfaccia", - "Allows to install, activate, disable plugins": "Consente di installare, attivare, disabilitare i plugin", - "Allows to configure plugins": "Consente di configurare i plugin", - "Action display name": "Nome visualizzato azione", - "Allow": "Permetti", - "Data scope": "Ambito dei dati", - "Action on new records": "Azione su nuovi record", - "Action on existing records": "Azione su record esistenti", - "All records": "Tutti i record", - "Own records": "Record propri", - "Permission policy": "Policy di autorizzazione", - "Individual": "Individuale", - "General": "Generale", - "Accessible": "Accessibile", - "Configure permission": "Configura permesso", - "Action permission": "Permesso azione", - "Field permission": "Permesso campo", - "Scope name": "Nome ambito", - "Unsaved changes": "Modifiche non salvate", - "Are you sure you don't want to save?": "Sei sicuro di non voler salvare?", - "Dragging": "Trascina", - "Popup": "Popup", - "Trigger workflow": "Trigger workflow", - "Request API": "Richiesta API", - "Assign field values": "Assegna valori del campo", - "Constant value": "Valore costante", - "Dynamic value": "Valore dinamico", - "Current user": "Utente attuale", - "Current role": "Ruolo attuale", - "Current record": "Record attuale", - "Current collection": "Raccolta attuale", - "Other collections": "Altre raccolte", - "Current popup record": "Record popup attuale", - "Parent popup record": "Record popup padre", - "Associated records": "Record associati", - "Parent record": "Record padre", - "Current time": "Ora attuale", - "System variables": "Variabili di sistema", - "Date variables": "Variabili della data", - "Message popup close method": "Metodo di chiusura popup di messaggio", - "Automatic close": "Chiudi automaticamente", - "Manually close": "Chiudi manualmente", - "After successful update": "Dopo un aggiornamento riuscito", - "Save record": "Salva record", - "Updated successfully": "Aggiornamento riuscito", - "After successful save": "Dopo un salvataggio riuscito", - "After clicking the custom button, the following field values will be assigned according to the following form.": "Dopo aver fatto clic sul pulsante personalizza, i seguenti valori verranno assegnati in base al seguente modulo.", - "After clicking the custom button, the following fields of the current record will be saved according to the following form.": "Dopo aver fatto clic sul pulsante personalizza, i seguenti campi del record corrente verranno salvati in base al seguente modulo.", - "Button background color": "Colore sfondo del pulsante", - "Highlight": "Evidenziato", - "Danger red": "Rosso pericolo", - "Custom request": "Richiesta personalizzata", - "Request settings": "Impostazioni richiesta", - "Request URL": "URL richiesta", - "Request method": "Metodo richiesta", - "Request query parameters": "Parametri richiesta query", - "Request headers": "Intestazioni richiesta", - "Request body": "Corpo richiesta", - "Request success": "Successo richiesta", - "Invalid JSON format": "Formato JSON non valido", - "After successful request": "Dopo una richiesta riuscita", - "Add exportable field": "Aggiungi campo esportabile", - "Audit logs": "Registri audit", - "Record ID": "ID record", - "User": "Utente", - "Field": "Campo", - "Select": "Seleziona", - "Select field": "Seleziona campo", - "Field value changes": "Modifiche valore del campo", - "One to one (has one)": "Uno a uno (ne ha uno)", - "One to one (belongs to)": "Uno a uno (appartiene a)", - "Use the same time zone (GMT) for all users": "Usa lo stesso fuso orario (GMT) per tutti gli utenti", - "Province/city/area name": "Nome provincia/città/area", - "Enabled languages": "Lingue abilitate", - "View all plugins": "Visualizza tutti i plugin", - "Print": "Stampa", - "Done": "Fatto", - "Sign up successfully, and automatically jump to the sign in page": "Iscriviti correttamente e reindirizza automaticamente alla pagina di accesso", - "File manager": "File Manager", - "ACL": "ACL", - "Collection manager": "Responsabile della raccolta", - "Plugin manager": "Plugin Manager", - "Local": "Locale", - "Built-in": "Incorporato", - "Marketplace": "Marketplace", - "Add plugin": "Aggiungi plugin", - "Plugin source": "Sorgente plugin", - "Upgrade": "Aggiornamento", - "Plugin dependencies check failed": "Controllo delle dipendenze del plugin non riuscito", - "More details": "Maggiori dettagli", - "Upload new version": "Carica nuova versione", - "Version": "Versione", - "Npm package": "Pacchetto Npm", - "Npm package name": "Nome pacchetto Npm", - "Upload plugin": "Carica plugin", - "Official plugin": "Plugin ufficiale", - "Add type": "Aggiungi tipo", - "Changelog": "Changelog", - "Dependencies check": "Controllo delle dipendenze", - "Update plugin": "Aggiorna plugin", - "Installing": "Installazione", - "The deletion was successful.": "Cancellazione riuscita.", - "Plugin Zip File": "File zip plugin", - "Compressed file url": "URL file compresso", - "Last updated": "Ultimo aggiornamento", - "PackageName": "Nome pacchetto", - "DisplayName": "Nome da visualizzare", - "Readme": "Readme", - "Dependencies compatibility check": "Controllo compatibilità delle dipendenze", - "Plugin dependencies check failed, you should change the dependent version to meet the version requirements.": "Controllo delle dipendenze del plugin non riuscito, è necessario modificare la versione dipendente per soddisfare i requisiti della versione.", - "Version range": "Range versione", - "Plugin's version": "Versione plugin", - "Result": "Risultato", - "No CHANGELOG.md file": "Nessun file Changelog.md", - "No README.md file": "Nessun file readme.md", - "Homepage": "Homepage", - "Drag and drop the file here or click to upload, file size should not exceed 30M": "Trascina e rilascia il file qui o fai clic per caricare, la dimensione del file non deve superare i 30M", - "Dependencies check failed, can't enable.": "Il controllo delle dipendenze non è riuscito, impossibile abilitare.", - "Plugin starting...": "Avvio plugin...", - "Plugin stopping...": "Interruzione plugin ...", - "Are you sure to delete this plugin?": "Sei sicuro di eliminare questo plugin?", - "Are you sure to disable this plugin?": "Sei sicuro di disabilitare questo plugin?", - "re-download file": "ri-scarica file", - "Not enabled": "Non abilitato", - "Search plugin": "Ricerca plugin", - "Author": "Autore", - "Plugin loading failed. Please check the server logs.": "Il caricamento del plugin non è riuscito. Si prega di controllare i registri del server.", - "Coming soon...": "Prossimamente...", - "All plugin settings": "Tutte le impostazioni del plugin", - "Bookmark": "Segnalibro", - "Manage all settings": "Gestisci tutte le impostazioni", - "Create inverse field in the target collection": "Crea campo inverso nella raccolta di destinazione", - "Inverse field name": "Nome campo inverso", - "Inverse field display name": "Nome visualizzato campo inverso", - "Bulk update": "Aggiornamento di massa", - "After successful bulk update": "Dopo un aggiornamento di massa riuscito", - "Bulk edit": "Modifica di massa", - "Data will be updated": "I dati verranno aggiornati", - "Selected": "Selezionato", - "All": "Tutto", - "Update selected data?": "Aggiornare i dati selezionati?", - "Update all data?": "Aggiornare tutti i dati?", - "Remains the same": "Rimane lo stesso", - "Changed to": "Cambiato in", - "Clear": "Cancella", - "Add attach": "Aggiungi allegato", - "Please select the records to be updated": "Si prega di selezionare i record da aggiornare", - "Selector": "Selettore", - "Inner": "Interno", - "Search and select collection": "Cerca e seleziona la raccolta", - "Please fill in the iframe URL": "Si prega di compilare l'URL iFrame", - "Fix block": "Fissa blocco", - "Plugin name": "Nome plugin", - "Plugin tab name": "Nome scheda plugin", - "Column width": "Larghezza colonna", - "Sortable": "Ordinabile", - "Enable link": "Abilita link", - "This is likely a NocoBase internals bug. Please open an issue at <1>here": "Questo sembra un bug interno di NocoBase. Si prega di aprire un ticket <1>qui", - "Render Failed": "Rendering non riuscito", - "App error": "Errore app", - "Feedback": "Feedback", - "Try again": "Riprova", - "Download logs": "Download registri", - "Data template": "Modello dati", - "Duplicate": "Duplica", - "Duplicating": "Duplicazione", - "Duplicate mode": "Modalità duplicazione", - "Quick duplicate": "Duplicazione veloce", - "Duplicate and continue": "Duplica e continua", - "Please configure the duplicate fields": "Si prega di configurare i campi duplicati", - "Add": "Aggiungi", - "Add new mode": "Modalità aggiungi nuovo", - "Quick add": "Aggiunta rapida", - "Modal add": "Aggiunta modale", - "Save mode": "Modalità salvataggio", - "First or create": "Prima o crea", - "Update or create": "Aggiorna o crea", - "Find by the following fields": "Trova dai seguenti campi", - "Create": "Crea", - "Current form": "Modulo corrente", - "Current object": "Oggetto corrente", - "Linkage with form fields": "Collegamento con i campi del modulo", - "Allow add new, update and delete actions": "Consenti azioni aggiungi nuovo, aggiorna ed elimina", - "Date display format": "Formato di visualizzazione della data", - "Table selected records": "Tabella record selezionati", - "Tag": "Etichetta", - "Tag color field": "Campo colore etichetta", - "Sync successfully": "Sincronizzazione riuscita", - "Sync from form fields": "Sincronizzazione dai campi del modulo", - "Select all": "Seleziona tutto", - "Restart": "Ricomincia", - "Restart application": "Riavvia applicazione", - "Cascade Select": "Seleziona in cascata", - "Execute": "Esegui", - "Please use a valid SELECT or WITH AS statement": "Si prega di utilizzare un' istruzione SELECT o WITH AS valida", - "Please confirm the SQL statement first": "Si prega di confermare prima l'istruzione SQL", - "Automatically drop objects that depend on the collection (such as views), and in turn all objects that depend on those objects": "Elimina automaticamente gli oggetti che dipendono dalla raccolta (come le viste) e, a loro volta, tutti gli oggetti che dipendono da tali oggetti", - "Sign in with another account": "Accedi con un altro account", - "Return to the main application": "Torna alla applicazione principale", - "loading": "caricamento", - "name is required": "nome richiesto", - "data source": "sorgente dati", - "Data source": "Sorgente dati", - "DataSource": "Sorgente Dati", - "The {{type}} \"{{name}}\" may have been deleted. Please remove this {{blockType}}.": "Il {{type}} \"{{name}}\" potrebbe essere stato eliminato. Si prega di rimuovere {{blockType}}.", - "Preset fields": "Campi preimpostati", - "Home page": "Home page", - "Handbook": "Manuale", - "License": "Licenza", - "Generic properties": "Proprietà generiche", - "Specific properties": "Proprietà specifiche", - "Used for drag and drop sorting scenarios, supporting grouping sorting": "Utilizzato per scenari con drag and drop, supporta ordinamento raggruppato", - "Grouped sorting": "Ordinamento raggruppato", - "When a field is selected for grouping, it will be grouped first before sorting.": "Quando viene selezionato un campo per il raggruppamento, verrà raggruppato prima dell'ordinamento.", - "Departments": "Dipartimenti", - "Main department": "Dipartimento principale", - "Department name": "Nome del dipartimento", - "Superior department": "Dipartimento superiore", - "Owners": "Proprietari", - "Plugin settings": "Impostazioni plugin", - "Menu": "Menu", - "Drag and drop sorting field": "Campi ordinamento drag and drop", - "This variable has been deprecated and can be replaced with \"Current form\"": "Questa variabile è stata deprecata e può essere sostituita con \"Current form\"", - "The value of this variable is derived from the query string of the page URL. This variable can only be used normally when the page has a query string.": "Il valore di questa variabile deriva dalla stringa di ricerca nell'URL della pagina. Questa variabile può essere utilizzata normalmente solo quando la pagina ha una stringa di ricerca.", - "URL search params": "Parametri di ricerca URL", - "Expand All": "Espandi tutto", - "Search": "Ricerca", - "Clear default value": "Cancella valore predefinito", - "Open in new window": "Apri in una nuova finestra", - "Sorry, the page you visited does not exist.": "Spiacente, la pagina che hai visitato non esiste.", - "is none of": "non è nessuno di", - "is any of": "è uno di", - "Plugin dependency version mismatch": "Mancata corrispondenza della versione della dipendenza del plugin", - "The current dependency version of the plugin does not match the version of the application and may not work properly. Are you sure you want to continue enabling the plugin?": "L'attuale versione della dipendenza del plugin non corrisponde alla versione dell'applicazione e potrebbe non funzionare correttamente. Sei sicuro di voler continuare a abilitare il plugin?", - "Allow multiple selection": "Consenti selezione multipla", - "Parent object": "Oggetto padre", - "Skip getting the total number of table records during paging to speed up loading. It is recommended to enable this option for data tables with a large amount of data": "Ometti calcolo del numero totale di record della tabella durante l'impaginazione per accelerare il caricamento. Si consiglia di abilitare questa opzione per tabelle con grandi quantità di dati", - "Enable secondary confirmation": "Abilita conferma secondaria", - "Notification": "Notifica", - "Ellipsis overflow content": "Contenuto Ellipsis overflow", - "Hide column": "Nascondi colonna", - "In configuration mode, the entire column becomes transparent. In non-configuration mode, the entire column will be hidden. Even if the entire column is hidden, its configured default values and other settings will still take effect.": "In modalità di configurazione, l'intera colonna diventa trasparente. In modalità non di configurazione, l'intera colonna verrà nascosta. Anche se l'intera colonna è nascosta, i suoi valori predefiniti configurati e le altre impostazioni avranno comunque effetto.", - "The following old template features have been deprecated and will be removed in next version.": "Le seguenti funzionalità dei modelli vecchi sono state deprecate e saranno rimosse nella prossima versione." -} +{ + "Display <1><0>10<1>20<2>50<3>100 items per page": "Visualizza <1><0>10<1>20<2>50<3>100 articoli per pagina", + "Meet <1><0>All<1>Any conditions in the group": "Soddisfa<1><0>Tutte<1>Qualsiasicondizioni nel gruppo", + "Open in<1><0>Modal<1>Drawer<2>Window": "Apri in<1><0>Modale<1>Cassetto<2>Finestra", + "{{count}} filter items": "{{Count}} filtri elementi", + "{{count}} more items": "{{Count}} altri elementi", + "Total {{count}} items": "{{count}} elementi totali", + "Today": "Oggi", + "Yesterday": "Ieri", + "Tomorrow": "Domani", + "Month": "Mese", + "Week": "Settimana", + "This week": "Questa settimana", + "This month": "Questo mese", + "This year": "Quest'anno", + "Next year": "Anno prossimo", + "Last week": "Settimana scorsa", + "Next week": "Prossima settimana", + "Last month": "Mese scorso", + "Next month": "Mese prossimo", + "Last quarter": "Ultimo trimestre", + "This quarter": "Questo trimestre", + "Next quarter": "Prossimo trimestre", + "Last year": "Anno scorso", + "Last 7 days": "Ultimi 7 giorni", + "Last 30 days": "Ultimi 30 giorni", + "Last 90 days": "Ultimi 90 giorni", + "Next 7 days": "Prossimi 7 giorni", + "Next 30 days": "Prossimi 30 giorni", + "Next 90 days": "Prossimi 90 giorni", + "Work week": "Settimana lavorativa", + "Day": "Giorno", + "Agenda": "Agenda", + "Date": "Data", + "Time": "Tempo", + "Event": "Evento", + "None": "Nessuno", + "Unconnected": "Non collegato", + "System settings": "Impostazioni di sistema", + "System title": "Titolo del sistema", + "Settings": "Impostazioni", + "Logo": "Logo", + "Add menu item": "Aggiungi voce di menu", + "Page": "Pagina", + "Name": "Nome", + "Icon": "Icona", + "Group": "Gruppo", + "Link": "Collegamento", + "Save conditions": "Salva condizioni", + "Edit menu item": "Modifica voce di menu", + "Move to": "Passa a", + "Insert left": "Inserisci a sinistra", + "Insert right": "Inserire a destra", + "Insert inner": "Inserire dentro", + "Delete": "Eliminare", + "Disassociate": "Dissociare", + "Disassociate record": "Dissociare record", + "Are you sure you want to disassociate it?": "Sei sicuro di voler dissociare?", + "UI editor": "Editor UI", + "Collection": "Raccolta", + "Collection selector": "Selettore di raccolta", + "Providing certain collections as options for users, typically used in polymorphic or inheritance scenarios": "Fornire alcune raccolte come opzioni per gli utenti, in genere utilizzati negli scenari polimorfici o ereditari", + "Collections & Fields": "Raccolte e campi", + "All collections": "Tutte le raccolte", + "Add category": "Aggiungi categoria", + "Enable child collections": "Abilita raccolte figlie", + "Allow adding records to the current collection": "Consenti l'aggiunta di record alla raccolta corrente", + "Delete category": "Elimina categoria", + "Edit category": "Modifica categoria", + "Collection category": "Categoria raccolta", + "Collection template": "Modello raccolta", + "Sort": "Ordina", + "Categories": "Categorie", + "Visible": "Visibile", + "Read only": "Solo lettura", + "Easy reading": "Lettura facile", + "Hidden": "Nascosto", + "Hidden(reserved value)": "Nascosto (valore riservato)", + "Not required": "Non richiesto", + "Value": "Valore", + "Disabled": "Disabilitato", + "Enabled": "Abilitato", + "Problematic": "Con problemi", + "Setting": "Impostazioni", + "On": "Acceso", + "Off": "Spento", + "Empty": "Vuoto", + "Linkage rule": "Regola di collegamento", + "Linkage rules": "Regole di collegamento", + "Condition": "Condizione", + "Properties": "Proprietà", + "Add linkage rule": "Aggiungi regola di collegamento", + "Add property": "Aggiungi proprietà", + "Category name": "Nome della categoria", + "Roles & Permissions": "Ruoli e autorizzazioni", + "Edit profile": "Modifica profilo", + "Change password": "Cambia password", + "Old password": "Vecchia password", + "New password": "Nuova password", + "Switch role": "Cambia ruolo", + "Super admin": "Super Admin", + "Language": "Lingua", + "Allow sign up": "Consenti iscrizione", + "Enable SMS authentication": "Abilita autenticazione SMS", + "Sign out": "Disconnessione", + "Cancel": "Annulla", + "Submit": "Invia", + "Close": "Chiudi", + "Set the data scope": "Imposta l'ambito dei dati", + "Set data loading mode": "Imposta modalità di caricamento dei dati", + "Load all data when filter is empty": "Carica tutti i dati quando il filtro è vuoto", + "Do not load data when filter is empty": "Non caricare i dati quando il filtro è vuoto", + "Data loading mode": "Modalità di caricamento dei dati", + "Data blocks": "Blocchi dati", + "Filter blocks": "Blocchi filtro", + "Table": "Tabella", + "Table OID(Inheritance)": "Tabella OID (eredità)", + "Form": "Modulo", + "List": "Elenco", + "Grid Card": "Scheda griglia", + "pixels": "pixel", + "Screen size": "Dimensione dello schermo", + "Display title": "Visualizza titolo", + "Set the count of columns displayed in a row": "Imposta conteggio delle colonne visualizzate in una riga", + "Column": "Colonna", + "Phone device": "Telefono", + "Tablet device": "Tablet", + "Desktop device": "Desktop", + "Large screen device": "Schermo di grandi dimensioni", + "Collapse": "Comprimi", + "Select data source": "Seleziona origine dati", + "Calendar": "Calendario", + "Delete events": "Elimina eventi", + "This event": "Questo evento", + "This and following events": "Questo e seguenti eventi", + "All events": "Tutti gli eventi", + "Delete this event?": "Eliminare questo evento?", + "Delete Event": "Elimina evento", + "Kanban": "Kanban", + "Gantt": "Gantt", + "Create gantt block": "Crea blocco Gantt", + "Progress field": "Campo avanzamento", + "Time scale": "Scala del tempo", + "Hour": "Ora", + "Quarter of day": "Quarto del giorno", + "Half of day": "Metà del giorno", + "Year": "Anno", + "QuarterYear": "Quarto dell' anno", + "Select grouping field": "Seleziona campo di raggruppamento", + "Media": "Media", + "Markdown": "Markdown", + "Wysiwyg": "Wysiwyg", + "Chart blocks": "Blocchi grafici", + "Column chart": "Grafico a colonne", + "Bar chart": "Grafico a barre", + "Line chart": "Grafico a linee", + "Pie chart": "Grafico a torta", + "Area chart": "Grafico ad area", + "Other chart": "Altro grafico", + "Other blocks": "Altri blocchi", + "In configuration": "In configurazione", + "Chart title": "Titolo grafico", + "Chart type": "Tipo grafico", + "Chart config": "Configurazione grafico", + "Templates": "Modelli", + "Select template": "Seleziona modello", + "Action logs": "Registri eventi", + "Create template": "Crea modello", + "Edit markdown": "Modifica Markdown", + "Add block": "Aggiungi blocco", + "Add new": "Aggiungi nuovo", + "Add record": "Aggiungi record", + "Add child": "Aggiungi figlio", + "Collapse all": "Comprimi tutto", + "Expand all": "Espandi tutto", + "Expand/Collapse": "Espandi/Comprimi", + "Default collapse": "Comprimi di default", + "Tree table": "Tabella struttura ad albero", + "Custom field display name": "Nome visualizzato campo personalizzato ", + "Display fields": "Visualizza campi", + "Edit record": "Modifica record", + "Delete menu item": "Elimina voce di menu", + "Add page": "Aggiungi pagina", + "Add group": "Aggiungi gruppo", + "Add link": "Aggiungi link", + "Insert above": "Inserisci sopra", + "Insert below": "Inserisci sotto", + "Save": "Salva", + "Delete block": "Elimina blocco", + "Are you sure you want to delete it?": "Sei sicuro di volerlo eliminare?", + "This is a demo text, **supports Markdown syntax**.": "Questo è un testo demo, ** supporta la sintassi di Markdown **.", + "Filter": "Filtro", + "Connect data blocks": "Collega blocchi di dati", + "Action type": "Tipo di azione", + "Actions": "Azioni", + "Insert": "Inserisci", + "Insert if not exists": "Inserisci se non esiste", + "Insert if not exists, or update": "Inserisci se non esiste o aggiorna", + "Determine whether a record exists by the following fields": "Determina se un record esiste dai seguenti campi", + "Update": "Aggiorna", + "Update record": "Aggiorna record", + "View": "Visualizza", + "View record": "Visualizza record", + "Refresh": "Refresh", + "Data changes": "Modifiche ai dati", + "Field name": "Nome campo", + "Before change": "Prima delle modifiche", + "After change": "Dopo le modifiche", + "Delete record": "Elimina record", + "Delete collection": "Elimina raccolta", + "Create collection": "Crea raccolta", + "Collection display name": "Nome visualizzato raccolta", + "Collection name": "Nome raccolta", + "Inherits": "Eredita", + "Primary key, unique identifier, self growth": "Chiave primaria, identificatore univoco, auto-incremento", + "Store the creation user of each record": "Memorizza l'utente della creazione di ogni record", + "Store the last update user of each record": "Memorizza l'ultimo utente di aggiornamento di ogni record", + "Store the creation time of each record": "Memorizza l'orario di creazione di ogni record", + "Store the last update time of each record": "Memorizza l'ultimo orario di aggiornamento di ogni record", + "More options": "Più opzioni", + "Records can be sorted": "I record possono essere ordinati", + "Calendar collection": "Raccolta calendario", + "General collection": "Raccolta generale", + "Connect to database view": "Connetti alla vista del database", + "Sync from database": "Sincronizza dal database", + "Source collections": "Sorgente raccolte", + "Field source": "Sorgente campo", + "Preview": "Anteprima", + "Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.": "Generato casualmente e può essere modificato. Supporta lettere, numeri e underscore, deve iniziare con una lettera.", + "Edit": "Modifica", + "Edit collection": "Modifica raccolta", + "Configure fields": "Configura campi", + "Configure columns": "Configura colonne", + "Edit field": "Modifica campo", + "Override": "Forza", + "Override field": "Forza campo", + "Configure fields of {{title}}": "Configura campi di {{title}}", + "Association fields filter": "Filtro associazione campi", + "PK & FK fields": "Campi PK e FK", + "Association fields": "Campi associazione", + "Choices fields": "Campi scelte", + "System fields": "Campi di sistema", + "General fields": "Campi generali", + "Inherited fields": "Campi ereditati", + "Parent collection fields": "Campi raccolta padre", + "Basic": "Di base", + "Single line text": "Testo a riga singola", + "Long text": "Testo lungo", + "Phone": "Telefono", + "Email": "E-mail", + "Number": "Numero", + "Integer": "Intero", + "Percent": "Percentuale", + "Password": "Password", + "Advanced type": "Avanzato", + "Choices": "Scelte", + "Checkbox": "Casella di controllo", + "Single select": "Selezione singola", + "Multiple select": "Selezione multipla", + "Radio group": "Gruppo radio", + "Checkbox group": "Gruppo cassella di controllo", + "China region": "Regione cinese", + "Date & Time": "Data e ora", + "Datetime": "DateTime", + "Relation": "Relazione", + "Link to": "Collegamento a", + "Link to description": "Utilizzato per creare relazioni tra raccolte in modo rapido e compatibile con gli scenari più comuni. Adatto per un uso da non sviluppatore. Se presente come campo, è una selezione a discesa utilizzata per selezionare i record dalla raccolta di destinazione. Una volta creato, genererà contemporaneamente i campi associati dell'attuale raccolta nella raccolta di destinazione.", + "Sub-table": "Sotto-tabella", + "Sub-details": "Sotto-dettagli", + "Sub-form(Popover)": "Sotto-modulo (Popover)", + "System info": "Informazioni di sistema", + "Created at": "Creato il", + "Last updated at": "Ultimo aggiornamento il", + "Created by": "Creato da", + "Last updated by": "Ultimo aggiornamento da", + "Add field": "Aggiungi campo", + "Field display name": "Nome visualizzato campo", + "Field type": "Tipo campo", + "Field interface": "Interfaccia campo", + "Date format": "Formato data", + "Year/Month/Day": "Anno/Mese/Giorno", + "Year-Month-Day": "Anno-Mese-Giorno", + "Day/Month/Year": "Giorno/Mese/Anno", + "Show time": "Mostra orario", + "Time format": "Formato tempo", + "12 hour": "12 ore", + "24 hour": "24 ore", + "Relationship type": "Tipo di relazione", + "Inverse relationship type": "Tipo di relazione inversa", + "Source collection": "Raccolta sorgente", + "Source key": "Chiave sorgente", + "Target collection": "Raccolta di destinazione", + "Through collection": "Attraverso la raccolta", + "Target key": "Chiave di destinazione", + "Foreign key": "Chiave esterna", + "One to one": "Uno a uno", + "One to many": "Uno a molti", + "Many to one": "Molti a uno", + "Many to many": "Molti a molti", + "Foreign key 1": "Chiave esterna 1", + "Foreign key 2": "Chiave esterna 2", + "One to one description": "Usato per creare relazioni one-to-one. Ad esempio, un utente ha un profilo.", + "One to many description": "Utilizzato per creare una relazione da uno a molti. Ad esempio, un paese avrà molte città e una città può essere solo in un paese. Se presente come campo, è una sotto-tabella che mostra i record della raccolta associata. Se creato, un campo molti-a-uno viene generato automaticamente nella raccolta associata.", + "Many to one description": "Utilizzato per creare relazioni molti-a-uno. Ad esempio, una città può appartenere a un solo paese e un paese può avere molte città. Se presente come campo, è una selezione a discesa utilizzata per selezionare il record dalla raccolta associata. Una volta creato, un campo da uno a molti viene generato automaticamente nella raccolta associata.", + "Many to many description": "Utilizzato per creare relazioni molti-a-molti. Ad esempio, uno studente avrà molti insegnanti e un insegnante avrà molti studenti. Se presente come campo, è una selezione a discesa utilizzata per selezionare i record dalla raccolta associata.", + "Generated automatically if left blank": "Generato automaticamente se lasciato vuoto", + "Display association fields": "Visualizza campi di associazione", + "Display field title": "Visualizza titolo campo", + "Field component": "Componente campo", + "Allow multiple": "Consenti multipli", + "Quick upload": "Caricamento rapido", + "Select file": "Seleziona file", + "Subtable": "Sotto-tabella", + "Sub-form": "Sotto-modulo", + "Field mode": "Modalità campo", + "Allow add new data": "Consenti aggiunta nuovi dati", + "Record picker": "Record Picker", + "Toggles the subfield mode": "Attiva la modalità Subfield", + "Selector mode": "Modalità selettore", + "Subtable mode": "Modalità sotto-tabella", + "Subform mode": "Modalità sotto-modulo", + "Block title": "Titolo blocco", + "Pattern": "Modello", + "Operator": "Operatore", + "Editable": "Modificabile", + "Readonly": "Solo lettura", + "Easy-reading": "Lettura facile", + "Add filter": "Aggiungi filtro", + "Add filter group": "Aggiungi gruppo di filtri", + "Comparision": "Confronto", + "is": "è", + "is not": "non lo è", + "contains": "contiene", + "does not contain": "non contiene", + "starts with": "inizia con", + "not starts with": "non inizia con", + "ends with": "termina con", + "not ends with": "non termina con", + "is empty": "è vuoto", + "is not empty": "non è vuoto", + "Edit chart": "Modifica grafico", + "Filterable fields": "Campi filtrabili", + "Edit button": "Modifica pulsante", + "Hide": "Nascondi", + "Enable actions": "Abilita azioni", + "Import": "Importa", + "Export": "Esporta", + "Customize": "Personalizza", + "Custom": "Personalizzato", + "Function": "Funzione", + "Popup form": "Modulo Popup", + "Flexible popup": "Popup flessibile", + "Configure actions": "Configura azioni", + "Display order number": "Visualizza numero ordinamento", + "Enable drag and drop sorting": "Abilita l'ordinamento con drag and drop", + "Triggered when the row is clicked": "Attivato quando si fa clic sulla riga", + "Add tab": "Aggiungi scheda", + "Disable tabs": "Disabilita schede", + "Details": "Dettagli", + "Edit form": "Modifica modulo", + "Create form": "Crea modulo", + "Form (Edit)": "Modulo (modifica)", + "Form (Add new)": "Modulo (aggiungi nuovo)", + "Edit tab": "Modifica scheda", + "Relationship blocks": "Blocchi di relazione", + "Select record": "Seleziona Record", + "Display name": "Visualizza nome", + "Select icon": "Seleziona icona", + "Custom column name": "Nome colonna personalizzato", + "Edit description": "Modifica descrizione", + "Required": "Richiesto", + "Unique": "Univoco", + "Primary": "Primario", + "Auto increment": "Incremento automatico", + "Label field": "Campo etichetta", + "Default is the ID field": "L'impostazione predefinita è il campo ID", + "Set default sorting rules": "Imposta regole di ordinamento predefinite", + "Set validation rules": "Imposta regole di convalida", + "Max length": "Lunghezza massima", + "Min length": "Lunghezza minima", + "Maximum": "Massimo", + "Minimum": "Minimo", + "Max length must greater than min length": "La lunghezza massima deve essere maggiore della lunghezza minima", + "Min length must less than max length": "La lunghezza minima deve essere inferiore della lunghezza massima", + "Maximum must greater than minimum": "Il massimo deve essere maggiore del minimo", + "Minimum must less than maximum": "Il minimo deve essere minore del massimo", + "Validation rule": "Regola di convalida", + "Add validation rule": "Aggiungi regola di convalida", + "Format": "Formato", + "Regular expression": "Espressione regolare", + "Error message": "Messaggio di errore", + "Length": "Lunghezza", + "The field value cannot be greater than ": "Il valore del campo non può essere maggiore di", + "The field value cannot be less than ": "Il valore del campo non può essere inferiore a", + "The field value is not an integer number": "Il valore del campo non è un numero intero", + "Set default value": "Imposta valore predefinito", + "Default value": "Valore predefinito", + "is before": "è prima", + "is after": "è dopo", + "is on or after": "a partire dal", + "is on or before": "entro il", + "is between": "è tra", + "Upload": "Upload", + "Select level": "Seleziona livello", + "Province": "Provincia", + "City": "Città", + "Area": "Zona", + "Street": "Strada", + "Village": "Villaggio", + "Must select to the last level": "Deve selezionare all'ultimo livello", + "Move {{title}} to": "Sposta {{title}} a", + "Target position": "Posizione di destinazione", + "After": "Dopo", + "Before": "Prima", + "Add {{type}} before \"{{title}}\"": "Aggiungi {{type}} prima di \"{{title}}\"", + "Add {{type}} after \"{{title}}\"": "Aggiungi {{type}} dopo \"{{title}}\"", + "Add {{type}} in \"{{title}}\"": "Aggiungi {{type}} in \"{{title}}\"", + "Original name": "Nome originale", + "Custom name": "Nome personalizzato", + "Custom Title": "Titolo personalizzato", + "Options": "Opzioni", + "Option value": "Valore opzione", + "Option label": "Etichetta opzione", + "Color": "Colore", + "Background Color": "Colore sfondo", + "Text Align": "Allineamento testo", + "Add option": "Aggiungi opzione", + "Related collection": "Raccolta correlata", + "Allow linking to multiple records": "Consenti ​collegamento a più record", + "Configure calendar": "Configura calendario", + "Title field": "Campo titolo", + "Custom title": "Titolo personalizzato", + "Daily": "Quotidiano", + "Weekly": "Settimanale", + "Monthly": "Mensile", + "Yearly": "Annuale", + "Repeats": "Ripeti", + "Show lunar": "Mostra lunare", + "Start date field": "Campo data di inizio", + "End date field": "Campo data di fine", + "Navigate": "Naviga", + "Title": "Titolo", + "Description": "Descrizione", + "Select view": "Seleziona vista", + "Reset": "Reset", + "Importable fields": "Campi importabili", + "Exportable fields": "Campi esportabili", + "Saved successfully": "Salvataggio riuscito", + "Nickname": "Soprannome", + "Sign in": "Registrazione", + "Sign in via account": "Accedi tramite account", + "Sign in via phone": "Accedi via telefono", + "Create an account": "Crea un account", + "Sign up": "Iscrizione", + "Confirm password": "Conferma password", + "Log in with an existing account": "Accedi con account esistente", + "Signed up successfully. It will jump to the login page.": "Registrazione riuscita. Reindirizzamento alla pagina di accesso.", + "Password mismatch": "Password non corretta", + "Users": "Utenti", + "Verification code": "Codice di verifica", + "Send code": "Invia codice", + "Retry after {{count}} seconds": "Riprova dopo {{count}} secondi", + "Roles": "Ruoli", + "Add role": "Aggiungi ruolo", + "Role name": "Nome ruolo", + "Configure": "Configura", + "Configure permissions": "Configura permessi", + "Edit role": "Modifica ruolo", + "Action permissions": "Permessi su azioni", + "Menu permissions": "Permessi su menu", + "Menu item name": "Nome voce di menu", + "Allow access": "Consenti accesso", + "Action name": "Nome azione", + "Allow action": "Consenti azione", + "Action scope": "Ambito azione", + "Operate on new data": "Operare su nuovi dati", + "Operate on existing data": "Operare su dati esistenti", + "Yes": "Si", + "No": "No", + "Red": "Rosso", + "Magenta": "Magenta", + "Volcano": "Vulcano", + "Orange": "Arancione", + "Gold": "Oro", + "Lime": "Lime", + "Green": "Verde", + "Cyan": "Ciano", + "Blue": "Blu", + "Geek blue": "Geek Blue", + "Purple": "Viola", + "Default": "Predefinito", + "Add card": "Aggiungi scheda", + "edit title": "modifica titolo", + "Turn pages": "Volta pagine", + "Others": "Altri", + "Other records": "Altri record", + "Save as template": "Salva come modello", + "Save as block template": "Salva come modello blocco", + "Block templates": "Modelli blocco", + "Block template": "Modello blocco", + "Convert reference to duplicate": "Converti ​​riferimento a duplicato", + "Template name": "Nome modello", + "Block type": "Tipo blocco", + "No blocks to connect": "Nessun blocco per connettersi", + "Action column": "Colonna azioni", + "Records per page": "Record per pagina", + "(Fields only)": "(Solo campi)", + "Button title": "Titolo pulsante", + "Button icon": "Icona pulsante", + "Submitted successfully": "Invio riuscito", + "Operation succeeded": "L'operazione è riuscita", + "Operation failed": "Operazione non riuscita", + "Open mode": "Modalità aperta", + "Popup size": "Dimensione popup", + "Small": "Piccolo", + "Middle": "Medio", + "Large": "Grande", + "Size": "Misura", + "Oversized": "Oversize", + "Auto": "Auto", + "Object Fit": "Adattato all'oggetto", + "Cover": "Cover", + "Fill": "Riempi", + "Contain": "Contiene", + "Scale Down": "Ridimensiona", + "Menu item title": "Titolo voce di menu", + "Menu item icon": "Icona voce di menu", + "Target": "Destinazione", + "Position": "Posizione", + "Insert before": "Inserire prima", + "Insert after": "Inserire dopo", + "UI Editor": "Editor UI", + "ASC": "Asc", + "DESC": "Desc", + "Add sort field": "Aggiungi campo di ordinamento", + "ID": "ID", + "Identifier for program usage. Support letters, numbers and underscores, must start with an letter.": "Identificatore per l'utilizzo del programma. Supporta lettere, numeri e underscore, deve iniziare con una lettera.", + "Drawer": "Cassetto", + "Dialog": "Dialogo", + "Delete action": "Elimina azione", + "Custom column title": "Titolo colonna personalizzata", + "Column title": "Titolo colonna", + "Original title: ": "Titolo originale: ", + "Delete table column": "Elimina colonna della tabella", + "Skip required validation": "Salta convalida richiesta", + "Form values": "Valori modulo", + "Fields values": "Valori campi", + "The field has been deleted": "Il campo è stato eliminato", + "When submitting the following fields, the saved values are": "Quando si inviano i seguenti campi, i valori salvati sono", + "After successful submission": "Dopo un invio riuscito", + "Then": "Poi", + "Stay on current page": "Resta sulla pagina corrente", + "Redirect to": "Reindirizza a", + "Save action": "Salva azione", + "Exists": "Esiste", + "Add condition": "Aggiungi condizione", + "Add condition group": "Aggiungi gruppo di condizioni", + "exists": "esiste", + "not exists": "non esiste", + "Style": "Stile", + "=": "=", + "≠": "≠", + ">": ">", + "≥": "≥", + "<": "<", + "≤": "≤", + "Role UID": "Ruolo UID", + "Precision": "Precisione", + "Expression": "Espressione", + "Rich Text": "Testo ricco", + "Junction collection": "Raccolta giunzione", + "Leave it blank, unless you need a custom intermediate table": "Lascialo vuoto, a meno che tu non abbia bisogno di una tabella intermedia personalizzata", + "Fields": "Campi", + "Edit field title": "Modifica titolo campo", + "Field title": "Titolo campo", + "Original field title: ": "Titolo campo originale:", + "Edit tooltip": "Modifica suggerimento", + "Delete field": "Elimina campo", + "Select collection": "Seleziona raccolta", + "Blank block": "Blocco vuoto", + "Duplicate template": "Modello duplicato", + "Reference template": "Modello di riferimento", + "Create calendar block": "Crea blocco calendario", + "Create kanban block": "Crea blocco kanban", + "Grouping field": "Campo di raggruppamento", + "Single select and radio fields can be used as the grouping field": "I campi di selezione singoli e radio possono essere utilizzati come campo di raggruppamento", + "Tab name": "Nome della scheda", + "Current record blocks": "Blocchi record attuale", + "Popup message": "Messaggio popup", + "Delete role": "Elimina ruolo", + "Role display name": "Nome visualizzato ruolo", + "Default role": "Ruolo predefinito", + "All collections use general action permissions by default; permission configured individually will override the default one.": "Tutte le raccolte utilizzano i permessi di operazioni generali per impostazione predefinita; I permessi configurati individualmente sovrascriveranno quelli predefiniti.", + "Allows configuration of the whole system, including UI, collections, permissions, etc.": "Consente la configurazione dell'intero sistema, tra cui interfaccia utente, raccolte, permessi, ecc.", + "New menu items are allowed to be accessed by default.": "È possibile accedere a nuove voci di menu per impostazione predefinita.", + "Global permissions": "Permessi globali", + "General permissions": "Permessi generali", + "Global action permissions": "Permessi operazioni globali", + "General action permissions": "Permessi operazioni generali", + "Plugin settings permissions": "Permessi impostazioni plugin", + "Allow to desgin pages": "Consenti progettazione pagine", + "Allow to manage plugins": "Consenti gestione plugin", + "Allow to configure plugins": "Consenti configurazione plugin", + "Allows to configure interface": "Consente di configurare l'interfaccia", + "Allows to install, activate, disable plugins": "Consente di installare, attivare, disabilitare i plugin", + "Allows to configure plugins": "Consente di configurare i plugin", + "Action display name": "Nome visualizzato azione", + "Allow": "Permetti", + "Data scope": "Ambito dei dati", + "Action on new records": "Azione su nuovi record", + "Action on existing records": "Azione su record esistenti", + "All records": "Tutti i record", + "Own records": "Record propri", + "Permission policy": "Policy di autorizzazione", + "Individual": "Individuale", + "General": "Generale", + "Accessible": "Accessibile", + "Configure permission": "Configura permesso", + "Action permission": "Permesso azione", + "Field permission": "Permesso campo", + "Scope name": "Nome ambito", + "Unsaved changes": "Modifiche non salvate", + "Are you sure you don't want to save?": "Sei sicuro di non voler salvare?", + "Dragging": "Trascina", + "Popup": "Popup", + "Trigger workflow": "Trigger workflow", + "Request API": "Richiesta API", + "Assign field values": "Assegna valori del campo", + "Constant value": "Valore costante", + "Dynamic value": "Valore dinamico", + "Current user": "Utente attuale", + "Current role": "Ruolo attuale", + "Current record": "Record attuale", + "Current collection": "Raccolta attuale", + "Other collections": "Altre raccolte", + "Current popup record": "Record popup attuale", + "Parent popup record": "Record popup padre", + "Associated records": "Record associati", + "Parent record": "Record padre", + "Current time": "Ora attuale", + "System variables": "Variabili di sistema", + "Date variables": "Variabili della data", + "Message popup close method": "Metodo di chiusura popup di messaggio", + "Automatic close": "Chiudi automaticamente", + "Manually close": "Chiudi manualmente", + "After successful update": "Dopo un aggiornamento riuscito", + "Save record": "Salva record", + "Updated successfully": "Aggiornamento riuscito", + "After successful save": "Dopo un salvataggio riuscito", + "After clicking the custom button, the following field values will be assigned according to the following form.": "Dopo aver fatto clic sul pulsante personalizza, i seguenti valori verranno assegnati in base al seguente modulo.", + "After clicking the custom button, the following fields of the current record will be saved according to the following form.": "Dopo aver fatto clic sul pulsante personalizza, i seguenti campi del record corrente verranno salvati in base al seguente modulo.", + "Button background color": "Colore sfondo del pulsante", + "Highlight": "Evidenziato", + "Danger red": "Rosso pericolo", + "Custom request": "Richiesta personalizzata", + "Request settings": "Impostazioni richiesta", + "Request URL": "URL richiesta", + "Request method": "Metodo richiesta", + "Request query parameters": "Parametri richiesta query", + "Request headers": "Intestazioni richiesta", + "Request body": "Corpo richiesta", + "Request success": "Successo richiesta", + "Invalid JSON format": "Formato JSON non valido", + "After successful request": "Dopo una richiesta riuscita", + "Add exportable field": "Aggiungi campo esportabile", + "Audit logs": "Registri audit", + "Record ID": "ID record", + "User": "Utente", + "Field": "Campo", + "Select": "Seleziona", + "Select field": "Seleziona campo", + "Field value changes": "Modifiche valore del campo", + "One to one (has one)": "Uno a uno (ne ha uno)", + "One to one (belongs to)": "Uno a uno (appartiene a)", + "Use the same time zone (GMT) for all users": "Usa lo stesso fuso orario (GMT) per tutti gli utenti", + "Province/city/area name": "Nome provincia/città/area", + "Enabled languages": "Lingue abilitate", + "View all plugins": "Visualizza tutti i plugin", + "Print": "Stampa", + "Done": "Fatto", + "Sign up successfully, and automatically jump to the sign in page": "Iscriviti correttamente e reindirizza automaticamente alla pagina di accesso", + "File manager": "File Manager", + "ACL": "ACL", + "Collection manager": "Responsabile della raccolta", + "Plugin manager": "Plugin Manager", + "Local": "Locale", + "Built-in": "Incorporato", + "Marketplace": "Marketplace", + "Add plugin": "Aggiungi plugin", + "Plugin source": "Sorgente plugin", + "Upgrade": "Aggiornamento", + "Plugin dependencies check failed": "Controllo delle dipendenze del plugin non riuscito", + "More details": "Maggiori dettagli", + "Upload new version": "Carica nuova versione", + "Version": "Versione", + "Npm package": "Pacchetto Npm", + "Npm package name": "Nome pacchetto Npm", + "Upload plugin": "Carica plugin", + "Official plugin": "Plugin ufficiale", + "Add type": "Aggiungi tipo", + "Changelog": "Changelog", + "Dependencies check": "Controllo delle dipendenze", + "Update plugin": "Aggiorna plugin", + "Installing": "Installazione", + "The deletion was successful.": "Cancellazione riuscita.", + "Plugin Zip File": "File zip plugin", + "Compressed file url": "URL file compresso", + "Last updated": "Ultimo aggiornamento", + "PackageName": "Nome pacchetto", + "DisplayName": "Nome da visualizzare", + "Readme": "Readme", + "Dependencies compatibility check": "Controllo compatibilità delle dipendenze", + "Plugin dependencies check failed, you should change the dependent version to meet the version requirements.": "Controllo delle dipendenze del plugin non riuscito, è necessario modificare la versione dipendente per soddisfare i requisiti della versione.", + "Version range": "Range versione", + "Plugin's version": "Versione plugin", + "Result": "Risultato", + "No CHANGELOG.md file": "Nessun file Changelog.md", + "No README.md file": "Nessun file readme.md", + "Homepage": "Homepage", + "Drag and drop the file here or click to upload, file size should not exceed 30M": "Trascina e rilascia il file qui o fai clic per caricare, la dimensione del file non deve superare i 30M", + "Dependencies check failed, can't enable.": "Il controllo delle dipendenze non è riuscito, impossibile abilitare.", + "Plugin starting...": "Avvio plugin...", + "Plugin stopping...": "Interruzione plugin ...", + "Are you sure to delete this plugin?": "Sei sicuro di eliminare questo plugin?", + "Are you sure to disable this plugin?": "Sei sicuro di disabilitare questo plugin?", + "re-download file": "ri-scarica file", + "Not enabled": "Non abilitato", + "Search plugin": "Ricerca plugin", + "Author": "Autore", + "Plugin loading failed. Please check the server logs.": "Il caricamento del plugin non è riuscito. Si prega di controllare i registri del server.", + "Coming soon...": "Prossimamente...", + "All plugin settings": "Tutte le impostazioni del plugin", + "Bookmark": "Segnalibro", + "Manage all settings": "Gestisci tutte le impostazioni", + "Create inverse field in the target collection": "Crea campo inverso nella raccolta di destinazione", + "Inverse field name": "Nome campo inverso", + "Inverse field display name": "Nome visualizzato campo inverso", + "Bulk update": "Aggiornamento di massa", + "After successful bulk update": "Dopo un aggiornamento di massa riuscito", + "Bulk edit": "Modifica di massa", + "Data will be updated": "I dati verranno aggiornati", + "Selected": "Selezionato", + "All": "Tutto", + "Update selected data?": "Aggiornare i dati selezionati?", + "Update all data?": "Aggiornare tutti i dati?", + "Remains the same": "Rimane lo stesso", + "Changed to": "Cambiato in", + "Clear": "Cancella", + "Add attach": "Aggiungi allegato", + "Please select the records to be updated": "Si prega di selezionare i record da aggiornare", + "Selector": "Selettore", + "Inner": "Interno", + "Search and select collection": "Cerca e seleziona la raccolta", + "Please fill in the iframe URL": "Si prega di compilare l'URL iFrame", + "Fix block": "Fissa blocco", + "Plugin name": "Nome plugin", + "Plugin tab name": "Nome scheda plugin", + "Column width": "Larghezza colonna", + "Sortable": "Ordinabile", + "Enable link": "Abilita link", + "This is likely a NocoBase internals bug. Please open an issue at <1>here": "Questo sembra un bug interno di NocoBase. Si prega di aprire un ticket <1>qui", + "Render Failed": "Rendering non riuscito", + "App error": "Errore app", + "Feedback": "Feedback", + "Try again": "Riprova", + "Download logs": "Download registri", + "Data template": "Modello dati", + "Duplicate": "Duplica", + "Duplicating": "Duplicazione", + "Duplicate mode": "Modalità duplicazione", + "Quick duplicate": "Duplicazione veloce", + "Duplicate and continue": "Duplica e continua", + "Please configure the duplicate fields": "Si prega di configurare i campi duplicati", + "Add": "Aggiungi", + "Add new mode": "Modalità aggiungi nuovo", + "Quick add": "Aggiunta rapida", + "Modal add": "Aggiunta modale", + "Save mode": "Modalità salvataggio", + "First or create": "Prima o crea", + "Update or create": "Aggiorna o crea", + "Find by the following fields": "Trova dai seguenti campi", + "Create": "Crea", + "Current form": "Modulo corrente", + "Current object": "Oggetto corrente", + "Linkage with form fields": "Collegamento con i campi del modulo", + "Allow add new, update and delete actions": "Consenti azioni aggiungi nuovo, aggiorna ed elimina", + "Date display format": "Formato di visualizzazione della data", + "Table selected records": "Tabella record selezionati", + "Tag": "Etichetta", + "Tag color field": "Campo colore etichetta", + "Sync successfully": "Sincronizzazione riuscita", + "Sync from form fields": "Sincronizzazione dai campi del modulo", + "Select all": "Seleziona tutto", + "Restart": "Ricomincia", + "Restart application": "Riavvia applicazione", + "Cascade Select": "Seleziona in cascata", + "Execute": "Esegui", + "Please use a valid SELECT or WITH AS statement": "Si prega di utilizzare un' istruzione SELECT o WITH AS valida", + "Please confirm the SQL statement first": "Si prega di confermare prima l'istruzione SQL", + "Automatically drop objects that depend on the collection (such as views), and in turn all objects that depend on those objects": "Elimina automaticamente gli oggetti che dipendono dalla raccolta (come le viste) e, a loro volta, tutti gli oggetti che dipendono da tali oggetti", + "Sign in with another account": "Accedi con un altro account", + "Return to the main application": "Torna alla applicazione principale", + "loading": "caricamento", + "name is required": "nome richiesto", + "data source": "sorgente dati", + "Data source": "Sorgente dati", + "DataSource": "Sorgente Dati", + "The {{type}} \"{{name}}\" may have been deleted. Please remove this {{blockType}}.": "Il {{type}} \"{{name}}\" potrebbe essere stato eliminato. Si prega di rimuovere {{blockType}}.", + "Preset fields": "Campi preimpostati", + "Home page": "Home page", + "Handbook": "Manuale", + "License": "Licenza", + "Generic properties": "Proprietà generiche", + "Specific properties": "Proprietà specifiche", + "Used for drag and drop sorting scenarios, supporting grouping sorting": "Utilizzato per scenari con drag and drop, supporta ordinamento raggruppato", + "Grouped sorting": "Ordinamento raggruppato", + "When a field is selected for grouping, it will be grouped first before sorting.": "Quando viene selezionato un campo per il raggruppamento, verrà raggruppato prima dell'ordinamento.", + "Departments": "Dipartimenti", + "Main department": "Dipartimento principale", + "Department name": "Nome del dipartimento", + "Superior department": "Dipartimento superiore", + "Owners": "Proprietari", + "Plugin settings": "Impostazioni plugin", + "Menu": "Menu", + "Drag and drop sorting field": "Campi ordinamento drag and drop", + "This variable has been deprecated and can be replaced with \"Current form\"": "Questa variabile è stata deprecata e può essere sostituita con \"Current form\"", + "The value of this variable is derived from the query string of the page URL. This variable can only be used normally when the page has a query string.": "Il valore di questa variabile deriva dalla stringa di ricerca nell'URL della pagina. Questa variabile può essere utilizzata normalmente solo quando la pagina ha una stringa di ricerca.", + "URL search params": "Parametri di ricerca URL", + "Expand All": "Espandi tutto", + "Search": "Ricerca", + "Clear default value": "Cancella valore predefinito", + "Open in new window": "Apri in una nuova finestra", + "Sorry, the page you visited does not exist.": "Spiacente, la pagina che hai visitato non esiste.", + "is none of": "non è nessuno di", + "is any of": "è uno di", + "Plugin dependency version mismatch": "Mancata corrispondenza della versione della dipendenza del plugin", + "The current dependency version of the plugin does not match the version of the application and may not work properly. Are you sure you want to continue enabling the plugin?": "L'attuale versione della dipendenza del plugin non corrisponde alla versione dell'applicazione e potrebbe non funzionare correttamente. Sei sicuro di voler continuare a abilitare il plugin?", + "Allow multiple selection": "Consenti selezione multipla", + "Parent object": "Oggetto padre", + "Skip getting the total number of table records during paging to speed up loading. It is recommended to enable this option for data tables with a large amount of data": "Ometti calcolo del numero totale di record della tabella durante l'impaginazione per accelerare il caricamento. Si consiglia di abilitare questa opzione per tabelle con grandi quantità di dati", + "Enable secondary confirmation": "Abilita conferma secondaria", + "Notification": "Notifica", + "Ellipsis overflow content": "Contenuto Ellipsis overflow", + "Hide column": "Nascondi colonna", + "In configuration mode, the entire column becomes transparent. In non-configuration mode, the entire column will be hidden. Even if the entire column is hidden, its configured default values and other settings will still take effect.": "In modalità di configurazione, l'intera colonna diventa trasparente. In modalità non di configurazione, l'intera colonna verrà nascosta. Anche se l'intera colonna è nascosta, i suoi valori predefiniti configurati e le altre impostazioni avranno comunque effetto.", + "Page number": "Numero di pagina", + "Page size": "Numero di voci per pagina", + "Enable": "Abilita", + "Disable": "Disabilita", + "Tab": "Scheda", + "Calculation engine": "Motore di calcolo", + "Expression collection": "Raccolta espressioni", + "Tree collection": "Raccolta struttura ad albero", + "Parent ID": "ID record padre", + "Parent": "Record padre", + "Children": "Record figlio", + "Confirm": "Conferma", + "Block": "Blocco", + "Unnamed": "Senza nome", + "SQL collection": "Raccolta dati SQL", + "Configure field": "Configura campo", + "Username": "Nome utente", + "Null": "Null", + "Boolean": "Booleano", + "String": "Stringa", + "Syntax references": "Riferimenti sintassi", + "Math.js comes with a large set of built-in functions and constants, and offers an integrated solution to work with different data types.": "Math.js include un ampio set di funzioni e costanti integrate e offre una soluzione integrata per lavorare con diversi tipi di dati.", + "Formula.js supports most Microsoft Excel formula functions.": "Formula.js supporta la maggior parte delle funzioni delle formule di Microsoft Excel.", + "String template": "Modello stringa", + "Simple string replacement, can be used to interpolate variables in a string.": "Sostituzione semplice di stringhe, può essere utilizzata per interpolare variabili in una stringa.", + "https://docs.nocobase.com/handbook/calculation-engines/formula": "https://docs-cn.nocobase.com/handbook/calculation-engines/formula", + "https://docs.nocobase.com/handbook/calculation-engines/mathjs": "https://docs-cn.nocobase.com/handbook/calculation-engines/mathjs", + "Display when unchecked": "Visualizza quando deselezionato", + "Allow dissociate": "Consenti dissociazione", + "Edit block title & description": "Modifica titolo e descrizione blocco", + "Add Markdown": "Aggiungi Markdown", + "Must be 1-50 characters in length (excluding @.<>\"'/)": "Deve essere lungo 1-50 caratteri (esclusi @.<>\"'/)", + "Data source permissions": "Permessi origine dati", + "Now": "Adesso", + "Access control": "Controllo accessi", + "Remove": "Rimuovi", + "Docs": "Documenti", + "Enable page header": "Abilita intestazione pagina", + "Display page title": "Visualizza titolo pagina", + "Edit page title": "Modifica titolo pagina", + "Enable page tabs": "Abilita schede pagina", + "Constant": "Costante", + "Select a variable": "Seleziona una variabile", + "Double click to choose entire object": "Doppio clic per scegliere l'intero oggetto", + "True": "Vero", + "False": "Falso", + "Prettify": "Formatta", + "Theme": "Tema", + "Default theme": "Tema predefinito", + "Compact theme": "Tema compatto", + "Download": "Scarica", + "File type is not supported for previewing, please download it to preview.": "Il tipo di file non è supportato per l'anteprima, scaricalo per visualizzarlo.", + "Click or drag file to this area to upload": "Clicca o trascina il file in quest'area per caricarlo", + "Support for a single or bulk upload.": "Supporta il caricamento singolo o in blocco.", + "File size should not exceed {{size}}.": "La dimensione del file non deve superare {{size}}.", + "File size exceeds the limit": "La dimensione del file supera il limite", + "File type is not allowed": "Il tipo di file non è consentito", + "Incomplete uploading files need to be resolved": "I caricamenti incompleti dei file devono essere completati", + "Default title for each record": "Titolo predefinito per ogni record", + "If collection inherits, choose inherited collections as templates": "Se la raccolta eredita, scegli le raccolte ereditate come modelli", + "Select an existing piece of data as the initialization data for the form": "Seleziona un dato esistente come dati di inizializzazione per il modulo", + "Only the selected fields will be used as the initialization data for the form": "Solo i campi selezionati verranno utilizzati come dati di inizializzazione per il modulo", + "Template Data": "Dati modello", + "Data fields": "Campi dati", + "Add template": "Aggiungi modello", + "Enable form data template": "Abilita modello dati modulo", + "Form data templates": "Modelli dati modulo", + "No configuration available.": "Nessuna configurazione disponibile.", + "Reload application": "Ricarica applicazione", + "The application is reloading, please do not close the page.": "L'applicazione si sta ricaricando, non chiudere la pagina.", + "Application reloading": "Ricaricamento applicazione", + "Allows to clear cache, reboot application": "Consente di cancellare la cache, riavviare l'applicazione", + "The will interrupt service, it may take a few seconds to restart. Are you sure to continue?": "Il riavvio interromperà il servizio, potrebbero essere necessari alcuni secondi. Sei sicuro di continuare?", + "Clear cache": "Cancella cache", + "Quick create": "Creazione rapida", + "Dropdown": "Menu a discesa", + "Pop-up": "Popup", + "Direct duplicate": "Duplicazione diretta", + "Copy into the form and continue to fill in": "Copia nel modulo e continua a compilare", + "Failed to load plugin": "Caricamento plugin fallito", + "Date range limit": "Limite intervallo date", + "MinDate": "Data minima", + "MaxDate": "Data massima", + "Please select time or variable": "Seleziona ora o variabile", + "Filter out a single piece or a group of records as a template": "Filtra un singolo dato o un gruppo di record come modello", + "The title field is used to identify the template record": "Il campo titolo è utilizzato per identificare il record modello", + "Template fields": "Campi modello", + "The selected fields will automatically populate the form": "I campi selezionati popoleranno automaticamente il modulo", + "UnSelect all": "Deseleziona tutto", + "Secondary confirmation": "Conferma secondaria", + "Perform the {{title}}": "Esegui {{title}}", + "Are you sure you want to perform the {{title}} action?": "Sei sicuro di voler eseguire l'azione {{title}}?", + "Permission denied": "Permesso negato", + "Allow add new": "Consenti aggiunta", + "Data model": "Modello dati", + "Security": "Sicurezza", + "Action": "Azione", + "System": "Sistema", + "Other": "Altro", + "Allow selection of existing records": "Consenti selezione di record esistenti", + "Data Model": "Modello dati", + "Blocks": "Blocchi", + "Users & permissions": "Utenti e permessi", + "System management": "Gestione sistema", + "System & security": "Sistema e sicurezza", + "Workflow": "Workflow", + "Third party services": "Servizi di terze parti", + "Data model tools": "Strumenti modello dati", + "Data sources": "Origini dati", + "Collections": "Raccolte", + "Collection fields": "Campi raccolta", + "Authentication": "Autenticazione", + "Logging and monitoring": "Registrazione e monitoraggio", + "Main": "Principale", + "Index": "Indice", + "Field values must be unique.": "I valori dei campi devono essere univoci.", + "Alphabet": "Alfabeto", + "Accuracy": "Precisione", + "Millisecond": "Millisecondo", + "Second": "Secondo", + "Unix Timestamp": "Timestamp Unix", + "Field value do not meet the requirements": "Il valore del campo non soddisfa i requisiti", + "Field value size is": "La dimensione del valore del campo è", + "Unit conversion": "Conversione unità", + "Separator": "Separatore", + "Prefix": "Prefisso", + "Suffix": "Suffisso", + "Record unique key": "Chiave univoca record", + "Filter target key": "Chiave target filtro", + "If a collection lacks a primary key, you must configure a unique record key to locate row records within a block, failure to configure this will prevent the creation of data blocks for the collection.": "Se una raccolta non ha una chiave primaria, devi configurare un record come chiave univoca per individuare i record di ogni riga all'interno di un blocco, la mancata configurazione impedirà la creazione di blocchi di dati per la raccolta.", + "Filter data based on the specific field, with the requirement that the field value must be unique.": "Filtra i dati in base a un campo specifico, con il requisito che il valore del campo deve essere univoco.", + "Multiply by": "Moltiplica per", + "Divide by": "Dividi per", + "Scientifix notation": "Notazione scientifica", + "Normal": "Normale", + "Automatically generate default values": "Genera automaticamente valori predefiniti", + "Refresh data on close": "Refresh dei dati alla chiusura", + "Refresh data on action": "Refresh dei dati su azione", + "Unknown field type": "Tipo di campo sconosciuto", + "The following field types are not compatible and do not support output and display": "I seguenti tipi di campo non sono compatibili e non supportano l'output e la visualizzazione", + "Not fixed": "Non fissato", + "Left fixed": "Fissato a sinistra", + "Right fixed": "Fissato a destra", + "Fixed": "Colonna fissa", + "Set block height": "Imposta altezza del blocco", + "Specify height": "Specifica altezza", + "Full height": "Altezza completa", + "Please configure the URL": "Configura l'URL", + "URL": "URL", + "Search parameters": "Parametri di ricerca URL", + "Do not concatenate search params in the URL": "Non concatenare i parametri di ricerca nell'URL", + "Edit link": "Modifica link", + "Add parameter": "Aggiungi parametro", + "Use simple pagination mode": "Usa modalità di paginazione semplice", + "Set Template Engine": "Imposta motore template", + "Template engine": "Motore template", + "The current user only has the UI configuration permission, but don't have view permission for collection \"{{name}}\"": "L'utente corrente ha solo il permesso di configurazione dell'interfaccia utente, ma non ha il permesso di visualizzazione per la raccolta \"{{name}}\"", + "Default value to current time": "Imposta il valore predefinito del campo all'ora corrente", + "Automatically update timestamp on update": "Aggiorna automaticamente il timestamp all'aggiornamento", + "Default value to current server time": "Imposta il valore predefinito del campo all'ora corrente del server", + "Automatically update timestamp to the current server time on update": "Aggiorna automaticamente il timestamp all'ora corrente del server all'aggiornamento", + "Datetime (with time zone)": "Data e ora (con fuso orario)", + "Datetime (without time zone)": "Data e ora (senza fuso orario)", + "DateOnly": "Solo data", + "Content": "Contenuto", + "Perform the Update record": "Esegui aggiornamento record", + "Are you sure you want to perform the Update record action?": "Sei sicuro di voler eseguire l'azione di aggiornamento record?", + "Perform the Custom request": "Esegui richiesta personalizzata", + "Are you sure you want to perform the Custom request action": "Sei sicuro di voler eseguire l'azione di richiesta personalizzata?", + "Perform the Refresh": "Esegui refresh", + "Are you sure you want to perform the Refresh action?": "Sei sicuro di voler eseguire l'azione di refresh?", + "Perform the Submit": "Esegui l'invio", + "Are you sure you want to perform the Submit action?": "Sei sicuro di voler eseguire l'azione di invio?", + "Perform the Trigger workflow": "Esegui il trigger del workflow", + "Are you sure you want to perform the Trigger workflow action?": "Sei sicuro di voler eseguire l'azione di trigger del workflow?", + "Picker": "Selettore", + "Quarter": "Trimestre", + "Switching the picker, the value and default value will be cleared": "Cambiando il selettore, il valore e il valore predefinito verranno cancellati", + "Stay on the current popup or page": "Rimani nel popup o nella pagina corrente", + "Return to the previous popup or page": "Torna al popup o alla pagina precedente", + "Action after successful submission": "Azione dopo l'invio riuscito", + "Allow disassociation": "Consenti la dissociazione", + "Layout": "Layout", + "Vertical": "Verticale", + "Horizontal": "Orizzontale", + "Edit group title": "Modifica titolo del gruppo", + "Title position": "Posizione titolo", + "Dashed": "Tratteggiato", + "Left": "Sinistra", + "Center": "Centro", + "Right": "Destra", + "Divider line color": "Colore linea di divisione", + "Label align": "Allineamento etichetta", + "Label width": "Larghezza etichetta", + "When the Label exceeds the width": "Quando l'etichetta supera la larghezza", + "Line break": "A capo", + "Ellipsis": "Ellipsis", + "Set block layout": "Imposta layout del blocco", + "Add & Update": "Aggiungi e aggiorna", + "Table size": "Dimensione della tabella", + "Plugin": "Plugin", + "Bulk enable": "Abilitazione in blocco", + "Search plugin...": "Cerca plugin...", + "Package name": "Nome pacchetto", + "Associate": "Associa", + "Please add or select record": "Aggiungi o seleziona record", + "No data": "Nessun dato", + "Fields can only be used correctly if they are defined with an interface.": "I campi possono essere utilizzati correttamente solo se sono definiti con un'interfaccia.", + "Unauthenticated. Please sign in to continue.": "Non autenticato. Accedi per continuare.", + "User not found. Please sign in again to continue.": "Impossibile trovare l'utente. Accedi nuovamente per continuare.", + "Your session has expired. Please sign in again.": "La tua sessione è scaduta. Accedi nuovamente.", + "User password changed, please signin again.": "La password dell'utente è stata modificata, accedi di nuovo.", + "Show file name": "Mostra nome del file", + "Outlined": "Contornato", + "Filled": "Riempito", + "Two tone": "Due toni", + "Desktop routes": "Percorsi desktop", + "Route permissions": "Permessi percorso", + "New routes are allowed to be accessed by default": "I nuovi percorsi sono accessibili per impostazione predefinita", + "Route name": "Nome percorso", + "Mobile routes": "Percorsi mobile", + "Show in menu": "Mostra nel menu", + "Hide in menu": "Nascondi nel menu", + "Path": "Percorso", + "Type": "Tipo", + "Access": "Accesso", + "Routes": "Percorsi", + "Add child route": "Aggiungi percorso figlio", + "Delete routes": "Elimina percorsi", + "Delete route": "Elimina percorso", + "Are you sure you want to hide these routes in menu?": "Sei sicuro di voler nascondere questi percorsi nel menu?", + "Are you sure you want to show these routes in menu?": "Sei sicuro di voler mostrare questi percorsi nel menu?", + "Are you sure you want to hide this menu?": "Sei sicuro di voler nascondere questo menu?", + "After hiding, this menu will no longer appear in the menu bar. To show it again, you need to go to the route management page to configure it.": "Dopo averlo nascosto, questo menu non apparirà più nella barra dei menu. Per mostrarlo di nuovo, devi andare alla pagina di gestione dei percorsi per configurarlo.", + "If selected, the page will display Tab pages.": "Se selezionato, la pagina visualizzerà le pagine schede.", + "If selected, the route will be displayed in the menu.": "Se selezionato, il percorso verrà visualizzato nel menu.", + "Are you sure you want to hide this tab?": "Sei sicuro di voler nascondere questa scheda?", + "After hiding, this tab will no longer appear in the tab bar. To show it again, you need to go to the route management page to set it.": "Dopo averla nascosta, questa scheda non apparirà più nella barra delle schede. Per mostrarla di nuovo, devi andare alla pagina di gestione dei percorsi per configurarlo." +} diff --git a/packages/core/client/src/locale/zh-CN.json b/packages/core/client/src/locale/zh-CN.json index c563280d52..516c5a9f8b 100644 --- a/packages/core/client/src/locale/zh-CN.json +++ b/packages/core/client/src/locale/zh-CN.json @@ -1094,5 +1094,6 @@ "Font Size(px)": "字体大小(像素)", "Font Weight": "字体粗细", "Font Style": "字体样式", - "Italic": "斜体" + "Italic": "斜体", + "Response record":"响应结果记录" } diff --git a/packages/core/client/src/modules/fields/component/Select/selectComponentFieldSettings.tsx b/packages/core/client/src/modules/fields/component/Select/selectComponentFieldSettings.tsx index dc3ff40a10..8daaabe25d 100644 --- a/packages/core/client/src/modules/fields/component/Select/selectComponentFieldSettings.tsx +++ b/packages/core/client/src/modules/fields/component/Select/selectComponentFieldSettings.tsx @@ -126,6 +126,10 @@ export const getAllowMultiple = (params?: { title: string }) => { return { name: 'allowMultiple', type: 'switch', + useVisible() { + const isAssociationField = useIsAssociationField(); + return isAssociationField; + }, useComponentProps() { const { t } = useTranslation(); const field = useField(); diff --git a/packages/core/client/src/modules/menu/LinkMenuItem.tsx b/packages/core/client/src/modules/menu/LinkMenuItem.tsx index 8217f7de14..aace433ec4 100644 --- a/packages/core/client/src/modules/menu/LinkMenuItem.tsx +++ b/packages/core/client/src/modules/menu/LinkMenuItem.tsx @@ -14,6 +14,14 @@ import React, { useCallback, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { Router } from 'react-router-dom'; import { SchemaInitializerItem } from '../../application'; +import { + CollectionManagerProvider, + useCollectionManager, +} from '../../data-source/collection/CollectionManagerProvider'; +import { + DataSourceManagerProvider, + useDataSourceManager, +} from '../../data-source/data-source/DataSourceManagerProvider'; import { useGlobalTheme } from '../../global-theme'; import { NocoBaseDesktopRouteType } from '../../route-switch/antd/admin-layout/convertRoutesToSchema'; import { @@ -34,6 +42,8 @@ export const LinkMenuItem = () => { const { urlSchema, paramsSchema } = useURLAndHTMLSchema(); const parentRoute = useParentRoute(); const { createRoute } = useNocoBaseRoutes(); + const dm = useDataSourceManager(); + const cm = useCollectionManager(); const handleClick = useCallback(async () => { const values = await FormDialog( @@ -41,31 +51,35 @@ export const LinkMenuItem = () => { () => { const history = createMemoryHistory(); return ( - - - - - - - + + + + + + + + + + + ); }, theme, diff --git a/packages/core/client/src/pm/PluginManager.tsx b/packages/core/client/src/pm/PluginManager.tsx index f1a1de64f0..6ffe8eb425 100644 --- a/packages/core/client/src/pm/PluginManager.tsx +++ b/packages/core/client/src/pm/PluginManager.tsx @@ -127,25 +127,27 @@ function BulkEnableButton({ plugins = [] }) { }} size={'small'} pagination={false} - columns={[ - { - title: t('Plugin'), - dataIndex: 'displayName', - ellipsis: true, - }, - { - title: t('Description'), - dataIndex: 'description', - ellipsis: true, - width: 300, - }, - { - title: t('Package name'), - dataIndex: 'packageName', - width: 300, - ellipsis: true, - }, - ] as TableProps['columns']} + columns={ + [ + { + title: t('Plugin'), + dataIndex: 'displayName', + ellipsis: true, + }, + { + title: t('Description'), + dataIndex: 'description', + ellipsis: true, + width: 300, + }, + { + title: t('Package name'), + dataIndex: 'packageName', + width: 300, + ellipsis: true, + }, + ] as TableProps['columns'] + } dataSource={items} /> diff --git a/packages/core/client/src/pm/PluginManagerLink.tsx b/packages/core/client/src/pm/PluginManagerLink.tsx index 2d5815f1c4..2fce194c38 100644 --- a/packages/core/client/src/pm/PluginManagerLink.tsx +++ b/packages/core/client/src/pm/PluginManagerLink.tsx @@ -88,7 +88,7 @@ export const SettingsCenterDropdown = () => { } @@ -321,6 +335,7 @@ function FinallyButton({ style={{ display: !designable && field?.data?.hidden && 'none', opacity: designable && field?.data?.hidden && 0.1, + ...buttonStyle, }} > {props.children} @@ -342,7 +357,7 @@ function FinallyButton({ ...props?.style, display: !designable && field?.data?.hidden && 'none', opacity: designable && field?.data?.hidden && 0.1, - height: '100%', + ...buttonStyle, }} > {props.onlyIcon ? props?.children?.[1] : props?.children} diff --git a/packages/core/client/src/schema-settings/LinkageRules/action-hooks.ts b/packages/core/client/src/schema-settings/LinkageRules/action-hooks.ts index fe33bba3c4..5c1b3c2b20 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/action-hooks.ts +++ b/packages/core/client/src/schema-settings/LinkageRules/action-hooks.ts @@ -57,16 +57,6 @@ export const useLinkageCollectionFieldOptions = (collectionName: string, readPre if (nested || children || ['formula', 'richText', 'sequence'].includes(fieldInterface.name)) { return operator?.value !== ActionType.Value && operator?.value !== ActionType.Options; } - if (!['select', 'radioGroup', 'multipleSelect', 'checkboxGroup'].includes(fieldInterface.name)) { - return operator?.value !== ActionType.Options; - } - if ( - !['date', 'datetime', 'dateOnly', 'datetimeNoTz', 'unixTimestamp', 'createdAt', 'updatedAt'].includes( - fieldInterface.name, - ) - ) { - return operator?.value !== ActionType.DateScope; - } return true; }) || [], }; diff --git a/packages/core/client/src/schema-settings/LinkageRules/useValues.ts b/packages/core/client/src/schema-settings/LinkageRules/useValues.ts index 722b9da6ae..0001622468 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/useValues.ts +++ b/packages/core/client/src/schema-settings/LinkageRules/useValues.ts @@ -10,6 +10,7 @@ import { useField } from '@formily/react'; import { useEffect, useContext } from 'react'; import { LinkageLogicContext } from './context'; +import { ActionType } from './type'; const findOption = (dataIndex = [], options) => { let items = options; @@ -45,9 +46,34 @@ export const useValues = (options) => { field.data = field.data || {}; const operators = option?.operators; field.data.operators = operators?.filter((v) => { - if (dataIndex.length > 1) { - return !['value', 'dateScope', 'options'].includes(v.value); + const isOptionField = ['select', 'radioGroup', 'multipleSelect', 'checkboxGroup'].includes( + option?.interface || '', + ); + const isDateField = [ + 'date', + 'datetime', + 'dateOnly', + 'datetimeNoTz', + 'unixTimestamp', + 'createdAt', + 'updatedAt', + ].includes(option?.interface || ''); + + // 如果 多个字段,则排除 Value、DateScope、Options + if (dataIndex.length > 1 && [ActionType.Value, ActionType.DateScope, ActionType.Options].includes(v.value)) { + return false; } + + // 非选项字段,去掉 Options + if (!isOptionField && v.value === ActionType.Options) { + return false; + } + + // 非时间字段,去掉 DateScope + if (!isDateField && v.value === ActionType.DateScope) { + return false; + } + return true; }); field.data.schema = option?.schema; diff --git a/packages/core/client/src/variables/VariablesProvider.tsx b/packages/core/client/src/variables/VariablesProvider.tsx index 85c14a4a18..c7ffc83da5 100644 --- a/packages/core/client/src/variables/VariablesProvider.tsx +++ b/packages/core/client/src/variables/VariablesProvider.tsx @@ -18,7 +18,6 @@ import { getDataSourceHeaders } from '../data-source/utils'; import { useCompile } from '../schema-component'; import useBuiltInVariables from './hooks/useBuiltinVariables'; import { VariableOption, VariablesContextType } from './types'; -import { cacheLazyLoadedValues, getCachedLazyLoadedValues } from './utils/cacheLazyLoadedValues'; import { filterEmptyValues } from './utils/filterEmptyValues'; import { getAction } from './utils/getAction'; import { getPath } from './utils/getPath'; @@ -144,14 +143,13 @@ const VariablesProvider = ({ children, filterVariables }: any) => { .then((data) => { clearRequested(url); const value = data.data.data; - cacheLazyLoadedValues(item, currentVariablePath, value); return value; }); stashRequested(url, result); return result; } } - return getCachedLazyLoadedValues(item, currentVariablePath) || item?.[key]; + return item?.[key]; }); current = removeThroughCollectionFields(_.flatten(await Promise.all(result)), associationField); } else if ( @@ -180,17 +178,9 @@ const VariablesProvider = ({ children, filterVariables }: any) => { } const value = data.data.data; - if (!getCachedLazyLoadedValues(current, currentVariablePath)) { - // Cache the API response data to avoid repeated requests - cacheLazyLoadedValues(current, currentVariablePath, value); - } - current = removeThroughCollectionFields(value, associationField); } else { - current = removeThroughCollectionFields( - getCachedLazyLoadedValues(current, currentVariablePath) || getValuesByPath(current, key), - associationField, - ); + current = removeThroughCollectionFields(getValuesByPath(current, key), associationField); } if (associationField?.target) { @@ -359,13 +349,8 @@ export default VariablesProvider; function shouldToRequest(value, variableCtx: Record, variablePath: string) { let result = false; - if (getCachedLazyLoadedValues(variableCtx, variablePath)) { - return false; - } - // value may be a reactive object, using untracked to avoid unexpected autorun untracked(() => { - // fix https://nocobase.height.app/T-2502 // Compatible with `xxx to many` and `xxx to one` subform fields and subtable fields if (JSON.stringify(value) === '[{}]' || JSON.stringify(value) === '{}') { result = true; diff --git a/packages/core/client/src/variables/utils/cacheLazyLoadedValues.ts b/packages/core/client/src/variables/utils/cacheLazyLoadedValues.ts deleted file mode 100644 index 9d07c2959d..0000000000 --- a/packages/core/client/src/variables/utils/cacheLazyLoadedValues.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -const cache = new Map, any>(); - -export const cacheLazyLoadedValues = (variableCtx: Record, variablePath: string, value: any) => { - const cachedValue = cache.get(variableCtx); - - if (cachedValue) { - cachedValue[variablePath] = value; - } else { - cache.set(variableCtx, { [variablePath]: value }); - } -}; - -export const getCachedLazyLoadedValues = (variableCtx: Record, variablePath: string) => { - const cachedValue = cache.get(variableCtx); - return cachedValue?.[variablePath]; -}; diff --git a/packages/core/create-nocobase-app/package.json b/packages/core/create-nocobase-app/package.json index bc1274eb2a..05084946fa 100755 --- a/packages/core/create-nocobase-app/package.json +++ b/packages/core/create-nocobase-app/package.json @@ -1,6 +1,6 @@ { "name": "create-nocobase-app", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "src/index.js", "license": "AGPL-3.0", "dependencies": { diff --git a/packages/core/data-source-manager/package.json b/packages/core/data-source-manager/package.json index 21768f0e9f..6f579e30d1 100644 --- a/packages/core/data-source-manager/package.json +++ b/packages/core/data-source-manager/package.json @@ -1,16 +1,16 @@ { "name": "@nocobase/data-source-manager", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/actions": "1.7.0-alpha.4", - "@nocobase/cache": "1.7.0-alpha.4", - "@nocobase/database": "1.7.0-alpha.4", - "@nocobase/resourcer": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/actions": "1.7.0-beta.9", + "@nocobase/cache": "1.7.0-beta.9", + "@nocobase/database": "1.7.0-beta.9", + "@nocobase/resourcer": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "@types/jsonwebtoken": "^8.5.8", "jsonwebtoken": "^8.5.1" }, diff --git a/packages/core/database/package.json b/packages/core/database/package.json index fd3d45ec40..b07abbcfca 100644 --- a/packages/core/database/package.json +++ b/packages/core/database/package.json @@ -1,13 +1,13 @@ { "name": "@nocobase/database", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "main": "./lib/index.js", "types": "./lib/index.d.ts", "license": "AGPL-3.0", "dependencies": { - "@nocobase/logger": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/logger": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "async-mutex": "^0.3.2", "chalk": "^4.1.1", "cron-parser": "4.4.0", diff --git a/packages/core/devtools/package.json b/packages/core/devtools/package.json index 9bfb552a15..f567922e23 100644 --- a/packages/core/devtools/package.json +++ b/packages/core/devtools/package.json @@ -1,13 +1,13 @@ { "name": "@nocobase/devtools", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./src/index.js", "dependencies": { - "@nocobase/build": "1.7.0-alpha.4", - "@nocobase/client": "1.7.0-alpha.4", - "@nocobase/test": "1.7.0-alpha.4", + "@nocobase/build": "1.7.0-beta.9", + "@nocobase/client": "1.7.0-beta.9", + "@nocobase/test": "1.7.0-beta.9", "@types/koa": "^2.15.0", "@types/koa-bodyparser": "^4.3.4", "@types/lodash": "^4.14.177", diff --git a/packages/core/evaluators/package.json b/packages/core/evaluators/package.json index 0be6afb515..87ab563ca3 100644 --- a/packages/core/evaluators/package.json +++ b/packages/core/evaluators/package.json @@ -1,13 +1,13 @@ { "name": "@nocobase/evaluators", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "main": "./lib/index.js", "types": "./lib/index.d.ts", "license": "AGPL-3.0", "dependencies": { "@formulajs/formulajs": "4.4.9", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/utils": "1.7.0-beta.9", "mathjs": "^10.6.0" }, "repository": { diff --git a/packages/core/lock-manager/package.json b/packages/core/lock-manager/package.json index 773a723536..40bec6a979 100644 --- a/packages/core/lock-manager/package.json +++ b/packages/core/lock-manager/package.json @@ -1,10 +1,10 @@ { "name": "@nocobase/lock-manager", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "lib/index.js", "license": "AGPL-3.0", "devDependencies": { - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/utils": "1.7.0-beta.9", "async-mutex": "^0.5.0" } } diff --git a/packages/core/logger/package.json b/packages/core/logger/package.json index c9914aaf2a..43bac59e8f 100644 --- a/packages/core/logger/package.json +++ b/packages/core/logger/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/logger", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "nocobase logging library", "license": "AGPL-3.0", "main": "./lib/index.js", diff --git a/packages/core/resourcer/package.json b/packages/core/resourcer/package.json index a2c3c1aec8..d391468d38 100644 --- a/packages/core/resourcer/package.json +++ b/packages/core/resourcer/package.json @@ -1,12 +1,12 @@ { "name": "@nocobase/resourcer", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "main": "./lib/index.js", "types": "./lib/index.d.ts", "license": "AGPL-3.0", "dependencies": { - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/utils": "1.7.0-beta.9", "deepmerge": "^4.2.2", "koa-compose": "^4.1.0", "lodash": "^4.17.21", diff --git a/packages/core/sdk/package.json b/packages/core/sdk/package.json index 0e29f67ccb..dbae1fe657 100644 --- a/packages/core/sdk/package.json +++ b/packages/core/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/sdk", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/core/server/package.json b/packages/core/server/package.json index c19e7e079f..6781c07eeb 100644 --- a/packages/core/server/package.json +++ b/packages/core/server/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/server", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "lib/index.js", "types": "./lib/index.d.ts", "license": "AGPL-3.0", @@ -10,19 +10,19 @@ "@koa/cors": "^5.0.0", "@koa/multer": "^3.0.2", "@koa/router": "^9.4.0", - "@nocobase/acl": "1.7.0-alpha.4", - "@nocobase/actions": "1.7.0-alpha.4", - "@nocobase/auth": "1.7.0-alpha.4", - "@nocobase/cache": "1.7.0-alpha.4", - "@nocobase/data-source-manager": "1.7.0-alpha.4", - "@nocobase/database": "1.7.0-alpha.4", - "@nocobase/evaluators": "1.7.0-alpha.4", - "@nocobase/lock-manager": "1.7.0-alpha.4", - "@nocobase/logger": "1.7.0-alpha.4", - "@nocobase/resourcer": "1.7.0-alpha.4", - "@nocobase/sdk": "1.7.0-alpha.4", - "@nocobase/telemetry": "1.7.0-alpha.4", - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/acl": "1.7.0-beta.9", + "@nocobase/actions": "1.7.0-beta.9", + "@nocobase/auth": "1.7.0-beta.9", + "@nocobase/cache": "1.7.0-beta.9", + "@nocobase/data-source-manager": "1.7.0-beta.9", + "@nocobase/database": "1.7.0-beta.9", + "@nocobase/evaluators": "1.7.0-beta.9", + "@nocobase/lock-manager": "1.7.0-beta.9", + "@nocobase/logger": "1.7.0-beta.9", + "@nocobase/resourcer": "1.7.0-beta.9", + "@nocobase/sdk": "1.7.0-beta.9", + "@nocobase/telemetry": "1.7.0-beta.9", + "@nocobase/utils": "1.7.0-beta.9", "@types/decompress": "4.2.7", "@types/ini": "^1.3.31", "@types/koa-send": "^4.1.3", diff --git a/packages/core/telemetry/package.json b/packages/core/telemetry/package.json index 67491b233b..fa906c5420 100644 --- a/packages/core/telemetry/package.json +++ b/packages/core/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/telemetry", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "nocobase telemetry library", "license": "AGPL-3.0", "main": "./lib/index.js", @@ -11,7 +11,7 @@ "directory": "packages/telemetry" }, "dependencies": { - "@nocobase/utils": "1.7.0-alpha.4", + "@nocobase/utils": "1.7.0-beta.9", "@opentelemetry/api": "^1.7.0", "@opentelemetry/instrumentation": "^0.46.0", "@opentelemetry/resources": "^1.19.0", diff --git a/packages/core/test/package.json b/packages/core/test/package.json index d27f7fd7fc..41d3559b66 100644 --- a/packages/core/test/package.json +++ b/packages/core/test/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/test", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "lib/index.js", "module": "./src/index.ts", "types": "./lib/index.d.ts", @@ -51,7 +51,7 @@ }, "dependencies": { "@faker-js/faker": "8.1.0", - "@nocobase/server": "1.7.0-alpha.4", + "@nocobase/server": "1.7.0-beta.9", "@playwright/test": "^1.45.3", "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.0.0", diff --git a/packages/core/utils/package.json b/packages/core/utils/package.json index a54d57af8e..4232d4d795 100644 --- a/packages/core/utils/package.json +++ b/packages/core/utils/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/utils", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "lib/index.js", "types": "./lib/index.d.ts", "license": "AGPL-3.0", diff --git a/packages/core/utils/src/__tests__/transformMultiColumnToSingleColumn.test.ts b/packages/core/utils/src/__tests__/transformMultiColumnToSingleColumn.test.ts index 2d6a550437..84c3032177 100644 --- a/packages/core/utils/src/__tests__/transformMultiColumnToSingleColumn.test.ts +++ b/packages/core/utils/src/__tests__/transformMultiColumnToSingleColumn.test.ts @@ -37,7 +37,7 @@ vi.mock('@formily/json-schema', () => { const result = { ...schema, parent }; result._isJSONSchemaObject = true; return result; - }) + }), }; }); @@ -261,26 +261,26 @@ describe('transformMultiColumnToSingleColumn', () => { name: 'grid1', 'x-component': 'Grid', properties: { - row1: { - 'x-component': 'Grid.Row', - properties: { - col1: { 'x-component': 'Input' }, - col2: { 'x-component': 'Select' }, + row1: { + 'x-component': 'Grid.Row', + properties: { + col1: { 'x-component': 'Input' }, + col2: { 'x-component': 'Select' }, + }, }, }, - }, parent: { - properties: { - grid1: {} // Will be replaced by result - } + properties: { + grid1: {}, // Will be replaced by result + }, }, - toJSON: vi.fn().mockImplementation(function() { - return { - name: this.name, - 'x-component': this['x-component'], - properties: this.properties - }; - }) + toJSON: vi.fn().mockImplementation(function () { + return { + name: this.name, + 'x-component': this['x-component'], + properties: this.properties, + }; + }), }; const result = transformMultiColumnToSingleColumn(mockSchema); diff --git a/packages/plugins/@nocobase/plugin-acl/package.json b/packages/plugins/@nocobase/plugin-acl/package.json index 53c0f55020..066d83863b 100644 --- a/packages/plugins/@nocobase/plugin-acl/package.json +++ b/packages/plugins/@nocobase/plugin-acl/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "权限控制", "description": "Based on roles, resources, and actions, access control can precisely manage interface configuration permissions, data operation permissions, menu access permissions, and plugin permissions.", "description.zh-CN": "基于角色、资源和操作的权限控制,可以精确控制界面配置权限、数据操作权限、菜单访问权限、插件权限。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/acl", diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx index 7ebeb8eb0e..5839ba0bf1 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx @@ -276,41 +276,43 @@ export const MenuPermissions: React.FC<{ expandable={{ defaultExpandAllRows: false, }} - columns={[ - { - dataIndex: 'title', - title: t('Route name'), - }, - { - dataIndex: 'accessible', - title: ( - <> - { - if (allChecked) { - await resource.set({ - values: [], - }); - } else { - await resource.set({ - values: allIDList, - }); - } - refresh(); - refreshDesktopRoutes(); - message.success(t('Saved successfully')); - }} - />{' '} - {t('Accessible')} - - ), - render: (_, schema) => { - const checked = IDList.includes(schema.id); - return handleChange(checked, schema)} />; + columns={ + [ + { + dataIndex: 'title', + title: t('Route name'), }, - }, - ] as TableProps['columns']} + { + dataIndex: 'accessible', + title: ( + <> + { + if (allChecked) { + await resource.set({ + values: [], + }); + } else { + await resource.set({ + values: allIDList, + }); + } + refresh(); + refreshDesktopRoutes(); + message.success(t('Saved successfully')); + }} + />{' '} + {t('Accessible')} + + ), + render: (_, schema) => { + const checked = IDList.includes(schema.id); + return handleChange(checked, schema)} />; + }, + }, + ] as TableProps['columns'] + } dataSource={translateTitle(items, t, compile)} /> diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx index 3f82d86fed..2bc3e36afc 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx @@ -113,44 +113,46 @@ export const PluginPermissions: React.FC<{ expandable={{ defaultExpandAllRows: true, }} - columns={[ - { - dataIndex: 'title', - title: t('Plugin name'), - render: (value) => { - return compile(value); + columns={ + [ + { + dataIndex: 'title', + title: t('Plugin name'), + render: (value) => { + return compile(value); + }, }, - }, - { - dataIndex: 'accessible', - title: ( - <> - { - const values = allAclSnippets.map((v) => '!' + v); - if (!allChecked) { - await resource.remove({ - values, - }); - } else { - await resource.add({ - values, - }); - } - refresh(); - message.success(t('Saved successfully')); - }} - /> - {t('Accessible')} - - ), - render: (_, record) => { - const checked = !snippets.includes('!' + record.aclSnippet); - return handleChange(checked, record)} />; + { + dataIndex: 'accessible', + title: ( + <> + { + const values = allAclSnippets.map((v) => '!' + v); + if (!allChecked) { + await resource.remove({ + values, + }); + } else { + await resource.add({ + values, + }); + } + refresh(); + message.success(t('Saved successfully')); + }} + /> + {t('Accessible')} + + ), + render: (_, record) => { + const checked = !snippets.includes('!' + record.aclSnippet); + return handleChange(checked, record)} />; + }, }, - }, - ] as TableProps['columns']} + ] as TableProps['columns'] + } dataSource={settings .filter((v) => { return v.isTopLevel !== false; diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/RolesResourcesActions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/RolesResourcesActions.tsx index fa0d405df9..1cb918849a 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/RolesResourcesActions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/RolesResourcesActions.tsx @@ -106,48 +106,50 @@ export const RolesResourcesActions = connect((props) => { className={styles} size={'small'} pagination={false} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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); + columns={ + [ + { + dataIndex: 'displayName', + title: t('Action display name'), + render: (value) => 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); }} /> ), - }, - ] as TableProps['columns']} + }, + { + dataIndex: 'scope', + title: t('Data scope'), + render: (value, action) => + !action.onNewRecord && ( + { + setScope(action.name, scope); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let enabled = false; let scope = null; @@ -170,60 +172,62 @@ export const RolesResourcesActions = connect((props) => { className={styles} pagination={false} dataSource={fieldPermissions} - columns={[ - { - dataIndex: ['uiSchema', 'title'], - title: t('Field display name'), - render: (value) => compile(value), - }, - ...availableActionsWithFields.map((action) => { - const checked = allChecked?.[action.name]; - return { - dataIndex: action.name, - title: ( - <> + columns={ + [ + { + dataIndex: ['uiSchema', 'title'], + title: t('Field display name'), + render: (value) => 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) { - item.fields = []; + const index = fields.indexOf(field.name); + fields.splice(index, 1); } else { - item.fields = collectionFields?.map?.((item) => item.name); + fields.push(field.name); } + item.fields = fields; 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)); - }} - /> - ), - }; - }), - ] as TableProps['columns']} + /> + ), + }; + }), + ] as TableProps['columns'] + } /> diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/StrategyActions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/StrategyActions.tsx index 77aa2f9152..4d10b71e22 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/StrategyActions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/StrategyActions.tsx @@ -55,62 +55,64 @@ export const StrategyActions = connect((props) => { rowKey={'name'} size={'small'} pagination={false} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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) => ( - { - if (enabled) { - delete scopes[action.name]; - } else { - scopes[action.name] = 'all'; - } - onChange(toFieldValue(scopes)); - }} - /> - ), - }, - { - dataIndex: 'scope', - title: t('Data scope'), - render: (scope, action) => - !action.onNewRecord && ( - { + scopes[action.name] = value; + onChange(toFieldValue(scopes)); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let scope = 'all'; let enabled = false; diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/package.json b/packages/plugins/@nocobase/plugin-action-bulk-edit/package.json index fc0b091be2..8df016986d 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/package.json +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-action-bulk-edit", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-bulk-edit", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-edit", diff --git a/packages/plugins/@nocobase/plugin-action-bulk-update/package.json b/packages/plugins/@nocobase/plugin-action-bulk-update/package.json index 052ba81530..fdcc0108e6 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-update/package.json +++ b/packages/plugins/@nocobase/plugin-action-bulk-update/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-action-bulk-update", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-bulk-update", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-update", diff --git a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/BulkUpdateAction.Settings.tsx b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/BulkUpdateAction.Settings.tsx index f5016985f0..894faaaf7d 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/BulkUpdateAction.Settings.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/BulkUpdateAction.Settings.tsx @@ -8,7 +8,6 @@ */ import { ISchema, useFieldSchema } from '@formily/react'; -import { isValid } from '@formily/shared'; import { ActionDesigner, SchemaSettings, @@ -19,6 +18,8 @@ import { useDesignable, useSchemaToolbar, RefreshDataBlockRequest, + useAfterSuccessOptions, + useGlobalVariable, } from '@nocobase/client'; import { useTranslation } from 'react-i18next'; import React from 'react'; @@ -49,11 +50,22 @@ function UpdateMode() { /> ); } - +const fieldNames = { + value: 'value', + label: 'label', +}; +const useVariableProps = (environmentVariables) => { + const scope = useAfterSuccessOptions(); + return { + scope: [environmentVariables, ...scope].filter(Boolean), + fieldNames, + }; +}; function AfterSuccess() { const { dn } = useDesignable(); const { t } = useTranslation(); const fieldSchema = useFieldSchema(); + const environmentVariables = useGlobalVariable('$env'); return ( useVariableProps(environmentVariables), }, }, } as ISchema diff --git a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/utils.tsx b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/utils.tsx index 181ef1d2b3..ac7253f2d0 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/utils.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/utils.tsx @@ -68,7 +68,7 @@ export const useCustomizeBulkUpdateActionProps = () => { if (result) { assignedValues[key] = transformVariableValue(result, { targetCollectionField: collectionField }); } - } else if (value != null && value !== '') { + } else if (value !== '') { assignedValues[key] = value; } }); diff --git a/packages/plugins/@nocobase/plugin-action-custom-request/package.json b/packages/plugins/@nocobase/plugin-action-custom-request/package.json index 658ebf41b9..ec13e6ca6a 100644 --- a/packages/plugins/@nocobase/plugin-action-custom-request/package.json +++ b/packages/plugins/@nocobase/plugin-action-custom-request/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-action-custom-request", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-custom-request", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-custom-request", diff --git a/packages/plugins/@nocobase/plugin-action-custom-request/src/client/hooks/useCustomizeRequestActionProps.ts b/packages/plugins/@nocobase/plugin-action-custom-request/src/client/hooks/useCustomizeRequestActionProps.ts index 13e17c8378..a1580495e9 100644 --- a/packages/plugins/@nocobase/plugin-action-custom-request/src/client/hooks/useCustomizeRequestActionProps.ts +++ b/packages/plugins/@nocobase/plugin-action-custom-request/src/client/hooks/useCustomizeRequestActionProps.ts @@ -68,10 +68,13 @@ export const useCustomizeRequestActionProps = () => { responseType: fieldSchema['x-response-type'] === 'stream' ? 'blob' : 'json', }); if (res.headers['content-disposition']) { - const regex = /attachment;\s*filename="([^"]+)"/; - const match = res.headers['content-disposition'].match(regex); - if (match?.[1]) { - saveAs(res.data, match[1]); + const contentDisposition = res.headers['content-disposition']; + const utf8Match = contentDisposition.match(/filename\*=utf-8''([^;]+)/i); + const asciiMatch = contentDisposition.match(/filename="([^"]+)"/i); + if (utf8Match) { + saveAs(res.data, decodeURIComponent(utf8Match[1])); + } else if (asciiMatch) { + saveAs(res.data, asciiMatch[1]); } } actionField.data.loading = false; diff --git a/packages/plugins/@nocobase/plugin-action-duplicate/package.json b/packages/plugins/@nocobase/plugin-action-duplicate/package.json index ed12733afc..57d13611ee 100644 --- a/packages/plugins/@nocobase/plugin-action-duplicate/package.json +++ b/packages/plugins/@nocobase/plugin-action-duplicate/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-action-duplicate", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-duplicate", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-duplicate", diff --git a/packages/plugins/@nocobase/plugin-action-export/package.json b/packages/plugins/@nocobase/plugin-action-export/package.json index 702817031a..9d840b0bf5 100644 --- a/packages/plugins/@nocobase/plugin-action-export/package.json +++ b/packages/plugins/@nocobase/plugin-action-export/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "操作:导出记录", "description": "Export filtered records to excel, you can configure which fields to export.", "description.zh-CN": "导出筛选后的记录到 Excel 中,可以配置导出哪些字段。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-export", diff --git a/packages/plugins/@nocobase/plugin-action-import/package.json b/packages/plugins/@nocobase/plugin-action-import/package.json index 4f93275f50..1aa0aabc45 100644 --- a/packages/plugins/@nocobase/plugin-action-import/package.json +++ b/packages/plugins/@nocobase/plugin-action-import/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "操作:导入记录", "description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.", "description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-import", diff --git a/packages/plugins/@nocobase/plugin-action-import/src/client/ImportAction.tsx b/packages/plugins/@nocobase/plugin-action-import/src/client/ImportAction.tsx index 996f315e3e..4b18b009f0 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/client/ImportAction.tsx +++ b/packages/plugins/@nocobase/plugin-action-import/src/client/ImportAction.tsx @@ -12,6 +12,7 @@ import { ISchema, useFieldSchema } from '@formily/react'; import { Action, ActionContextProvider, PopupSettingsProvider, SchemaComponent, useCompile } from '@nocobase/client'; import React, { useState } from 'react'; import { NAMESPACE } from './constants'; +import { useTranslation } from 'react-i18next'; import { UploadOutlined } from '@ant-design/icons'; const importFormSchema: ISchema = { @@ -128,7 +129,7 @@ export const ImportAction = (props) => { return ( } + icon={props.icon || 'uploadoutlined'} title={compile(fieldSchema?.title || "t('Import')")} {...props} onClick={() => setVisible(true)} diff --git a/packages/plugins/@nocobase/plugin-action-print/package.json b/packages/plugins/@nocobase/plugin-action-print/package.json index 46764111db..e47c9bd80c 100644 --- a/packages/plugins/@nocobase/plugin-action-print/package.json +++ b/packages/plugins/@nocobase/plugin-action-print/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-action-print", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/action-print", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-print", diff --git a/packages/plugins/@nocobase/plugin-ai/package.json b/packages/plugins/@nocobase/plugin-ai/package.json index ee01d35ac2..32170b6e2f 100644 --- a/packages/plugins/@nocobase/plugin-ai/package.json +++ b/packages/plugins/@nocobase/plugin-ai/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "AI 集成", "description": "Support integration with AI services, providing AI-related workflow nodes to enhance business processing capabilities.", "description.zh-CN": "支持接入 AI 服务,提供 AI 相关的工作流节点,增强业务处理能力。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "peerDependencies": { "@nocobase/client": "1.x", diff --git a/packages/plugins/@nocobase/plugin-api-doc/package.json b/packages/plugins/@nocobase/plugin-api-doc/package.json index 551901edd6..eac364fb15 100644 --- a/packages/plugins/@nocobase/plugin-api-doc/package.json +++ b/packages/plugins/@nocobase/plugin-api-doc/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-api-doc", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "API documentation", "displayName.zh-CN": "API 文档", "description": "An OpenAPI documentation generator for NocoBase HTTP API.", diff --git a/packages/plugins/@nocobase/plugin-api-keys/package.json b/packages/plugins/@nocobase/plugin-api-keys/package.json index 526be5acd7..a867ff47bd 100644 --- a/packages/plugins/@nocobase/plugin-api-keys/package.json +++ b/packages/plugins/@nocobase/plugin-api-keys/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "认证:API 密钥", "description": "Allows users to use API key to access application's HTTP API", "description.zh-CN": "允许用户使用 API 密钥访问应用的 HTTP API", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/api-keys", diff --git a/packages/plugins/@nocobase/plugin-async-task-manager/package.json b/packages/plugins/@nocobase/plugin-async-task-manager/package.json index 111528c3a8..c72954469d 100644 --- a/packages/plugins/@nocobase/plugin-async-task-manager/package.json +++ b/packages/plugins/@nocobase/plugin-async-task-manager/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "异步任务管理器", "description": "Manage and monitor asynchronous tasks such as data import/export. Support task progress tracking and notification.", "description.zh-CN": "管理和监控数据导入导出等异步任务。支持任务进度跟踪和通知。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "peerDependencies": { "@nocobase/client": "1.x", diff --git a/packages/plugins/@nocobase/plugin-audit-logs/package.json b/packages/plugins/@nocobase/plugin-audit-logs/package.json index 3f9f7cc32a..7480d9bc8d 100644 --- a/packages/plugins/@nocobase/plugin-audit-logs/package.json +++ b/packages/plugins/@nocobase/plugin-audit-logs/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-audit-logs", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Audit logs (deprecated)", "displayName.zh-CN": "审计日志(废弃)", "description": "This plugin is deprecated. There will be a new audit log plugin in the future.", diff --git a/packages/plugins/@nocobase/plugin-auth-sms/package.json b/packages/plugins/@nocobase/plugin-auth-sms/package.json index c8d4dd0354..2b312b813b 100644 --- a/packages/plugins/@nocobase/plugin-auth-sms/package.json +++ b/packages/plugins/@nocobase/plugin-auth-sms/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "认证:短信", "description": "SMS authentication.", "description.zh-CN": "通过短信验证码认证身份。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/auth-sms", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth-sms", diff --git a/packages/plugins/@nocobase/plugin-auth/package.json b/packages/plugins/@nocobase/plugin-auth/package.json index f74e88e9f7..55ab41248b 100644 --- a/packages/plugins/@nocobase/plugin-auth/package.json +++ b/packages/plugins/@nocobase/plugin-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-auth", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/auth", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth", diff --git a/packages/plugins/@nocobase/plugin-backup-restore/package.json b/packages/plugins/@nocobase/plugin-backup-restore/package.json index 12d254b7f6..0f416d822c 100644 --- a/packages/plugins/@nocobase/plugin-backup-restore/package.json +++ b/packages/plugins/@nocobase/plugin-backup-restore/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "应用的备份与还原(废弃)", "description": "Backup and restore applications for scenarios such as application replication, migration, and upgrades.", "description.zh-CN": "备份和还原应用,可用于应用的复制、迁移、升级等场景。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/backup-restore", diff --git a/packages/plugins/@nocobase/plugin-backup-restore/src/client/Configuration.tsx b/packages/plugins/@nocobase/plugin-backup-restore/src/client/Configuration.tsx index 4dace132ba..140a6e27ba 100644 --- a/packages/plugins/@nocobase/plugin-backup-restore/src/client/Configuration.tsx +++ b/packages/plugins/@nocobase/plugin-backup-restore/src/client/Configuration.tsx @@ -111,11 +111,11 @@ const LearnMore: any = (props: { collectionsData?: any; isBackup?: boolean }) => render: (_, data) => { const title = compile(data.title); const name = data.name; - return name === title ? title : ( + return name === title ? ( + title + ) : (
- {data.name} - {' '} - ({compile(data.title)}) + {data.name} ({compile(data.title)})
); }, @@ -418,73 +418,75 @@ export const BackupAndRestoreList = () => { { - return data.inProgress - ? { - colSpan: 4, - } - : {}; + columns={ + [ + { + title: t('Backup file'), + dataIndex: 'name', + width: 400, + onCell: (data) => { + return data.inProgress + ? { + colSpan: 4, + } + : {}; + }, + render: (name, data) => + data.inProgress ? ( +
+ {name}({t('Backing up')}...) +
+ ) : ( +
{name}
+ ), }, - render: (name, data) => - data.inProgress ? ( -
- {name}({t('Backing up')}...) -
- ) : ( -
{name}
+ { + title: t('File size'), + dataIndex: 'fileSize', + onCell: (data) => { + return data.inProgress + ? { + colSpan: 0, + } + : {}; + }, + }, + { + title: t('Created at', { ns: 'client' }), + dataIndex: 'createdAt', + onCell: (data) => { + return data.inProgress + ? { + colSpan: 0, + } + : {}; + }, + render: (value) => { + return ; + }, + }, + { + title: t('Actions', { ns: 'client' }), + dataIndex: 'actions', + onCell: (data) => { + return data.inProgress + ? { + colSpan: 0, + } + : {}; + }, + render: (_, record) => ( + }> + + handleDownload(record)}> + {t('Download')} + + handleDestory(record)}>{t('Delete')} + ), - }, - { - title: t('File size'), - dataIndex: 'fileSize', - onCell: (data) => { - return data.inProgress - ? { - colSpan: 0, - } - : {}; }, - }, - { - title: t('Created at', { ns: 'client' }), - dataIndex: 'createdAt', - onCell: (data) => { - return data.inProgress - ? { - colSpan: 0, - } - : {}; - }, - render: (value) => { - return ; - }, - }, - { - title: t('Actions', { ns: 'client' }), - dataIndex: 'actions', - onCell: (data) => { - return data.inProgress - ? { - colSpan: 0, - } - : {}; - }, - render: (_, record) => ( - }> - - handleDownload(record)}> - {t('Download')} - - handleDestory(record)}>{t('Delete')} - - ), - }, - ] as TableProps['columns']} + ] as TableProps['columns'] + } /> diff --git a/packages/plugins/@nocobase/plugin-block-iframe/package.json b/packages/plugins/@nocobase/plugin-block-iframe/package.json index b390b6ddab..366944d5c7 100644 --- a/packages/plugins/@nocobase/plugin-block-iframe/package.json +++ b/packages/plugins/@nocobase/plugin-block-iframe/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "区块:iframe", "description": "Create an iframe block on the page to embed and display external web pages or content.", "description.zh-CN": "在页面上创建和管理iframe,用于嵌入和展示外部网页或内容。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/block-iframe", diff --git a/packages/plugins/@nocobase/plugin-block-template/package.json b/packages/plugins/@nocobase/plugin-block-template/package.json index 7bb88737c6..7c61440ad4 100644 --- a/packages/plugins/@nocobase/plugin-block-template/package.json +++ b/packages/plugins/@nocobase/plugin-block-template/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "区块:模板", "description": "Create and manage block templates for reuse on pages.", "description.zh-CN": "创建和管理区块模板,用于在页面中重复使用。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/block-template", diff --git a/packages/plugins/@nocobase/plugin-block-template/src/client/components/SaveAsTemplateSetting.tsx b/packages/plugins/@nocobase/plugin-block-template/src/client/components/SaveAsTemplateSetting.tsx index ac44f2172d..3e50a94d78 100644 --- a/packages/plugins/@nocobase/plugin-block-template/src/client/components/SaveAsTemplateSetting.tsx +++ b/packages/plugins/@nocobase/plugin-block-template/src/client/components/SaveAsTemplateSetting.tsx @@ -23,7 +23,7 @@ import { useLocation } from 'react-router-dom'; const blockDecoratorMenuMaps = { TableBlockProvider: ['Table', 'table'], - FormBlockProvider: ['Form', 'form'], + FormBlockProvider: ['FormItem', 'form'], DetailsBlockProvider: ['Details', 'details'], 'List.Decorator': ['List', 'list'], 'GridCard.Decorator': ['GridCard', 'gridCard'], @@ -281,6 +281,7 @@ function getTemplateSchemaFromPage(schema: ISchema) { if (s['x-template-root-uid']) { return; } + t = t || {}; _.merge(t, _.omit(s, ['x-uid', 'properties'])); t['x-uid'] = uid(); if (s.properties) { @@ -288,7 +289,7 @@ function getTemplateSchemaFromPage(schema: ISchema) { if (s.properties[key]['x-template-root-uid']) { continue; } - _.set(t, `properties.${key}`, {}); + _.set(t, `properties.['${key}']`, {}); traverseSchema(s.properties[key], t.properties[key]); } } diff --git a/packages/plugins/@nocobase/plugin-block-template/src/client/index.tsx b/packages/plugins/@nocobase/plugin-block-template/src/client/index.tsx index 8dc644ee76..767779246f 100644 --- a/packages/plugins/@nocobase/plugin-block-template/src/client/index.tsx +++ b/packages/plugins/@nocobase/plugin-block-template/src/client/index.tsx @@ -169,6 +169,9 @@ export class PluginBlockTemplateClient extends Plugin { 'blockSettings:createForm', 'blockSettings:details', 'blockSettings:detailsWithPagination', + 'blockSettings:multiDataDetails', + 'blockSettings:singleDataDetails', + 'blockSettings:stepsForm', 'blockSettings:filterCollapse', 'blockSettings:filterForm', 'blockSettings:gantt', @@ -176,6 +179,13 @@ export class PluginBlockTemplateClient extends Plugin { 'blockSettings:kanban', 'blockSettings:list', 'blockSettings:table', + 'blockSettings:tree', + 'ReadPrettyFormSettings', + 'GanttBlockSettings', + 'FormV1Settings', + 'FormSettings', + 'FormItemSettings', + 'FormDetailsSettings', ]; if (blockSettings.includes(key)) { // schemaSetting.add('template-saveAsTemplateItem', saveAsTemplateSetting); diff --git a/packages/plugins/@nocobase/plugin-block-template/src/client/initializers/TemplateBlockInitializer.tsx b/packages/plugins/@nocobase/plugin-block-template/src/client/initializers/TemplateBlockInitializer.tsx index 50c9e6ec8c..2a9808cd39 100644 --- a/packages/plugins/@nocobase/plugin-block-template/src/client/initializers/TemplateBlockInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-block-template/src/client/initializers/TemplateBlockInitializer.tsx @@ -43,6 +43,10 @@ export function convertTplBlock( if (newSchema['x-decorator'] === 'TemplateGridDecorator') { delete newSchema['x-decorator']; } + if (newSchema['x-linkage-rules']) { + // linkage rules 有可能保存在Grid组件中 + delete newSchema['x-linkage-rules']; + } for (const key in tpl.properties) { const t = convertTplBlock(tpl.properties[key], virtual, isRoot, newRootId, templateKey, options); if (isRoot) { @@ -154,8 +158,12 @@ export function formSchemaPatch(currentSchema: ISchema, options?: any) { return key !== 'grid'; }); if (actionKey) { - _.set(currentSchema, `properties.${comKey}.x-use-component-props`, 'useEditFormBlockProps'); - _.set(currentSchema, `properties.${comKey}.properties.${actionKey}.x-initializer`, 'editForm:configureActions'); + _.set(currentSchema, `properties.['${comKey}'].x-use-component-props`, 'useEditFormBlockProps'); + _.set( + currentSchema, + `properties.['${comKey}'].properties.['${actionKey}'].x-initializer`, + 'editForm:configureActions', + ); const actionBarSchema = _.get(currentSchema, `properties.${comKey}.properties.${actionKey}.properties`, {}); for (const key in actionBarSchema) { diff --git a/packages/plugins/@nocobase/plugin-block-workbench/package.json b/packages/plugins/@nocobase/plugin-block-workbench/package.json index 029d6c8890..4e53982d26 100644 --- a/packages/plugins/@nocobase/plugin-block-workbench/package.json +++ b/packages/plugins/@nocobase/plugin-block-workbench/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-block-workbench", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Block: Action panel", "displayName.zh-CN": "区块:操作面板", "description": "Centrally manages and displays various actions, allowing users to efficiently perform tasks. It supports extensibility, with current action types including pop-ups, links, scanning, and custom requests.", diff --git a/packages/plugins/@nocobase/plugin-calendar/package.json b/packages/plugins/@nocobase/plugin-calendar/package.json index ea6cacabf4..d2791430a7 100644 --- a/packages/plugins/@nocobase/plugin-calendar/package.json +++ b/packages/plugins/@nocobase/plugin-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-calendar", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Calendar", "displayName.zh-CN": "日历", "description": "Provides callendar collection template and block for managing date data, typically for date/time related information such as events, appointments, tasks, and so on.", diff --git a/packages/plugins/@nocobase/plugin-charts/package.json b/packages/plugins/@nocobase/plugin-charts/package.json index ef09305209..9867a3d5d1 100644 --- a/packages/plugins/@nocobase/plugin-charts/package.json +++ b/packages/plugins/@nocobase/plugin-charts/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "图表(废弃)", "description": "The plugin has been deprecated, please use the data visualization plugin instead.", "description.zh-CN": "已废弃插件,请使用数据可视化插件代替。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "license": "AGPL-3.0", "devDependencies": { diff --git a/packages/plugins/@nocobase/plugin-client/package.json b/packages/plugins/@nocobase/plugin-client/package.json index 301c4d7d60..e5933dd0ac 100644 --- a/packages/plugins/@nocobase/plugin-client/package.json +++ b/packages/plugins/@nocobase/plugin-client/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "WEB 客户端", "description": "Provides a client interface for the NocoBase server", "description.zh-CN": "为 NocoBase 服务端提供客户端界面", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "license": "AGPL-3.0", "devDependencies": { diff --git a/packages/plugins/@nocobase/plugin-collection-sql/package.json b/packages/plugins/@nocobase/plugin-collection-sql/package.json index 413cc0bdbb..c7cdb9e47e 100644 --- a/packages/plugins/@nocobase/plugin-collection-sql/package.json +++ b/packages/plugins/@nocobase/plugin-collection-sql/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "数据表: SQL", "description": "Provides SQL collection template", "description.zh-CN": "提供 SQL 数据表模板", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "homepage": "https://docs-cn.nocobase.com/handbook/collection-sql", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/collection-sql", "main": "dist/server/index.js", diff --git a/packages/plugins/@nocobase/plugin-collection-tree/package.json b/packages/plugins/@nocobase/plugin-collection-tree/package.json index 6fd1c1f86a..899485bdaa 100644 --- a/packages/plugins/@nocobase/plugin-collection-tree/package.json +++ b/packages/plugins/@nocobase/plugin-collection-tree/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-collection-tree", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Collection: Tree", "displayName.zh-CN": "数据表:树", "description": "Provides tree collection template", diff --git a/packages/plugins/@nocobase/plugin-collection-tree/src/server/migrations/20240802141435-collection-tree.ts b/packages/plugins/@nocobase/plugin-collection-tree/src/server/migrations/20240802141435-collection-tree.ts index 61772f45ab..27def98812 100644 --- a/packages/plugins/@nocobase/plugin-collection-tree/src/server/migrations/20240802141435-collection-tree.ts +++ b/packages/plugins/@nocobase/plugin-collection-tree/src/server/migrations/20240802141435-collection-tree.ts @@ -31,6 +31,8 @@ export default class extends Migration { await this.db.sequelize.transaction(async (transaction) => { const treeCollections = await this.getTreeCollections({ transaction }); for (const treeCollection of treeCollections) { + await treeCollection.load({ transaction }); + const name = `main_${treeCollection.name}_path`; const collectionOptions = { name, @@ -47,35 +49,16 @@ export default class extends Migration { }, ], }; - const collectionInstance = this.db.getCollection(treeCollection.name); const treeCollectionSchema = collectionInstance.collectionSchema(); - if (this.app.db.inDialect('postgres') && treeCollectionSchema != this.app.db.options.schema) { collectionOptions['schema'] = treeCollectionSchema; } - this.app.db.collection(collectionOptions); const treeExistsInDb = await this.app.db.getCollection(name).existsInDb({ transaction }); - if (!treeExistsInDb) { await this.app.db.getCollection(name).sync({ transaction } as SyncOptions); - const opts = { - name: treeCollection.name, - autoGenId: false, - timestamps: false, - fields: [ - { type: 'integer', name: 'id' }, - { type: 'integer', name: 'parentId' }, - ], - }; - - if (treeCollectionSchema != this.app.db.options.schema) { - opts['schema'] = treeCollectionSchema; - } - - this.app.db.collection(opts); const chunkSize = 1000; await this.app.db.getRepository(treeCollection.name).chunk({ chunkSize: chunkSize, diff --git a/packages/plugins/@nocobase/plugin-data-source-main/package.json b/packages/plugins/@nocobase/plugin-data-source-main/package.json index 39bbed6ac7..de97fc31a0 100644 --- a/packages/plugins/@nocobase/plugin-data-source-main/package.json +++ b/packages/plugins/@nocobase/plugin-data-source-main/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "数据源:主数据库", "description": "NocoBase main database, supports relational databases such as PostgreSQL, MySQL, MariaDB and so on.", "description.zh-CN": "NocoBase 主数据库,支持 PostgreSQL、MySQL、MariaDB 等关系型数据库。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/data-source-main", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/data-source-main", diff --git a/packages/plugins/@nocobase/plugin-data-source-manager/package.json b/packages/plugins/@nocobase/plugin-data-source-manager/package.json index 68ac339b82..b622fe377a 100644 --- a/packages/plugins/@nocobase/plugin-data-source-manager/package.json +++ b/packages/plugins/@nocobase/plugin-data-source-manager/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-data-source-manager", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "displayName": "Data source manager", "displayName.zh-CN": "数据源管理", diff --git a/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/RolesResourcesActions.tsx b/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/RolesResourcesActions.tsx index 67f661d7f5..b2f7c23746 100644 --- a/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/RolesResourcesActions.tsx +++ b/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/RolesResourcesActions.tsx @@ -101,48 +101,50 @@ export const RolesResourcesActions = connect((props) => { className={styles} size={'small'} pagination={false} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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); + columns={ + [ + { + dataIndex: 'displayName', + title: t('Action display name'), + render: (value) => 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); }} /> ), - }, - ] as TableProps['columns']} + }, + { + dataIndex: 'scope', + title: t('Data scope'), + render: (value, action) => + !action.onNewRecord && ( + { + setScope(action.name, scope); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let enabled = false; let scope = null; @@ -165,59 +167,61 @@ export const RolesResourcesActions = connect((props) => { className={styles} pagination={false} dataSource={fieldPermissions} - columns={[ - { - dataIndex: ['uiSchema', 'title'], - title: t('Field display name'), - render: (value, record) => compile(value) || record.name, - }, - ...availableActionsWithFields.map((action) => { - const checked = allChecked?.[action.name]; - return { - dataIndex: action.name, - title: ( - <> + columns={ + [ + { + dataIndex: ['uiSchema', 'title'], + title: t('Field display name'), + render: (value, record) => compile(value) || record.name, + }, + ...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) { - item.fields = []; + const index = fields.indexOf(field.name); + fields.splice(index, 1); } else { - item.fields = collectionFields?.map?.((item) => item.name); + fields.push(field.name); } + item.fields = fields; 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)); - }} - /> - ), - }; - }), - ] as TableProps['columns']} + ), + }; + }), + ] as TableProps['columns'] + } /> diff --git a/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/StrategyActions.tsx b/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/StrategyActions.tsx index 42c105603b..642e80bfc0 100644 --- a/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/StrategyActions.tsx +++ b/packages/plugins/@nocobase/plugin-data-source-manager/src/client/component/PermissionManager/StrategyActions.tsx @@ -56,61 +56,63 @@ export const StrategyActions = connect((props) => { size={'small'} pagination={false} rowKey={'name'} - columns={[ - { - dataIndex: 'displayName', - title: t('Action display name'), - render: (value) => 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) => ( - { - if (enabled) { - delete scopes[action.name]; - } else { - scopes[action.name] = 'all'; - } - onChange(toFieldValue(scopes)); - }} - /> - ), - }, - { - dataIndex: 'scope', - title: t('Data scope'), - render: (scope, action) => - !action.onNewRecord && ( - { + scopes[action.name] = value; + onChange(toFieldValue(scopes)); + }} + /> + ), + }, + ] as TableProps['columns'] + } dataSource={availableActions?.map((item) => { let scope = 'all'; let enabled = false; diff --git a/packages/plugins/@nocobase/plugin-data-visualization/package.json b/packages/plugins/@nocobase/plugin-data-visualization/package.json index 1279d5a279..a375415cd5 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/package.json +++ b/packages/plugins/@nocobase/plugin-data-visualization/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-data-visualization", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Data visualization", "displayName.zh-CN": "数据可视化", "description": "Provides data visualization feature, including chart block and chart filter block, support line charts, area charts, bar charts and more than a dozen kinds of charts, you can also extend more chart types.", diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/CardItem.tsx b/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/CardItem.tsx index c7c53dcd00..cdcfccd91f 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/CardItem.tsx +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/CardItem.tsx @@ -17,7 +17,10 @@ export const ChartCardItem = withDynamicSchemaProps( const { token } = useToken(); const filedSchema = useFieldSchema(); const { isMobileLayout } = useMobileLayout(); - const schema = useMemo(() => isMobileLayout ? transformMultiColumnToSingleColumn(filedSchema, isAntdStatistic) : filedSchema, [isMobileLayout, filedSchema]); + const schema = useMemo( + () => (isMobileLayout ? transformMultiColumnToSingleColumn(filedSchema, isAntdStatistic) : filedSchema), + [isMobileLayout, filedSchema], + ); return ( { expect(content.text.includes('Hello world!')).toBe(true); }); + it('path with heading or tailing slash', async () => { + const BASE_URL = `/storage/uploads/another`; + const urlPath = 'test/path'; + + // 动态添加 storage + const storage = await StorageRepo.create({ + values: { + name: 'local_private', + type: STORAGE_TYPE_LOCAL, + rules: { + mimetype: ['text/*'], + }, + path: `/${urlPath}//`, + baseUrl: BASE_URL, + options: { + documentRoot: 'storage/uploads/another', + }, + }, + }); + + db.collection({ + name: 'customers', + fields: [ + { + name: 'file', + type: 'belongsTo', + target: 'attachments', + storage: storage.name, + }, + ], + }); + + const { body } = await agent.resource('attachments').create({ + attachmentField: 'customers.file', + file: path.resolve(__dirname, './files/text.txt'), + }); + + // 文件的 url 是否正常生成 + expect(body.data.url).toBe(`${BASE_URL}/${urlPath}/${body.data.filename}`); + const url = body.data.url.replace(`http://localhost:${APP_PORT}`, ''); + const content = await agent.get(url); + expect(content.text.includes('Hello world!')).toBe(true); + }); + it('path longer than 255', async () => { const BASE_URL = `/storage/uploads/another`; const urlPath = diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/server/actions/attachments.ts b/packages/plugins/@nocobase/plugin-file-manager/src/server/actions/attachments.ts index e21544fd43..b84c5175f1 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/server/actions/attachments.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/server/actions/attachments.ts @@ -28,43 +28,6 @@ function getFileFilter(storage) { }; } -export async function getFileData(ctx: Context) { - const { [FILE_FIELD_NAME]: file, storage } = ctx; - if (!file) { - return ctx.throw(400, 'file validation failed'); - } - - const plugin = ctx.app.pm.get(Plugin); - const StorageType = plugin.storageTypes.get(storage.type) as StorageClassType; - const { [StorageType.filenameKey || 'filename']: name } = file; - // make compatible filename across cloud service (with path) - const filename = Path.basename(name); - const extname = Path.extname(filename); - const path = (storage.path || '').replace(/^\/|\/$/g, ''); - - let storageInstance = plugin.storagesCache.get(storage.id); - - if (!storageInstance) { - await plugin.loadStorages(); - storageInstance = plugin.storagesCache.get(storage.id); - } - - const data = { - title: Buffer.from(file.originalname, 'latin1').toString('utf8').replace(extname, ''), - filename, - extname, - // TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path - path, - size: file.size, - mimetype: file.mimetype, - meta: ctx.request.body, - storageId: storage.id, - ...StorageType?.['getFileData']?.(file), - }; - - return data; -} - async function multipart(ctx: Context, next: Next) { const { storage } = ctx; if (!storage) { @@ -101,7 +64,12 @@ async function multipart(ctx: Context, next: Next) { return ctx.throw(500, err); } - const values = await getFileData(ctx); + const { [FILE_FIELD_NAME]: file } = ctx; + if (!file) { + return ctx.throw(400, 'file validation failed'); + } + + const values = storageInstance.getFileData(file, ctx.request.body); ctx.action.mergeParams({ values, @@ -119,12 +87,10 @@ export async function createMiddleware(ctx: Context, next: Next) { return next(); } + const plugin = ctx.app.pm.get(Plugin) as Plugin; const storageName = ctx.db.getFieldByPath(attachmentField)?.options?.storage || collection.options.storage; - const StorageRepo = ctx.db.getRepository('storages'); - const storage = await StorageRepo.findOne({ filter: storageName ? { name: storageName } : { default: true } }); - - const plugin = ctx.app.pm.get(Plugin); - ctx.storage = plugin.parseStorage(storage); + const storages = Array.from(plugin.storagesCache.values()); + ctx.storage = storages.find((item) => item.name === storageName) || storages.find((item) => item.default); if (ctx?.request.is('multipart/*')) { await multipart(ctx, next); diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/server/server.ts b/packages/plugins/@nocobase/plugin-file-manager/src/server/server.ts index a5dc7f2a30..aaef4c1e79 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/server/server.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/server/server.ts @@ -7,18 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { basename } from 'path'; +import fs from 'fs'; + import { Plugin } from '@nocobase/server'; import { isURL, Registry } from '@nocobase/utils'; - -import { basename } from 'path'; - import { Collection, Model, Transactionable } from '@nocobase/database'; -import fs from 'fs'; import { STORAGE_TYPE_ALI_OSS, STORAGE_TYPE_LOCAL, STORAGE_TYPE_S3, STORAGE_TYPE_TX_COS } from '../constants'; import initActions from './actions'; -import { getFileData } from './actions/attachments'; import { AttachmentInterface } from './interfaces/attachment-interface'; -import { AttachmentModel, StorageClassType, StorageModel, StorageType } from './storages'; +import { AttachmentModel, StorageClassType, StorageModel } from './storages'; import StorageTypeAliOss from './storages/ali-oss'; import StorageTypeLocal from './storages/local'; import StorageTypeS3 from './storages/s3'; @@ -106,39 +104,31 @@ export class PluginFileManagerServer extends Plugin { async uploadFile(options: UploadFileOptions) { const { storageName, filePath, documentRoot } = options; - const storageRepository = this.db.getRepository('storages'); - let storageInstance; - storageInstance = await storageRepository.findOne({ - filter: storageName - ? { - name: storageName, - } - : { - default: true, - }, - }); + if (!this.storagesCache.size) { + await this.loadStorages(); + } + const storages = Array.from(this.storagesCache.values()); + const storage = storages.find((item) => item.name === storageName) || storages.find((item) => item.default); - const fileStream = fs.createReadStream(filePath); - - if (!storageInstance) { + if (!storage) { throw new Error('[file-manager] no linked or default storage provided'); } - storageInstance = this.parseStorage(storageInstance); + const fileStream = fs.createReadStream(filePath); if (documentRoot) { - storageInstance.options['documentRoot'] = documentRoot; + storage.options['documentRoot'] = documentRoot; } - const storageType = this.storageTypes.get(storageInstance.type); - const storage = new storageType(storageInstance); + const StorageType = this.storageTypes.get(storage.type); + const storageInstance = new StorageType(storage); - if (!storage) { - throw new Error(`[file-manager] storage type "${storageInstance.type}" is not defined`); + if (!storageInstance) { + throw new Error(`[file-manager] storage type "${storage.type}" is not defined`); } - const engine = storage.make(); + const engine = storageInstance.make(); const file = { originalname: basename(filePath), @@ -156,7 +146,7 @@ export class PluginFileManagerServer extends Plugin { }); }); - return getFileData({ app: this.app, file, storage: storageInstance, request: { body: {} } } as any); + return storageInstance.getFileData(file, {}); } async loadStorages(options?: { transaction: any }) { @@ -195,17 +185,8 @@ export class PluginFileManagerServer extends Plugin { } async handleSyncMessage(message) { - if (message.type === 'storageChange') { - const storage = await this.db.getRepository('storages').findOne({ - filterByTk: message.storageId, - }); - if (storage) { - this.storagesCache.set(storage.id, this.parseStorage(storage)); - } - } - if (message.type === 'storageRemove') { - const id = message.storageId; - this.storagesCache.delete(id); + if (message.type === 'reloadStorages') { + await this.loadStorages(); } } @@ -244,17 +225,11 @@ export class PluginFileManagerServer extends Plugin { this.storageTypes.register(STORAGE_TYPE_TX_COS, StorageTypeTxCos); const Storage = this.db.getModel('storages'); - Storage.afterSave((m, { transaction }) => { - this.storagesCache.set(m.id, m.toJSON()); - this.sendSyncMessage( - { - type: 'storageChange', - storageId: m.id, - }, - { transaction }, - ); + Storage.afterSave(async (m, { transaction }) => { + await this.loadStorages({ transaction }); + this.sendSyncMessage({ type: 'reloadStorages' }, { transaction }); }); - Storage.afterDestroy((m, { transaction }) => { + Storage.afterDestroy(async (m, { transaction }) => { for (const collection of this.db.collections.values()) { if (collection?.options?.template === 'file' && collection?.options?.storage === m.name) { throw new Error( @@ -264,14 +239,8 @@ export class PluginFileManagerServer extends Plugin { ); } } - this.storagesCache.delete(m.id); - this.sendSyncMessage( - { - type: 'storageRemove', - storageId: m.id, - }, - { transaction }, - ); + await this.loadStorages({ transaction }); + this.sendSyncMessage({ type: 'reloadStorages' }, { transaction }); }); this.app.acl.registerSnippet({ diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/server/storages/index.ts b/packages/plugins/@nocobase/plugin-file-manager/src/server/storages/index.ts index 355fb4ea00..6c6cc825d9 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/server/storages/index.ts +++ b/packages/plugins/@nocobase/plugin-file-manager/src/server/storages/index.ts @@ -7,9 +7,10 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { isURL } from '@nocobase/utils'; +import Path from 'path'; import { StorageEngine } from 'multer'; import urlJoin from 'url-join'; +import { isURL } from '@nocobase/utils'; import { encodeURL, ensureUrlEncoded, getFileKey } from '../utils'; export interface StorageModel { @@ -46,7 +47,28 @@ export abstract class StorageType { return getFileKey(record); } - getFileData?(file: { [key: string]: any }): { [key: string]: any }; + getFileData(file, meta = {}) { + const { [(this.constructor as typeof StorageType).filenameKey || 'filename']: name } = file; + // make compatible filename across cloud service (with path) + const filename = Path.basename(name); + const extname = Path.extname(filename); + const path = (this.storage.path || '').replace(/^\/|\/$/g, ''); + + const data = { + title: Buffer.from(file.originalname, 'latin1').toString('utf8').replace(extname, ''), + filename, + extname, + // TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path + path, + size: file.size, + mimetype: file.mimetype, + meta, + storageId: this.storage.id, + }; + + return data; + } + getFileURL(file: AttachmentModel, preview?: boolean): string | Promise { // 兼容历史数据 if (file.url && isURL(file.url)) { diff --git a/packages/plugins/@nocobase/plugin-gantt/package.json b/packages/plugins/@nocobase/plugin-gantt/package.json index 9e59fc6f1b..73e015f575 100644 --- a/packages/plugins/@nocobase/plugin-gantt/package.json +++ b/packages/plugins/@nocobase/plugin-gantt/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-gantt", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Block: Gantt", "displayName.zh-CN": "区块:甘特图", "description": "Provides Gantt block.", diff --git a/packages/plugins/@nocobase/plugin-graph-collection-manager/package.json b/packages/plugins/@nocobase/plugin-graph-collection-manager/package.json index e9f90b1c15..1e831d0f5f 100644 --- a/packages/plugins/@nocobase/plugin-graph-collection-manager/package.json +++ b/packages/plugins/@nocobase/plugin-graph-collection-manager/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "可视化数据表管理", "description": "An ER diagram-like tool. Currently only the Master database is supported.", "description.zh-CN": "类似 ER 图的工具,目前只支持主数据库。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/graph-collection-manager", diff --git a/packages/plugins/@nocobase/plugin-kanban/package.json b/packages/plugins/@nocobase/plugin-kanban/package.json index a1da91bdef..e786609456 100644 --- a/packages/plugins/@nocobase/plugin-kanban/package.json +++ b/packages/plugins/@nocobase/plugin-kanban/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-kanban", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/block-kanban", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/block-kanban", diff --git a/packages/plugins/@nocobase/plugin-localization/package.json b/packages/plugins/@nocobase/plugin-localization/package.json index 5a1000e790..4c4d6f6bb6 100644 --- a/packages/plugins/@nocobase/plugin-localization/package.json +++ b/packages/plugins/@nocobase/plugin-localization/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-localization", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/localization-management", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/localization-management", diff --git a/packages/plugins/@nocobase/plugin-logger/package.json b/packages/plugins/@nocobase/plugin-logger/package.json index 4dfcf493c7..a2710cdb24 100644 --- a/packages/plugins/@nocobase/plugin-logger/package.json +++ b/packages/plugins/@nocobase/plugin-logger/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "日志", "description": "Server-side logs, mainly including API request logs and system runtime logs, and allows to package and download log files.", "description.zh-CN": "服务端日志,主要包括接口请求日志和系统运行日志,并支持打包和下载日志文件。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/logger", diff --git a/packages/plugins/@nocobase/plugin-map/package.json b/packages/plugins/@nocobase/plugin-map/package.json index 7793a5c466..80b47b9896 100644 --- a/packages/plugins/@nocobase/plugin-map/package.json +++ b/packages/plugins/@nocobase/plugin-map/package.json @@ -2,7 +2,7 @@ "name": "@nocobase/plugin-map", "displayName": "Block: Map", "displayName.zh-CN": "区块:地图", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "Map block, support Gaode map and Google map, you can also extend more map types.", "description.zh-CN": "地图区块,支持高德地图和 Google 地图,你也可以扩展更多地图类型。", "license": "AGPL-3.0", diff --git a/packages/plugins/@nocobase/plugin-mobile-client/package.json b/packages/plugins/@nocobase/plugin-mobile-client/package.json index e45d50783c..b6f11a0c72 100644 --- a/packages/plugins/@nocobase/plugin-mobile-client/package.json +++ b/packages/plugins/@nocobase/plugin-mobile-client/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-mobile-client", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/mobile-client", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile-client", diff --git a/packages/plugins/@nocobase/plugin-mobile/package.json b/packages/plugins/@nocobase/plugin-mobile/package.json index ea1a8dba37..eb151c133f 100644 --- a/packages/plugins/@nocobase/plugin-mobile/package.json +++ b/packages/plugins/@nocobase/plugin-mobile/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-mobile", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/mobile", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile", diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/MenuPermissions.tsx b/packages/plugins/@nocobase/plugin-mobile/src/client/MenuPermissions.tsx index 8967fc9887..dbcc634fed 100644 --- a/packages/plugins/@nocobase/plugin-mobile/src/client/MenuPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-mobile/src/client/MenuPermissions.tsx @@ -225,40 +225,42 @@ export const MenuPermissions: React.FC<{ expandable={{ defaultExpandAllRows: false, }} - columns={[ - { - dataIndex: 'title', - title: t('Route name'), - }, - { - dataIndex: 'accessible', - title: ( - <> - { - if (allChecked) { - await resource.set({ - values: [], - }); - } else { - await resource.set({ - values: allIDList, - }); - } - refresh(); - message.success(t('Saved successfully')); - }} - />{' '} - {t('Accessible')} - - ), - render: (_, schema) => { - const checked = IDList.includes(schema.id); - return handleChange(checked, schema)} />; + columns={ + [ + { + dataIndex: 'title', + title: t('Route name'), }, - }, - ] as TableProps['columns']} + { + dataIndex: 'accessible', + title: ( + <> + { + if (allChecked) { + await resource.set({ + values: [], + }); + } else { + await resource.set({ + values: allIDList, + }); + } + refresh(); + message.success(t('Saved successfully')); + }} + />{' '} + {t('Accessible')} + + ), + render: (_, schema) => { + const checked = IDList.includes(schema.id); + return handleChange(checked, schema)} />; + }, + }, + ] as TableProps['columns'] + } dataSource={translateTitle(items, t, compile)} /> diff --git a/packages/plugins/@nocobase/plugin-mock-collections/package.json b/packages/plugins/@nocobase/plugin-mock-collections/package.json index 162c451dc2..9918d91a92 100644 --- a/packages/plugins/@nocobase/plugin-mock-collections/package.json +++ b/packages/plugins/@nocobase/plugin-mock-collections/package.json @@ -2,7 +2,7 @@ "name": "@nocobase/plugin-mock-collections", "displayName": "mock-collections", "description": "mock-collections", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "license": "AGPL-3.0", "peerDependencies": { diff --git a/packages/plugins/@nocobase/plugin-multi-app-manager/package.json b/packages/plugins/@nocobase/plugin-multi-app-manager/package.json index ed873d18cd..c8e9c56eb8 100644 --- a/packages/plugins/@nocobase/plugin-multi-app-manager/package.json +++ b/packages/plugins/@nocobase/plugin-multi-app-manager/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "多应用管理器", "description": "Dynamically create multiple apps without separate deployments.", "description.zh-CN": "无需单独部署即可动态创建多个应用。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/multi-app-manager", diff --git a/packages/plugins/@nocobase/plugin-multi-app-share-collection/package.json b/packages/plugins/@nocobase/plugin-multi-app-share-collection/package.json index 36715c5fab..90f030c47e 100644 --- a/packages/plugins/@nocobase/plugin-multi-app-share-collection/package.json +++ b/packages/plugins/@nocobase/plugin-multi-app-share-collection/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "多应用数据表共享", "description": "", "description.zh-CN": "", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "devDependencies": { "@formily/react": "2.x", diff --git a/packages/plugins/@nocobase/plugin-notification-email/package.json b/packages/plugins/@nocobase/plugin-notification-email/package.json index b70330f406..5e6ca8f425 100644 --- a/packages/plugins/@nocobase/plugin-notification-email/package.json +++ b/packages/plugins/@nocobase/plugin-notification-email/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-notification-email", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Notification: Email", "displayName.zh-CN": "通知:电子邮件", "description": "Used for sending email notifications with built-in SMTP transport.", diff --git a/packages/plugins/@nocobase/plugin-notification-in-app-message/package.json b/packages/plugins/@nocobase/plugin-notification-in-app-message/package.json index e33fca02db..71bd3e924a 100644 --- a/packages/plugins/@nocobase/plugin-notification-in-app-message/package.json +++ b/packages/plugins/@nocobase/plugin-notification-in-app-message/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-notification-in-app-message", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "displayName": "Notification: In-app message", "displayName.zh-CN": "通知:站内信", "description": "It supports users in receiving real-time message notifications within the NocoBase application.", diff --git a/packages/plugins/@nocobase/plugin-notification-manager/package.json b/packages/plugins/@nocobase/plugin-notification-manager/package.json index f07f2d8cf7..51ed238a0c 100644 --- a/packages/plugins/@nocobase/plugin-notification-manager/package.json +++ b/packages/plugins/@nocobase/plugin-notification-manager/package.json @@ -4,7 +4,7 @@ "description": "Provides a unified management service that includes channel configuration, logging, and other features, supporting the configuration of various notification channels, including in-app message and email.", "displayName.zh-CN": "通知管理", "description.zh-CN": "提供统一的管理服务,涵盖渠道配置、日志记录等功能,支持多种通知渠道的配置,包括站内信和电子邮件等。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "homepage": "https://docs.nocobase.com/handbook/notification-manager", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/notification-manager", "main": "dist/server/index.js", diff --git a/packages/plugins/@nocobase/plugin-notifications/package.json b/packages/plugins/@nocobase/plugin-notifications/package.json index 294caa442d..318a01cd4e 100644 --- a/packages/plugins/@nocobase/plugin-notifications/package.json +++ b/packages/plugins/@nocobase/plugin-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-notifications", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "description": "", "license": "AGPL-3.0", "main": "./dist/server/index.js", diff --git a/packages/plugins/@nocobase/plugin-public-forms/package.json b/packages/plugins/@nocobase/plugin-public-forms/package.json index b6d1d930bb..81e2eef56f 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/package.json +++ b/packages/plugins/@nocobase/plugin-public-forms/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-public-forms", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "displayName": "Public forms", "displayName.zh-CN": "公开表单", diff --git a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/AdminPublicFormPage.tsx b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/AdminPublicFormPage.tsx index e0ef14cb01..a9fe6f7ee5 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/AdminPublicFormPage.tsx +++ b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/AdminPublicFormPage.tsx @@ -24,6 +24,7 @@ import { TextAreaWithGlobalScope, ApplicationContext, useGlobalVariable, + useCompile, } from '@nocobase/client'; import { Breadcrumb, @@ -71,6 +72,7 @@ export function AdminPublicFormPage() { const { t } = usePublicFormTranslation(); const { theme } = useGlobalTheme(); const apiClient = useAPIClient(); + const compile = useCompile(); const { token } = AntdTheme.useToken(); const app = useApp(); const environmentCtx = useGlobalVariable('$env'); @@ -150,7 +152,7 @@ export function AdminPublicFormPage() { title: {t('Public forms', { ns: NAMESPACE })}, }, { - title: title, + title: compile(title), }, ]} /> diff --git a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/PublicFormPage.tsx b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/PublicFormPage.tsx index b3ad843f22..3e8635b3dd 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/PublicFormPage.tsx +++ b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/PublicFormPage.tsx @@ -28,17 +28,20 @@ import { useApp, useRequest, VariablesProvider, + useCompile, } from '@nocobase/client'; import { Input, Modal, Spin } from 'antd'; +import { useTranslation } from 'react-i18next'; import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { isDesktop } from 'react-device-detect'; import { useParams } from 'react-router'; import { usePublicSubmitActionProps } from '../hooks'; import { UnEnabledFormPlaceholder, UnFoundFormPlaceholder } from './UnEnabledFormPlaceholder'; - import { Button as MobileButton, Dialog as MobileDialog } from 'antd-mobile'; import { MobileDateTimePicker } from './components/MobileDatePicker'; import { MobilePicker } from './components/MobilePicker'; +import { usePublicFormTranslation } from '../locale'; + class PublicDataSource extends DataSource { async getDataSource() { return {}; @@ -83,6 +86,14 @@ function PublicAPIClientProvider({ children }) { return {children}; } +function useTitle(data) { + const compile = useCompile(); + useEffect(() => { + if (!data) return; + document.title = compile(data?.data?.title); + }, [data]); +} + export const PublicFormMessageContext = createContext({}); export const PageBackgroundColor = '#f5f5f5'; @@ -174,6 +185,7 @@ function InternalPublicForm() { ); const [pwd, setPwd] = useState(''); const ctx = useContext(SchemaComponentContext); + useTitle(data); // 设置的移动端 meta useEffect(() => { if (!isDesktop) { diff --git a/packages/plugins/@nocobase/plugin-public-forms/src/server/plugin.ts b/packages/plugins/@nocobase/plugin-public-forms/src/server/plugin.ts index 6b04a5bac1..f3c45f4487 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/src/server/plugin.ts +++ b/packages/plugins/@nocobase/plugin-public-forms/src/server/plugin.ts @@ -73,6 +73,7 @@ export class PluginPublicFormsServer extends Plugin { const keys = instance.collection.split(':'); const collectionName = keys.pop(); const dataSourceKey = keys.pop() || 'main'; + const title = instance.get('title'); const schema = await uiSchema.getJsonSchema(filterByTk); const { getAssociationAppends } = parseAssociationNames(dataSourceKey, collectionName, this.app, schema); const { appends } = getAssociationAppends(); @@ -94,6 +95,7 @@ export class PluginPublicFormsServer extends Plugin { }, ), schema, + title, }; } diff --git a/packages/plugins/@nocobase/plugin-sample-hello/package.json b/packages/plugins/@nocobase/plugin-sample-hello/package.json index 3571ef465b..15a20d7c91 100644 --- a/packages/plugins/@nocobase/plugin-sample-hello/package.json +++ b/packages/plugins/@nocobase/plugin-sample-hello/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-sample-hello", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "./dist/server/index.js", "displayName": "Hello", "displayName.zh-CN": "Hello", diff --git a/packages/plugins/@nocobase/plugin-snapshot-field/package.json b/packages/plugins/@nocobase/plugin-snapshot-field/package.json index b9b1cecc5f..ca7bc28649 100644 --- a/packages/plugins/@nocobase/plugin-snapshot-field/package.json +++ b/packages/plugins/@nocobase/plugin-snapshot-field/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "数据表字段:关系快照", "description": "When adding a new record, create a snapshot for its relational record and save in the new record. The snapshot will not be updated when the relational record is updated.", "description.zh-CN": "在添加数据时,为它的关系数据创建快照,并保存在当前的数据中。关系数据更新时,快照不会更新。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/field-snapshot", diff --git a/packages/plugins/@nocobase/plugin-system-settings/package.json b/packages/plugins/@nocobase/plugin-system-settings/package.json index e1062e492c..ad60e21376 100644 --- a/packages/plugins/@nocobase/plugin-system-settings/package.json +++ b/packages/plugins/@nocobase/plugin-system-settings/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "系统设置", "description": "Used to adjust the system title, logo, language, etc.", "description.zh-CN": "用于调整系统的标题、LOGO、语言等。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/system-settings", diff --git a/packages/plugins/@nocobase/plugin-theme-editor/package.json b/packages/plugins/@nocobase/plugin-theme-editor/package.json index 9eac7ec728..94bb6035d6 100644 --- a/packages/plugins/@nocobase/plugin-theme-editor/package.json +++ b/packages/plugins/@nocobase/plugin-theme-editor/package.json @@ -1,6 +1,6 @@ { "name": "@nocobase/plugin-theme-editor", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/theme-editor", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/theme-editor", diff --git a/packages/plugins/@nocobase/plugin-ui-schema-storage/package.json b/packages/plugins/@nocobase/plugin-ui-schema-storage/package.json index 52e901719f..124e215ce3 100644 --- a/packages/plugins/@nocobase/plugin-ui-schema-storage/package.json +++ b/packages/plugins/@nocobase/plugin-ui-schema-storage/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "UI schema 存储服务", "description": "Provides centralized UI schema storage service.", "description.zh-CN": "提供中心化的 UI schema 存储服务。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/ui-schema-storage", diff --git a/packages/plugins/@nocobase/plugin-user-data-sync/package.json b/packages/plugins/@nocobase/plugin-user-data-sync/package.json index c2f591e23d..16a069d4af 100644 --- a/packages/plugins/@nocobase/plugin-user-data-sync/package.json +++ b/packages/plugins/@nocobase/plugin-user-data-sync/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "用户数据同步", "description": "Reigster and manage extensible user data synchronization sources, with HTTP API provided by default. Support for synchronizing data to resources such as users and departments.", "description.zh-CN": "注册和管理可扩展的用户数据同步来源,默认提供 HTTP API。支持向用户和部门等资源同步数据。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "main": "dist/server/index.js", "peerDependencies": { "@nocobase/client": "1.x", diff --git a/packages/plugins/@nocobase/plugin-users/package.json b/packages/plugins/@nocobase/plugin-users/package.json index 84f4027c98..2ca8701a19 100644 --- a/packages/plugins/@nocobase/plugin-users/package.json +++ b/packages/plugins/@nocobase/plugin-users/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "用户", "description": "Provides basic user model, as well as created by and updated by fields.", "description.zh-CN": "提供了基础的用户模型,以及创建人和最后更新人字段。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/users", diff --git a/packages/plugins/@nocobase/plugin-verification/package.json b/packages/plugins/@nocobase/plugin-verification/package.json index d95a557ce7..41915f3791 100644 --- a/packages/plugins/@nocobase/plugin-verification/package.json +++ b/packages/plugins/@nocobase/plugin-verification/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "验证", "description": "User identity verification management, including SMS, TOTP authenticator, with extensibility.", "description.zh-CN": "用户身份验证管理,包含短信、TOTP 认证器等,可扩展。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/verification", diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json b/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json index 12bfaed482..320a0b5057 100644 --- a/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:操作后事件", "description": "Triggered after the completion of a request initiated through an action button or API, such as after adding, updating, deleting data, or \"submit to workflow\". Suitable for data processing, sending notifications, etc., after actions are completed.", "description.zh-CN": "通过操作按钮或 API 发起请求并在执行完成后触发,比如新增、更新、删除数据或者“提交至工作流”之后。适用于在操作完成后进行数据处理、发送通知等。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/plugins/workflow-action-trigger", diff --git a/packages/plugins/@nocobase/plugin-workflow-aggregate/package.json b/packages/plugins/@nocobase/plugin-workflow-aggregate/package.json index e03018bed1..2d2e90370e 100644 --- a/packages/plugins/@nocobase/plugin-workflow-aggregate/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-aggregate/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:聚合查询节点", "description": "Used to aggregate data against the database in workflow, such as: statistics, sum, average, etc.", "description.zh-CN": "可用于在工作流中对数据库进行聚合查询,如:统计数量、求和、平均值等。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-aggregate", diff --git a/packages/plugins/@nocobase/plugin-workflow-delay/package.json b/packages/plugins/@nocobase/plugin-workflow-delay/package.json index bcc3e572f1..1e31b8d49a 100644 --- a/packages/plugins/@nocobase/plugin-workflow-delay/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-delay/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:延时节点", "description": "Could be used in workflow parallel branch for waiting other branches.", "description.zh-CN": "可用于工作流并行分支中等待其他分支执行完成。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-delay", diff --git a/packages/plugins/@nocobase/plugin-workflow-dynamic-calculation/package.json b/packages/plugins/@nocobase/plugin-workflow-dynamic-calculation/package.json index f0ca8a657c..1f2521e12e 100644 --- a/packages/plugins/@nocobase/plugin-workflow-dynamic-calculation/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-dynamic-calculation/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:动态表达式计算节点", "description": "Useful plugin for doing dynamic calculation based on expression collection records in workflow.", "description.zh-CN": "用于在工作流中进行基于数据行的动态表达式计算。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-dynamic-calculation", diff --git a/packages/plugins/@nocobase/plugin-workflow-loop/package.json b/packages/plugins/@nocobase/plugin-workflow-loop/package.json index bc5df050da..09ec5c99b8 100644 --- a/packages/plugins/@nocobase/plugin-workflow-loop/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-loop/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:循环节点", "description": "Used to repeat the sub-process processing of each value in an array, and can also be used for fixed times of sub-process processing.", "description.zh-CN": "用于对一个数组中的每个值进行重复的子流程处理,也可用于固定次数的重复子流程处理。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-loop", diff --git a/packages/plugins/@nocobase/plugin-workflow-mailer/package.json b/packages/plugins/@nocobase/plugin-workflow-mailer/package.json index 51be849897..7d434c4a70 100644 --- a/packages/plugins/@nocobase/plugin-workflow-mailer/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-mailer/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:邮件发送节点", "description": "Send email in workflow.", "description.zh-CN": "可用于在工作流中发送电子邮件。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-smtp-mailer", diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/package.json b/packages/plugins/@nocobase/plugin-workflow-manual/package.json index 287ce05acc..f42e1f8041 100644 --- a/packages/plugins/@nocobase/plugin-workflow-manual/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-manual/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:人工处理节点", "description": "Could be used for workflows which some of decisions are made by users.", "description.zh-CN": "用于人工控制部分决策的流程。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-manual", diff --git a/packages/plugins/@nocobase/plugin-workflow-notification/package.json b/packages/plugins/@nocobase/plugin-workflow-notification/package.json index fe74899cca..3495c2b05d 100644 --- a/packages/plugins/@nocobase/plugin-workflow-notification/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-notification/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:通知节点", "description": "Send notification in workflow.", "description.zh-CN": "可用于在工作流中发送各类通知。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-smtp-mailer", diff --git a/packages/plugins/@nocobase/plugin-workflow-parallel/package.json b/packages/plugins/@nocobase/plugin-workflow-parallel/package.json index 9bf57c0604..7698723168 100644 --- a/packages/plugins/@nocobase/plugin-workflow-parallel/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-parallel/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:并行分支节点", "description": "Could be used for parallel execution of branch processes in the workflow.", "description.zh-CN": "用于在工作流中需要并行执行的分支流程。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-parallel", diff --git a/packages/plugins/@nocobase/plugin-workflow-request/package.json b/packages/plugins/@nocobase/plugin-workflow-request/package.json index 966c8e3167..c8fb351e9b 100644 --- a/packages/plugins/@nocobase/plugin-workflow-request/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-request/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:HTTP 请求节点", "description": "Send HTTP requests to any HTTP service for data interaction in workflow.", "description.zh-CN": "可用于在工作流中向任意 HTTP 服务发送请求,进行数据交互。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-request", diff --git a/packages/plugins/@nocobase/plugin-workflow-sql/package.json b/packages/plugins/@nocobase/plugin-workflow-sql/package.json index c145717bf0..0952913283 100644 --- a/packages/plugins/@nocobase/plugin-workflow-sql/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-sql/package.json @@ -4,7 +4,7 @@ "displayName.zh-CN": "工作流:SQL 节点", "description": "Execute SQL statements in workflow.", "description.zh-CN": "可用于在工作流中对数据库执行任意 SQL 语句。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow-sql", diff --git a/packages/plugins/@nocobase/plugin-workflow-test/package.json b/packages/plugins/@nocobase/plugin-workflow-test/package.json index abcd23bb6c..c6ff0c3bc9 100644 --- a/packages/plugins/@nocobase/plugin-workflow-test/package.json +++ b/packages/plugins/@nocobase/plugin-workflow-test/package.json @@ -2,7 +2,7 @@ "name": "@nocobase/plugin-workflow-test", "displayName": "Workflow: test kit", "displayName.zh-CN": "工作流:测试工具包", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "dist/server/index.js", "types": "./dist/server/index.d.ts", diff --git a/packages/plugins/@nocobase/plugin-workflow/package.json b/packages/plugins/@nocobase/plugin-workflow/package.json index 91373df6c7..ece246da0e 100644 --- a/packages/plugins/@nocobase/plugin-workflow/package.json +++ b/packages/plugins/@nocobase/plugin-workflow/package.json @@ -4,13 +4,13 @@ "displayName.zh-CN": "工作流", "description": "A powerful BPM tool that provides foundational support for business automation, with the capability to extend unlimited triggers and nodes.", "description.zh-CN": "一个强大的 BPM 工具,为业务自动化提供基础支持,并且可任意扩展更多的触发器和节点。", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./dist/server/index.js", "homepage": "https://docs.nocobase.com/handbook/workflow", "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/workflow", "dependencies": { - "@nocobase/plugin-workflow-test": "1.7.0-alpha.4" + "@nocobase/plugin-workflow-test": "1.7.0-beta.9" }, "devDependencies": { "@ant-design/icons": "5.x", diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/WorkflowTasks.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/WorkflowTasks.tsx index 60de7f36df..6d0f60a1a0 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/WorkflowTasks.tsx +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/WorkflowTasks.tsx @@ -51,7 +51,7 @@ export interface TaskTypeOptions { } const TasksCountsContext = createContext<{ reload: () => void; counts: Record; total: number }>({ - reload() { }, + reload() {}, counts: {}, total: 0, }); @@ -124,8 +124,8 @@ function StatusTabs() { tabBarExtraContent={ ExtraActions ? { - right: , - } + right: , + } : {} } /> @@ -251,7 +251,7 @@ export function WorkflowTasks() { className: contentClass, style: { padding: `${token.paddingPageVertical}px ${token.paddingPageHorizontal}px`, - } + }, }, properties: { list: { diff --git a/packages/presets/nocobase/package.json b/packages/presets/nocobase/package.json index 1c5c17229f..208a462dab 100644 --- a/packages/presets/nocobase/package.json +++ b/packages/presets/nocobase/package.json @@ -1,81 +1,81 @@ { "name": "@nocobase/preset-nocobase", - "version": "1.7.0-alpha.4", + "version": "1.7.0-beta.9", "license": "AGPL-3.0", "main": "./lib/server/index.js", "dependencies": { "@formily/json-schema": "2.x", - "@nocobase/plugin-acl": "1.7.0-alpha.4", - "@nocobase/plugin-action-bulk-edit": "1.7.0-alpha.4", - "@nocobase/plugin-action-bulk-update": "1.7.0-alpha.4", - "@nocobase/plugin-action-custom-request": "1.7.0-alpha.4", - "@nocobase/plugin-action-duplicate": "1.7.0-alpha.4", - "@nocobase/plugin-action-export": "1.7.0-alpha.4", - "@nocobase/plugin-action-import": "1.7.0-alpha.4", - "@nocobase/plugin-action-print": "1.7.0-alpha.4", - "@nocobase/plugin-ai": "1.7.0-alpha.4", - "@nocobase/plugin-api-doc": "1.7.0-alpha.4", - "@nocobase/plugin-api-keys": "1.7.0-alpha.4", - "@nocobase/plugin-async-task-manager": "1.7.0-alpha.4", - "@nocobase/plugin-audit-logs": "1.7.0-alpha.4", - "@nocobase/plugin-auth": "1.7.0-alpha.4", - "@nocobase/plugin-auth-sms": "1.7.0-alpha.4", - "@nocobase/plugin-backup-restore": "1.7.0-alpha.4", - "@nocobase/plugin-block-iframe": "1.7.0-alpha.4", - "@nocobase/plugin-block-template": "1.7.0-alpha.4", - "@nocobase/plugin-block-workbench": "1.7.0-alpha.4", - "@nocobase/plugin-calendar": "1.7.0-alpha.4", - "@nocobase/plugin-charts": "1.7.0-alpha.4", - "@nocobase/plugin-client": "1.7.0-alpha.4", - "@nocobase/plugin-collection-sql": "1.7.0-alpha.4", - "@nocobase/plugin-collection-tree": "1.7.0-alpha.4", - "@nocobase/plugin-data-source-main": "1.7.0-alpha.4", - "@nocobase/plugin-data-source-manager": "1.7.0-alpha.4", - "@nocobase/plugin-data-visualization": "1.7.0-alpha.4", - "@nocobase/plugin-environment-variables": "1.7.0-alpha.4", - "@nocobase/plugin-error-handler": "1.7.0-alpha.4", - "@nocobase/plugin-field-china-region": "1.7.0-alpha.4", - "@nocobase/plugin-field-formula": "1.7.0-alpha.4", - "@nocobase/plugin-field-m2m-array": "1.7.0-alpha.4", - "@nocobase/plugin-field-markdown-vditor": "1.7.0-alpha.4", - "@nocobase/plugin-field-sequence": "1.7.0-alpha.4", - "@nocobase/plugin-field-sort": "1.7.0-alpha.4", - "@nocobase/plugin-file-manager": "1.7.0-alpha.4", - "@nocobase/plugin-gantt": "1.7.0-alpha.4", - "@nocobase/plugin-graph-collection-manager": "1.7.0-alpha.4", - "@nocobase/plugin-kanban": "1.7.0-alpha.4", - "@nocobase/plugin-localization": "1.7.0-alpha.4", - "@nocobase/plugin-logger": "1.7.0-alpha.4", - "@nocobase/plugin-map": "1.7.0-alpha.4", - "@nocobase/plugin-mobile": "1.7.0-alpha.4", - "@nocobase/plugin-mobile-client": "1.7.0-alpha.4", - "@nocobase/plugin-mock-collections": "1.7.0-alpha.4", - "@nocobase/plugin-multi-app-manager": "1.7.0-alpha.4", - "@nocobase/plugin-multi-app-share-collection": "1.7.0-alpha.4", - "@nocobase/plugin-notification-email": "1.7.0-alpha.4", - "@nocobase/plugin-notification-in-app-message": "1.7.0-alpha.4", - "@nocobase/plugin-notification-manager": "1.7.0-alpha.4", - "@nocobase/plugin-public-forms": "1.7.0-alpha.4", - "@nocobase/plugin-snapshot-field": "1.7.0-alpha.4", - "@nocobase/plugin-system-settings": "1.7.0-alpha.4", - "@nocobase/plugin-theme-editor": "1.7.0-alpha.4", - "@nocobase/plugin-ui-schema-storage": "1.7.0-alpha.4", - "@nocobase/plugin-user-data-sync": "1.7.0-alpha.4", - "@nocobase/plugin-users": "1.7.0-alpha.4", - "@nocobase/plugin-verification": "1.7.0-alpha.4", - "@nocobase/plugin-workflow": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-action-trigger": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-aggregate": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-delay": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-dynamic-calculation": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-loop": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-mailer": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-manual": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-notification": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-parallel": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-request": "1.7.0-alpha.4", - "@nocobase/plugin-workflow-sql": "1.7.0-alpha.4", - "@nocobase/server": "1.7.0-alpha.4", + "@nocobase/plugin-acl": "1.7.0-beta.9", + "@nocobase/plugin-action-bulk-edit": "1.7.0-beta.9", + "@nocobase/plugin-action-bulk-update": "1.7.0-beta.9", + "@nocobase/plugin-action-custom-request": "1.7.0-beta.9", + "@nocobase/plugin-action-duplicate": "1.7.0-beta.9", + "@nocobase/plugin-action-export": "1.7.0-beta.9", + "@nocobase/plugin-action-import": "1.7.0-beta.9", + "@nocobase/plugin-action-print": "1.7.0-beta.9", + "@nocobase/plugin-ai": "1.7.0-beta.9", + "@nocobase/plugin-api-doc": "1.7.0-beta.9", + "@nocobase/plugin-api-keys": "1.7.0-beta.9", + "@nocobase/plugin-async-task-manager": "1.7.0-beta.9", + "@nocobase/plugin-audit-logs": "1.7.0-beta.9", + "@nocobase/plugin-auth": "1.7.0-beta.9", + "@nocobase/plugin-auth-sms": "1.7.0-beta.9", + "@nocobase/plugin-backup-restore": "1.7.0-beta.9", + "@nocobase/plugin-block-iframe": "1.7.0-beta.9", + "@nocobase/plugin-block-template": "1.7.0-beta.9", + "@nocobase/plugin-block-workbench": "1.7.0-beta.9", + "@nocobase/plugin-calendar": "1.7.0-beta.9", + "@nocobase/plugin-charts": "1.7.0-beta.9", + "@nocobase/plugin-client": "1.7.0-beta.9", + "@nocobase/plugin-collection-sql": "1.7.0-beta.9", + "@nocobase/plugin-collection-tree": "1.7.0-beta.9", + "@nocobase/plugin-data-source-main": "1.7.0-beta.9", + "@nocobase/plugin-data-source-manager": "1.7.0-beta.9", + "@nocobase/plugin-data-visualization": "1.7.0-beta.9", + "@nocobase/plugin-environment-variables": "1.7.0-beta.9", + "@nocobase/plugin-error-handler": "1.7.0-beta.9", + "@nocobase/plugin-field-china-region": "1.7.0-beta.9", + "@nocobase/plugin-field-formula": "1.7.0-beta.9", + "@nocobase/plugin-field-m2m-array": "1.7.0-beta.9", + "@nocobase/plugin-field-markdown-vditor": "1.7.0-beta.9", + "@nocobase/plugin-field-sequence": "1.7.0-beta.9", + "@nocobase/plugin-field-sort": "1.7.0-beta.9", + "@nocobase/plugin-file-manager": "1.7.0-beta.9", + "@nocobase/plugin-gantt": "1.7.0-beta.9", + "@nocobase/plugin-graph-collection-manager": "1.7.0-beta.9", + "@nocobase/plugin-kanban": "1.7.0-beta.9", + "@nocobase/plugin-localization": "1.7.0-beta.9", + "@nocobase/plugin-logger": "1.7.0-beta.9", + "@nocobase/plugin-map": "1.7.0-beta.9", + "@nocobase/plugin-mobile": "1.7.0-beta.9", + "@nocobase/plugin-mobile-client": "1.7.0-beta.9", + "@nocobase/plugin-mock-collections": "1.7.0-beta.9", + "@nocobase/plugin-multi-app-manager": "1.7.0-beta.9", + "@nocobase/plugin-multi-app-share-collection": "1.7.0-beta.9", + "@nocobase/plugin-notification-email": "1.7.0-beta.9", + "@nocobase/plugin-notification-in-app-message": "1.7.0-beta.9", + "@nocobase/plugin-notification-manager": "1.7.0-beta.9", + "@nocobase/plugin-public-forms": "1.7.0-beta.9", + "@nocobase/plugin-snapshot-field": "1.7.0-beta.9", + "@nocobase/plugin-system-settings": "1.7.0-beta.9", + "@nocobase/plugin-theme-editor": "1.7.0-beta.9", + "@nocobase/plugin-ui-schema-storage": "1.7.0-beta.9", + "@nocobase/plugin-user-data-sync": "1.7.0-beta.9", + "@nocobase/plugin-users": "1.7.0-beta.9", + "@nocobase/plugin-verification": "1.7.0-beta.9", + "@nocobase/plugin-workflow": "1.7.0-beta.9", + "@nocobase/plugin-workflow-action-trigger": "1.7.0-beta.9", + "@nocobase/plugin-workflow-aggregate": "1.7.0-beta.9", + "@nocobase/plugin-workflow-delay": "1.7.0-beta.9", + "@nocobase/plugin-workflow-dynamic-calculation": "1.7.0-beta.9", + "@nocobase/plugin-workflow-loop": "1.7.0-beta.9", + "@nocobase/plugin-workflow-mailer": "1.7.0-beta.9", + "@nocobase/plugin-workflow-manual": "1.7.0-beta.9", + "@nocobase/plugin-workflow-notification": "1.7.0-beta.9", + "@nocobase/plugin-workflow-parallel": "1.7.0-beta.9", + "@nocobase/plugin-workflow-request": "1.7.0-beta.9", + "@nocobase/plugin-workflow-sql": "1.7.0-beta.9", + "@nocobase/server": "1.7.0-beta.9", "cronstrue": "^2.11.0", "fs-extra": "^11.1.1" },