@nocobase/client-v2 2.2.0-beta.9 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/APIClient.d.ts +1 -3
- package/es/BaseApplication.d.ts +1 -0
- package/es/acl/ACLProvider.d.ts +10 -0
- package/es/authRedirect.d.ts +5 -0
- package/es/collection-field-interface/CollectionFieldInterface.d.ts +1 -0
- package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +1 -0
- package/es/components/AttachmentUpload.d.ts +51 -0
- package/es/components/category-tabs/SortableCategoryTabs.d.ts +55 -0
- package/es/components/category-tabs/index.d.ts +9 -0
- package/es/components/form/ScanInput/useCodeScanner.d.ts +3 -2
- package/es/components/form/TypedVariableInput.d.ts +31 -5
- package/es/components/form/filter/CollectionFilter.d.ts +2 -0
- package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
- package/es/components/form/filter/CollectionFilterPanel.d.ts +2 -0
- package/es/components/form/filter/index.d.ts +2 -0
- package/es/components/form/filter/useFilterActionProps.d.ts +2 -0
- package/es/components/index.d.ts +2 -0
- package/es/flow/actions/index.d.ts +1 -1
- package/es/flow/actions/linkageRules.d.ts +3 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/NocoBaseLogo.d.ts +10 -0
- package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
- package/es/flow/components/FieldAssignValueInput.d.ts +9 -0
- package/es/flow/components/FlowRoute.d.ts +2 -2
- package/es/flow/components/RunJSValueEditor.d.ts +1 -0
- package/es/flow/components/filter/FilterGroup.d.ts +1 -0
- package/es/flow/components/filter/VariableFilterItem.d.ts +6 -1
- package/es/flow/index.d.ts +1 -0
- package/es/flow/internal/registerDeviceTypeContext.d.ts +10 -0
- package/es/flow/models/base/ActionModelCore.d.ts +4 -2
- package/es/flow/models/base/BlockGridModel.d.ts +3 -0
- package/es/flow/models/base/PageModel/PageModel.d.ts +12 -0
- package/es/flow/models/base/PageModel/PageModelTabBar.d.ts +22 -0
- package/es/flow/models/base/PageModel/PageTabModel.d.ts +12 -0
- package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
- package/es/flow/models/blocks/table/TableColumnModel.d.ts +1 -0
- package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +15 -7
- package/es/flow-compat/fieldValidationConstants.d.ts +1 -1
- package/es/flow-compat/routeTypes.d.ts +1 -0
- package/es/index.d.ts +8 -1
- package/es/index.mjs +190 -141
- package/es/nocobase-buildin-plugin/currentUserAuthStatus.d.ts +11 -0
- package/es/nocobase-buildin-plugin/index.d.ts +9 -0
- package/es/settings-app/SettingsApplication.d.ts +18 -0
- package/es/settings-app/SettingsBrand.d.ts +16 -0
- package/es/settings-app/SettingsBuildInPlugin.d.ts +9 -0
- package/es/settings-app/SettingsDocumentRedirect.d.ts +10 -0
- package/es/settings-app/SettingsGroupNav.d.ts +17 -0
- package/es/settings-app/SettingsPluginSettingsManager.d.ts +14 -0
- package/es/settings-app/SettingsRouterManager.d.ts +15 -0
- package/es/settings-app/SettingsSearch.d.ts +17 -0
- package/es/settings-app/SettingsShell.d.ts +10 -0
- package/es/settings-app/isSettingsApp.d.ts +18 -0
- package/es/settings-app/runtimePaths.d.ts +18 -0
- package/es/settings-app/settingsDocumentPath.d.ts +14 -0
- package/es/settings-app/settingsTheme.d.ts +87 -0
- package/es/settings-app/useSettingsThemeConfig.d.ts +22 -0
- package/es/settings-center/AdminSettingsLayout.d.ts +2 -2
- package/es/settings-center/groups.d.ts +66 -0
- package/es/settings-center/useSettingsGroups.d.ts +36 -0
- package/es/settings-center/useSettingsSearch.d.ts +35 -0
- package/es/settings-center/utils.d.ts +24 -0
- package/es/theme/index.d.ts +1 -0
- package/es/theme/itemActive.d.ts +24 -0
- package/es/theme/type.d.ts +9 -0
- package/es/utils/getRouteRuntimeVersion.d.ts +23 -0
- package/es/utils/index.d.ts +1 -0
- package/lib/index.js +195 -146
- package/lib/locale/languageCodes.js +3 -1
- package/package.json +9 -7
- package/src/APIClient.ts +1 -10
- package/src/Application.tsx +4 -0
- package/src/BaseApplication.tsx +11 -6
- package/src/__tests__/app.test.tsx +73 -0
- package/src/__tests__/authRedirect.test.ts +137 -0
- package/src/__tests__/browserChecker.test.ts +185 -6
- package/src/__tests__/getRouteRuntimeVersion.test.ts +68 -0
- package/src/__tests__/mockSettingsApplication.ts +29 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +79 -10
- package/src/__tests__/plugin-manager.test.tsx +7 -6
- package/src/__tests__/settings-application.test.ts +164 -0
- package/src/__tests__/settings-auth-routes.test.ts +71 -0
- package/src/__tests__/settings-center.test.tsx +38 -37
- package/src/__tests__/settings-layout-root.test.tsx +260 -0
- package/src/__tests__/settings-runtime-paths.test.ts +99 -0
- package/src/__tests__/settings-shell.test.tsx +200 -0
- package/src/acl/ACLProvider.tsx +21 -0
- package/src/authRedirect.ts +72 -3
- package/src/collection-field-interface/CollectionFieldInterface.ts +1 -0
- package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +1 -0
- package/src/collection-manager/field-validation.ts +1 -1
- package/src/components/AttachmentUpload.tsx +275 -0
- package/src/components/README.md +7 -1
- package/src/components/README.zh-CN.md +6 -1
- package/src/components/category-tabs/SortableCategoryTabs.tsx +210 -0
- package/src/components/category-tabs/index.ts +10 -0
- package/src/components/form/JsonTextArea.tsx +4 -0
- package/src/components/form/ScanInput/CodeScanner.tsx +79 -35
- package/src/components/form/ScanInput/__tests__/CodeScanner.test.tsx +101 -0
- package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +284 -11
- package/src/components/form/ScanInput/useCodeScanner.ts +332 -24
- package/src/components/form/TypedVariableInput.tsx +452 -101
- package/src/components/form/__tests__/TypedVariableInput.test.tsx +364 -12
- package/src/components/form/filter/CollectionFilter.tsx +4 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
- package/src/components/form/filter/CollectionFilterPanel.tsx +4 -0
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
- package/src/components/form/filter/__tests__/useFilterActionProps.test.tsx +95 -0
- package/src/components/form/filter/index.ts +2 -0
- package/src/components/form/filter/useFilterActionProps.ts +37 -6
- package/src/components/index.ts +2 -0
- package/src/flow/FlowPage.tsx +9 -1
- package/src/flow/__tests__/FlowPage.test.tsx +50 -3
- package/src/flow/__tests__/FlowRoute.test.tsx +128 -10
- package/src/flow/__tests__/PluginFlowEngine.test.ts +58 -0
- package/src/flow/actions/__tests__/actionLinkageRules.forkProps.test.ts +314 -0
- package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +102 -0
- package/src/flow/actions/__tests__/linkageRules.tab.test.ts +171 -0
- package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +7 -3
- package/src/flow/actions/index.ts +2 -0
- package/src/flow/actions/linkageRules.tsx +111 -16
- package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +1 -57
- package/src/flow/admin-shell/admin-layout/NocoBaseLogo.tsx +77 -0
- package/src/flow/admin-shell/admin-layout/TopbarActionsBar.tsx +37 -14
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +253 -6
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +77 -13
- package/src/flow/common/Markdown/style.ts +4 -0
- package/src/flow/components/BlockItemCard.tsx +2 -2
- package/src/flow/components/FieldAssignExactDatePicker.tsx +25 -11
- package/src/flow/components/FieldAssignValueInput.tsx +91 -20
- package/src/flow/components/FlowRoute.tsx +78 -32
- package/src/flow/components/RunJSValueEditor.tsx +9 -1
- package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
- package/src/flow/components/filter/FilterGroup.tsx +33 -5
- package/src/flow/components/filter/VariableFilterItem.tsx +158 -10
- package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +45 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +9 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +70 -1
- package/src/flow/index.ts +3 -0
- package/src/flow/internal/registerDeviceTypeContext.ts +39 -0
- package/src/flow/models/base/ActionModelCore.tsx +11 -2
- package/src/flow/models/base/BlockGridModel.tsx +26 -0
- package/src/flow/models/base/CollectionBlockModel.tsx +6 -2
- package/src/flow/models/base/PageModel/PageModel.tsx +387 -53
- package/src/flow/models/base/PageModel/PageModelTabBar.tsx +114 -0
- package/src/flow/models/base/PageModel/PageTabModel.tsx +249 -18
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +790 -10
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.module-isolation.test.tsx +130 -0
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.test.tsx +118 -0
- package/src/flow/models/base/PageModel/__tests__/PageTabModel.test.ts +1075 -7
- package/src/flow/models/base/__tests__/ActionModelCore.render.test.tsx +49 -0
- package/src/flow/models/base/__tests__/BlockGridModel.selectSceneActivation.test.ts +124 -0
- package/src/flow/models/base/__tests__/CollectionBlockModel.addAppends.test.ts +41 -0
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +28 -3
- package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +27 -12
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +36 -0
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +66 -4
- package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
- package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +1 -1
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +2 -1
- package/src/flow/models/blocks/table/TableBlockModel.tsx +4 -2
- package/src/flow/models/blocks/table/TableColumnModel.tsx +30 -1
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +12 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +33 -0
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +2 -1
- package/src/flow/models/fields/DateTimeFieldModel/__tests__/DateTimeNoTzFieldModel.dateLimit.test.tsx +149 -0
- package/src/flow/models/fields/DateTimeFieldModel/dateLimit.ts +149 -113
- package/src/flow/models/fields/JsonFieldModel.tsx +31 -8
- package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
- package/src/flow/models/fields/__tests__/JsonFieldModel.test.ts +82 -0
- package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
- package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +20 -10
- package/src/flow/models/fields/mobile-components/MobileSelect.tsx +24 -12
- package/src/flow/models/topbar/TopbarActionModel.tsx +52 -180
- package/src/flow/utils/dataScopeFormValueClear.ts +4 -3
- package/src/flow-compat/fieldValidationConstants.ts +1 -1
- package/src/flow-compat/routeTypes.ts +1 -0
- package/src/index.ts +14 -1
- package/src/locale/languageCodes.ts +3 -1
- package/src/nocobase-buildin-plugin/currentUserAuthStatus.ts +58 -0
- package/src/nocobase-buildin-plugin/index.tsx +110 -70
- package/src/settings-app/SettingsApplication.ts +31 -0
- package/src/settings-app/SettingsBrand.tsx +108 -0
- package/src/settings-app/SettingsBuildInPlugin.ts +10 -0
- package/src/settings-app/SettingsDocumentRedirect.tsx +26 -0
- package/src/settings-app/SettingsGroupNav.tsx +124 -0
- package/src/settings-app/SettingsPluginSettingsManager.ts +38 -0
- package/src/settings-app/SettingsRouterManager.ts +92 -0
- package/src/settings-app/SettingsSearch.tsx +238 -0
- package/src/settings-app/SettingsShell.tsx +167 -0
- package/src/settings-app/isSettingsApp.ts +21 -0
- package/src/settings-app/runtimePaths.ts +104 -0
- package/src/settings-app/settingsDocumentPath.ts +66 -0
- package/src/settings-app/settingsTheme.ts +301 -0
- package/src/settings-app/useSettingsThemeConfig.ts +100 -0
- package/src/settings-center/AdminSettingsLayout.tsx +122 -141
- package/src/settings-center/SystemSettingsPage.tsx +4 -170
- package/src/settings-center/groups.ts +108 -0
- package/src/settings-center/useSettingsGroups.ts +105 -0
- package/src/settings-center/useSettingsSearch.ts +173 -0
- package/src/settings-center/utils.tsx +50 -1
- package/src/theme/index.tsx +1 -0
- package/src/theme/itemActive.ts +31 -0
- package/src/theme/type.ts +10 -0
- package/src/utils/getRouteRuntimeVersion.ts +185 -0
- package/src/utils/index.tsx +1 -0
|
@@ -68,6 +68,12 @@ interface LinkageRule {
|
|
|
68
68
|
}[];
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
export function updateLinkageRules<T>(rules: T[], updater: (nextRules: T[]) => void): T[] {
|
|
72
|
+
const nextRules = _.cloneDeep(rules);
|
|
73
|
+
updater(nextRules);
|
|
74
|
+
return nextRules;
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
const previewValueForLog = (value: any) => {
|
|
72
78
|
if (value == null) return value;
|
|
73
79
|
const t = typeof value;
|
|
@@ -731,6 +737,41 @@ export const linkageSetMenuItemProps = defineAction({
|
|
|
731
737
|
},
|
|
732
738
|
});
|
|
733
739
|
|
|
740
|
+
export const linkageSetTabProps = defineAction({
|
|
741
|
+
name: 'linkageSetTabProps',
|
|
742
|
+
title: tExpr('Set tab state'),
|
|
743
|
+
scene: ActionScene.TAB_LINKAGE_RULES,
|
|
744
|
+
sort: 100,
|
|
745
|
+
uiSchema: {
|
|
746
|
+
value: {
|
|
747
|
+
type: 'string',
|
|
748
|
+
'x-component': (props) => {
|
|
749
|
+
const { value, onChange } = props;
|
|
750
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
751
|
+
const ctx = useFlowContext();
|
|
752
|
+
const t = ctx.model.translate.bind(ctx.model);
|
|
753
|
+
|
|
754
|
+
return (
|
|
755
|
+
<Select
|
|
756
|
+
value={value}
|
|
757
|
+
onChange={onChange}
|
|
758
|
+
placeholder={t('Please select state')}
|
|
759
|
+
style={{ width: '100%' }}
|
|
760
|
+
options={[
|
|
761
|
+
{ label: t('Visible'), value: 'visible' },
|
|
762
|
+
{ label: t('Hidden'), value: 'hidden' },
|
|
763
|
+
]}
|
|
764
|
+
allowClear
|
|
765
|
+
/>
|
|
766
|
+
);
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
handler(ctx, { value, setProps }) {
|
|
771
|
+
setProps(ctx.model, { hiddenModel: value === 'hidden' });
|
|
772
|
+
},
|
|
773
|
+
});
|
|
774
|
+
|
|
734
775
|
export const linkageSetFieldProps = defineAction({
|
|
735
776
|
name: 'linkageSetFieldProps',
|
|
736
777
|
title: tExpr('Set field state'),
|
|
@@ -1339,6 +1380,7 @@ export const linkageRunjs = defineAction({
|
|
|
1339
1380
|
ActionScene.FIELD_LINKAGE_RULES,
|
|
1340
1381
|
ActionScene.ACTION_LINKAGE_RULES,
|
|
1341
1382
|
ActionScene.MENU_LINKAGE_RULES,
|
|
1383
|
+
ActionScene.TAB_LINKAGE_RULES,
|
|
1342
1384
|
ActionScene.DETAILS_FIELD_LINKAGE_RULES,
|
|
1343
1385
|
ActionScene.SUB_FORM_FIELD_LINKAGE_RULES,
|
|
1344
1386
|
],
|
|
@@ -1464,13 +1506,26 @@ async function resolveLinkageRulesParamsPreservingRunJsScripts(ctx: FlowContext,
|
|
|
1464
1506
|
}
|
|
1465
1507
|
|
|
1466
1508
|
const LinkageRulesUI = observer(
|
|
1467
|
-
(props: {
|
|
1468
|
-
|
|
1509
|
+
(props: {
|
|
1510
|
+
readonly value: LinkageRule[];
|
|
1511
|
+
onChange?: (value: LinkageRule[]) => void;
|
|
1512
|
+
supportedActions: string[];
|
|
1513
|
+
title?: string;
|
|
1514
|
+
}) => {
|
|
1515
|
+
const { value: rules = [], onChange, supportedActions } = props;
|
|
1469
1516
|
const ctx = useFlowContext();
|
|
1470
1517
|
const flowEngine = useFlowEngine();
|
|
1471
1518
|
const t = ctx.model.translate.bind(ctx.model);
|
|
1472
1519
|
const assignPriorityTip = t('Assignment takes precedence over form field assignment');
|
|
1473
1520
|
|
|
1521
|
+
const replaceRules = (updater: (nextRules: LinkageRule[]) => void) => {
|
|
1522
|
+
if (onChange) {
|
|
1523
|
+
onChange(updateLinkageRules(rules, updater));
|
|
1524
|
+
} else {
|
|
1525
|
+
updater(rules);
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1474
1529
|
// 创建新规则的默认值
|
|
1475
1530
|
const createNewRule = (): LinkageRule => ({
|
|
1476
1531
|
key: uid(),
|
|
@@ -1487,7 +1542,7 @@ const LinkageRulesUI = observer(
|
|
|
1487
1542
|
|
|
1488
1543
|
// 删除规则
|
|
1489
1544
|
const handleDeleteRule = (index: number) => {
|
|
1490
|
-
|
|
1545
|
+
replaceRules((nextRules) => nextRules.splice(index, 1));
|
|
1491
1546
|
};
|
|
1492
1547
|
|
|
1493
1548
|
// 上移规则
|
|
@@ -1526,7 +1581,9 @@ const LinkageRulesUI = observer(
|
|
|
1526
1581
|
|
|
1527
1582
|
// 切换规则启用状态
|
|
1528
1583
|
const handleToggleEnable = (index: number, enable: boolean) => {
|
|
1529
|
-
|
|
1584
|
+
replaceRules((nextRules) => {
|
|
1585
|
+
nextRules[index].enable = enable;
|
|
1586
|
+
});
|
|
1530
1587
|
};
|
|
1531
1588
|
|
|
1532
1589
|
// 获取可用的动作类型
|
|
@@ -2169,17 +2226,30 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2169
2226
|
}
|
|
2170
2227
|
: props;
|
|
2171
2228
|
|
|
2172
|
-
//
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2229
|
+
// 只记录联动实际控制的属性,避免之后恢复状态时把标题、路由等无关的新配置回滚到旧快照。
|
|
2230
|
+
const originalProps = model.__originalProps || (model.__originalProps = {});
|
|
2231
|
+
const rememberOriginalProp = (key: string, value: unknown) => {
|
|
2232
|
+
if (!Object.prototype.hasOwnProperty.call(originalProps, key)) {
|
|
2233
|
+
originalProps[key] = value;
|
|
2234
|
+
}
|
|
2235
|
+
};
|
|
2236
|
+
Object.keys(normalizedProps || {}).forEach((key) => {
|
|
2237
|
+
if (key === 'hiddenModel') {
|
|
2238
|
+
rememberOriginalProp(
|
|
2239
|
+
key,
|
|
2240
|
+
Object.prototype.hasOwnProperty.call(model.props || {}, key) ? model.props?.[key] : model.hidden,
|
|
2241
|
+
);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
rememberOriginalProp(key, model.props?.[key]);
|
|
2246
|
+
if (key === 'hiddenText' && normalizedProps[key]) {
|
|
2247
|
+
rememberOriginalProp('title', model.props?.title);
|
|
2248
|
+
}
|
|
2249
|
+
if (key === 'required') {
|
|
2250
|
+
rememberOriginalProp('rules', model.props?.rules);
|
|
2251
|
+
}
|
|
2252
|
+
});
|
|
2183
2253
|
|
|
2184
2254
|
// 临时存起来,遍历完所有规则后,再统一处理
|
|
2185
2255
|
patchPropsByModel.set(model, {
|
|
@@ -2237,7 +2307,6 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
|
|
|
2237
2307
|
const newProps = { ...model.__originalProps, ...patchProps };
|
|
2238
2308
|
const prevHidden = !!model.hidden;
|
|
2239
2309
|
const nextHidden = !!newProps.hiddenModel;
|
|
2240
|
-
|
|
2241
2310
|
model.setProps(_.omit(newProps, ['hiddenModel', 'value', 'hiddenText', LINKAGE_ASSIGN_MODE_PROP]));
|
|
2242
2311
|
syncFieldOptionsToForks(model, patchProps);
|
|
2243
2312
|
if (typeof model.setHidden === 'function') {
|
|
@@ -2463,6 +2532,32 @@ export const menuLinkageRules = defineAction({
|
|
|
2463
2532
|
},
|
|
2464
2533
|
});
|
|
2465
2534
|
|
|
2535
|
+
export const tabLinkageRules = defineAction({
|
|
2536
|
+
name: 'tabLinkageRules',
|
|
2537
|
+
title: tExpr('Tab linkage rules'),
|
|
2538
|
+
uiMode: 'embed',
|
|
2539
|
+
uiSchema(ctx) {
|
|
2540
|
+
return {
|
|
2541
|
+
value: {
|
|
2542
|
+
type: 'array',
|
|
2543
|
+
'x-component': LinkageRulesUI,
|
|
2544
|
+
'x-component-props': {
|
|
2545
|
+
supportedActions: getSupportedActions(ctx, ActionScene.TAB_LINKAGE_RULES),
|
|
2546
|
+
title: tExpr('Tab linkage rules'),
|
|
2547
|
+
},
|
|
2548
|
+
},
|
|
2549
|
+
};
|
|
2550
|
+
},
|
|
2551
|
+
defaultParams: {
|
|
2552
|
+
value: [],
|
|
2553
|
+
},
|
|
2554
|
+
useRawParams: true,
|
|
2555
|
+
handler: async (ctx, params) => {
|
|
2556
|
+
const resolved = await resolveLinkageRulesParamsPreservingRunJsScripts(ctx, params);
|
|
2557
|
+
return commonLinkageRulesHandler(ctx, resolved);
|
|
2558
|
+
},
|
|
2559
|
+
});
|
|
2560
|
+
|
|
2466
2561
|
export const fieldLinkageRules = defineAction({
|
|
2467
2562
|
name: 'fieldLinkageRules',
|
|
2468
2563
|
title: tExpr('Field linkage rules'),
|
|
@@ -35,12 +35,8 @@ export const linkageRulesRefresh = defineAction({
|
|
|
35
35
|
// Prefer running on the current model; fallback to blockModel when the current model doesn't own the flow.
|
|
36
36
|
if (!hasFlow) return;
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// Skip master when unmounted forks can handle the same flow.
|
|
39
39
|
// Otherwise master is likely the rendered model and still needs refresh.
|
|
40
|
-
// In design mode, always refresh master so the currently edited model state stays in sync.
|
|
41
|
-
const flowSettingsEnabled = Boolean(
|
|
42
|
-
(ctx as any)?.flowSettingsEnabled || (model as any)?.context?.flowSettingsEnabled,
|
|
43
|
-
);
|
|
44
40
|
const hasForkWithFlow =
|
|
45
41
|
!model?.isFork &&
|
|
46
42
|
!!model?.forks?.size &&
|
|
@@ -49,7 +45,7 @@ export const linkageRulesRefresh = defineAction({
|
|
|
49
45
|
return !!fork?.getFlow?.(flowKey);
|
|
50
46
|
});
|
|
51
47
|
const isMasterMounted = Boolean((model as any)?.context?.ref?.current);
|
|
52
|
-
if (hasForkWithFlow && !isMasterMounted
|
|
48
|
+
if (hasForkWithFlow && !isMasterMounted) {
|
|
53
49
|
return;
|
|
54
50
|
}
|
|
55
51
|
|
|
@@ -18,7 +18,6 @@ import { theme as antdTheme, ConfigProvider, Grid, Popover } from 'antd';
|
|
|
18
18
|
import { createStyles, createGlobalStyle } from 'antd-style';
|
|
19
19
|
import React, { FC, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
20
20
|
import ReactDOM from 'react-dom';
|
|
21
|
-
import { useTranslation } from 'react-i18next';
|
|
22
21
|
import { useLocation } from 'react-router-dom';
|
|
23
22
|
import {
|
|
24
23
|
AdminLayoutMenuModelRenderer,
|
|
@@ -35,7 +34,6 @@ import { ResetThemeTokenAndKeepAlgorithm } from './ResetThemeTokenAndKeepAlgorit
|
|
|
35
34
|
import { PinnedPluginListLite } from './PinnedPluginListLite';
|
|
36
35
|
import { useApplications } from './useApplications';
|
|
37
36
|
import { useGlobalTheme, type CustomToken } from '../../../theme';
|
|
38
|
-
import { useSystemSettings } from '../../system-settings';
|
|
39
37
|
import { NocoBaseDesktopRouteType, type NocoBaseDesktopRoute } from '../../../flow-compat';
|
|
40
38
|
import {
|
|
41
39
|
FLOW_SETTINGS_PREFERENCE_CHANGE_EVENT,
|
|
@@ -44,60 +42,7 @@ import {
|
|
|
44
42
|
} from './flowSettingsPreference';
|
|
45
43
|
import { joinAdminLayoutRoutePath, type AdminLayoutRoutePathLike } from './resolveAdminRouteRuntimeTarget';
|
|
46
44
|
import { useAppListRender } from './AppListRender';
|
|
47
|
-
|
|
48
|
-
const className1 = css`
|
|
49
|
-
height: var(--nb-header-height);
|
|
50
|
-
margin-right: 4px;
|
|
51
|
-
display: inline-flex;
|
|
52
|
-
flex-shrink: 0;
|
|
53
|
-
color: #fff;
|
|
54
|
-
padding: 0;
|
|
55
|
-
align-items: center;
|
|
56
|
-
`;
|
|
57
|
-
const className1WithFixedWidth = css`
|
|
58
|
-
${className1}
|
|
59
|
-
width: 168px;
|
|
60
|
-
`;
|
|
61
|
-
const className1WithAutoWidth = css`
|
|
62
|
-
${className1}
|
|
63
|
-
width: auto;
|
|
64
|
-
min-width: 168px;
|
|
65
|
-
`;
|
|
66
|
-
const className2 = css`
|
|
67
|
-
object-fit: contain;
|
|
68
|
-
width: 100%;
|
|
69
|
-
height: 100%;
|
|
70
|
-
`;
|
|
71
|
-
const className3 = css`
|
|
72
|
-
width: 100%;
|
|
73
|
-
height: 100%;
|
|
74
|
-
font-weight: 500;
|
|
75
|
-
text-align: center;
|
|
76
|
-
overflow: hidden;
|
|
77
|
-
text-overflow: ellipsis;
|
|
78
|
-
white-space: nowrap;
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
|
-
const NocoBaseLogo = observer(() => {
|
|
82
|
-
const { token } = antdTheme.useToken();
|
|
83
|
-
const customToken = token as CustomToken;
|
|
84
|
-
const result = useSystemSettings();
|
|
85
|
-
const { t } = useTranslation('lm-collections');
|
|
86
|
-
const fontSizeStyle = useMemo(() => ({ fontSize: customToken.fontSizeHeading3 }), [customToken.fontSizeHeading3]);
|
|
87
|
-
|
|
88
|
-
const hasLogo = result?.data?.data?.logo?.url;
|
|
89
|
-
const logo = hasLogo ? (
|
|
90
|
-
<img className={className2} src={result?.data?.data?.logo?.url} />
|
|
91
|
-
) : (
|
|
92
|
-
<span style={fontSizeStyle} className={className3}>
|
|
93
|
-
{t(result?.data?.data?.title)}
|
|
94
|
-
</span>
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<div className={hasLogo ? className1WithFixedWidth : className1WithAutoWidth}>{result?.loading ? null : logo}</div>
|
|
99
|
-
);
|
|
100
|
-
});
|
|
45
|
+
import { NocoBaseLogo } from './NocoBaseLogo';
|
|
101
46
|
|
|
102
47
|
const resetStyle = css`
|
|
103
48
|
.ant-layout-sider-children {
|
|
@@ -712,7 +657,6 @@ export const AdminLayoutComponent = observer((props: any) => {
|
|
|
712
657
|
<MobileMenuControlContext.Provider value={{ closeMobileMenu }}>
|
|
713
658
|
<DndProvider collisionDetection={menuCollisionDetection} onDragEnd={handleMenuDragEnd}>
|
|
714
659
|
<ProLayout
|
|
715
|
-
key={`admin-layout-menu-${menuRouteRefreshVersion}`}
|
|
716
660
|
{...props}
|
|
717
661
|
contentStyle={contentStyle}
|
|
718
662
|
siderWidth={customToken.siderWidth || 200}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { css } from '@emotion/css';
|
|
11
|
+
import { observer } from '@nocobase/flow-engine';
|
|
12
|
+
import { theme as antdTheme } from 'antd';
|
|
13
|
+
import React, { useMemo } from 'react';
|
|
14
|
+
import { useTranslation } from 'react-i18next';
|
|
15
|
+
import { useSystemSettings } from '../../system-settings';
|
|
16
|
+
import type { CustomToken } from '../../../theme';
|
|
17
|
+
|
|
18
|
+
const logoContainerClassName = css`
|
|
19
|
+
height: var(--nb-header-height);
|
|
20
|
+
margin-right: 4px;
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
align-items: center;
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const fixedWidthClassName = css`
|
|
28
|
+
${logoContainerClassName}
|
|
29
|
+
width: 168px;
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const autoWidthClassName = css`
|
|
33
|
+
${logoContainerClassName}
|
|
34
|
+
width: auto;
|
|
35
|
+
min-width: 168px;
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
const logoImageClassName = css`
|
|
39
|
+
object-fit: contain;
|
|
40
|
+
width: 100%;
|
|
41
|
+
height: 100%;
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const titleClassName = css`
|
|
45
|
+
width: 100%;
|
|
46
|
+
height: 100%;
|
|
47
|
+
font-weight: 500;
|
|
48
|
+
text-align: center;
|
|
49
|
+
overflow: hidden;
|
|
50
|
+
text-overflow: ellipsis;
|
|
51
|
+
white-space: nowrap;
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export const NocoBaseLogo = observer(() => {
|
|
55
|
+
const { token } = antdTheme.useToken();
|
|
56
|
+
const customToken = token as CustomToken;
|
|
57
|
+
const result = useSystemSettings();
|
|
58
|
+
const { t } = useTranslation('lm-collections');
|
|
59
|
+
const title = t(result?.data?.data?.title || 'NocoBase');
|
|
60
|
+
const logoUrl = result?.data?.data?.logo?.url;
|
|
61
|
+
const titleStyle = useMemo<React.CSSProperties>(
|
|
62
|
+
() => ({ color: customToken.colorTextHeaderMenu, fontSize: customToken.fontSizeHeading3 }),
|
|
63
|
+
[customToken.colorTextHeaderMenu, customToken.fontSizeHeading3],
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const logo = logoUrl ? (
|
|
67
|
+
<img alt={title} className={logoImageClassName} src={logoUrl} />
|
|
68
|
+
) : (
|
|
69
|
+
<span style={titleStyle} className={titleClassName}>
|
|
70
|
+
{title}
|
|
71
|
+
</span>
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return <div className={logoUrl ? fixedWidthClassName : autoWidthClassName}>{result?.loading ? null : logo}</div>;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
NocoBaseLogo.displayName = 'NocoBaseLogo';
|
|
@@ -24,7 +24,9 @@ const topbarActionsBarClassName = css`
|
|
|
24
24
|
align-items: center;
|
|
25
25
|
color: var(--nb-topbar-action-color);
|
|
26
26
|
|
|
27
|
-
.nb-topbar-actions-list
|
|
27
|
+
.nb-topbar-actions-list,
|
|
28
|
+
.nb-topbar-utility-actions-list,
|
|
29
|
+
.nb-topbar-plugin-settings-action {
|
|
28
30
|
display: inline-flex;
|
|
29
31
|
align-items: center;
|
|
30
32
|
height: 100%;
|
|
@@ -127,12 +129,18 @@ const getTopbarActionId = (action: TopbarActionModel) => {
|
|
|
127
129
|
return action?.actionId || action?.uid || '';
|
|
128
130
|
};
|
|
129
131
|
|
|
132
|
+
const PLUGIN_SETTINGS_ACTION_ID = 'plugin-settings';
|
|
133
|
+
|
|
130
134
|
const TopbarActionsContent = React.memo((props: { actions: TopbarActionModel[]; onActionClick?: () => void }) => {
|
|
131
135
|
const { allow } = useAclSnippets();
|
|
132
136
|
const { token } = theme.useToken();
|
|
133
137
|
const customToken = token as CustomToken;
|
|
134
138
|
const actions = useMemo(() => getVisibleTopbarActions(props.actions, allow), [allow, props.actions]);
|
|
135
|
-
const mainActions = actions.filter((action) =>
|
|
139
|
+
const mainActions = actions.filter((action) => {
|
|
140
|
+
const actionId = getTopbarActionId(action);
|
|
141
|
+
return actionId !== PLUGIN_SETTINGS_ACTION_ID && actionId !== USER_CENTER_ACTION_ID;
|
|
142
|
+
});
|
|
143
|
+
const pluginSettingsAction = actions.find((action) => getTopbarActionId(action) === PLUGIN_SETTINGS_ACTION_ID);
|
|
136
144
|
const userCenterAction = actions.find((action) => getTopbarActionId(action) === USER_CENTER_ACTION_ID);
|
|
137
145
|
|
|
138
146
|
return (
|
|
@@ -153,18 +161,33 @@ const TopbarActionsContent = React.memo((props: { actions: TopbarActionModel[];
|
|
|
153
161
|
<ConfigProvider theme={dividerTheme}>
|
|
154
162
|
<Divider type="vertical" />
|
|
155
163
|
</ConfigProvider>
|
|
156
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
<div className="nb-topbar-utility-actions-list">
|
|
165
|
+
{pluginSettingsAction ? (
|
|
166
|
+
<span className="nb-topbar-plugin-settings-action" onClick={props.onActionClick}>
|
|
167
|
+
<ErrorBoundary
|
|
168
|
+
key={pluginSettingsAction.uid}
|
|
169
|
+
FallbackComponent={TopbarActionErrorFallback}
|
|
170
|
+
onError={(error) => {
|
|
171
|
+
console.error('[NocoBase] Topbar action render failed.', error);
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<FlowModelRenderer model={pluginSettingsAction} />
|
|
175
|
+
</ErrorBoundary>
|
|
176
|
+
</span>
|
|
177
|
+
) : null}
|
|
178
|
+
<HelpLite />
|
|
179
|
+
{userCenterAction ? (
|
|
180
|
+
<ErrorBoundary
|
|
181
|
+
key={userCenterAction.uid}
|
|
182
|
+
FallbackComponent={TopbarActionErrorFallback}
|
|
183
|
+
onError={(error) => {
|
|
184
|
+
console.error('[NocoBase] Topbar action render failed.', error);
|
|
185
|
+
}}
|
|
186
|
+
>
|
|
187
|
+
<FlowModelRenderer model={userCenterAction} />
|
|
188
|
+
</ErrorBoundary>
|
|
189
|
+
) : null}
|
|
190
|
+
</div>
|
|
168
191
|
</div>
|
|
169
192
|
);
|
|
170
193
|
});
|