@nocobase/client-v2 2.1.11 → 2.2.0-alpha.2
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/PluginSettingsManager.d.ts +33 -0
- package/es/RouteRepository.d.ts +21 -6
- package/es/components/category-tabs/SortableCategoryTabs.d.ts +55 -0
- package/es/components/category-tabs/index.d.ts +9 -0
- package/es/components/form/TypedVariableInput.d.ts +22 -4
- package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
- package/es/components/form/filter/index.d.ts +2 -0
- package/es/components/index.d.ts +2 -0
- package/es/flow/actions/afterSuccess.d.ts +8 -1
- package/es/flow/actions/index.d.ts +1 -1
- package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
- package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +5 -0
- package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
- package/es/flow/components/FieldAssignValueInput.d.ts +2 -0
- package/es/flow/index.d.ts +1 -0
- package/es/flow/models/base/GridModel.d.ts +1 -1
- package/es/flow/models/blocks/form/submitHandler.d.ts +1 -1
- package/es/flow/models/blocks/table/TableActionsColumnModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableBlockModel.d.ts +1 -0
- package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +1 -1
- package/es/flow/models/blocks/table/dragSort/dragSortSettings.d.ts +2 -1
- package/es/flow/models/blocks/table/dragSort/dragSortUtils.d.ts +6 -4
- package/es/flow/resolveViewParamsToViewList.d.ts +1 -1
- package/es/index.d.ts +2 -1
- package/es/index.mjs +181 -131
- package/lib/index.js +186 -136
- package/package.json +7 -7
- package/src/PluginSettingsManager.ts +53 -0
- package/src/RouteRepository.ts +126 -24
- package/src/__tests__/PluginSettingsManager.test.ts +13 -0
- package/src/__tests__/RouteRepository.test.ts +216 -0
- package/src/__tests__/browserChecker.test.ts +61 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/plugin-manager.test.tsx +44 -2
- package/src/__tests__/settings-center.test.tsx +40 -1
- package/src/collection-manager/field-configure.ts +1 -1
- package/src/collection-manager/interfaces/id.ts +1 -1
- package/src/collection-manager/interfaces/m2m.tsx +2 -2
- package/src/collection-manager/interfaces/m2o.tsx +2 -2
- package/src/collection-manager/interfaces/nanoid.ts +1 -1
- package/src/collection-manager/interfaces/o2m.tsx +2 -2
- package/src/collection-manager/interfaces/obo.tsx +2 -2
- package/src/collection-manager/interfaces/oho.tsx +2 -2
- package/src/collection-manager/interfaces/properties/index.ts +2 -2
- package/src/collection-manager/interfaces/uuid.ts +1 -1
- 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/TypedVariableInput.tsx +416 -93
- package/src/components/form/__tests__/TypedVariableInput.test.tsx +266 -9
- package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
- package/src/components/form/filter/index.ts +2 -0
- package/src/components/index.ts +2 -0
- package/src/flow/__tests__/FlowRoute.test.tsx +443 -5
- package/src/flow/__tests__/getKey.test.ts +7 -0
- package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +34 -0
- package/src/flow/actions/__tests__/afterSuccess.test.ts +73 -0
- package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +104 -0
- package/src/flow/actions/afterSuccess.tsx +142 -3
- package/src/flow/actions/customVariable.tsx +1 -2
- package/src/flow/actions/index.ts +1 -1
- package/src/flow/actions/linkageRules.tsx +2 -7
- package/src/flow/actions/openView.tsx +38 -4
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/admin-shell/BaseLayoutModel.tsx +25 -3
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +5 -2
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +13 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +34 -10
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +310 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +44 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +23 -9
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +188 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +82 -0
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +166 -2
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
- package/src/flow/components/DefaultValue.tsx +1 -2
- package/src/flow/components/FieldAssignValueInput.tsx +10 -5
- package/src/flow/components/FlowRoute.tsx +56 -11
- package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
- package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
- package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
- package/src/flow/getViewDiffAndUpdateHidden.tsx +1 -0
- package/src/flow/index.ts +1 -0
- package/src/flow/models/actions/JSActionModel.tsx +2 -7
- package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
- package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
- package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
- package/src/flow/models/base/ActionModel.tsx +12 -1
- package/src/flow/models/base/GridModel.tsx +38 -7
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +0 -4
- package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
- package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
- package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +1 -2
- package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
- package/src/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.tsx +1 -1
- package/src/flow/models/blocks/form/FormActionModel.tsx +1 -1
- package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
- package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +54 -1
- package/src/flow/models/blocks/form/submitHandler.ts +17 -3
- package/src/flow/models/blocks/form/value-runtime/rules.ts +2 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +2 -7
- package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +36 -13
- package/src/flow/models/blocks/table/TableBlockModel.tsx +38 -17
- package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +111 -1
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.dragSort.test.ts +127 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +1 -0
- package/src/flow/models/blocks/table/dragSort/dragSortHooks.tsx +28 -17
- package/src/flow/models/blocks/table/dragSort/dragSortSettings.ts +13 -6
- package/src/flow/models/blocks/table/dragSort/dragSortUtils.ts +15 -2
- package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
- package/src/flow/models/fields/JSFieldModel.tsx +2 -7
- package/src/flow/models/fields/JSItemModel.tsx +2 -14
- package/src/flow/models/topbar/TopbarActionModel.tsx +93 -10
- package/src/flow/resolveViewParamsToViewList.tsx +11 -3
- package/src/flow-compat/Popover.tsx +43 -4
- package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
- package/src/index.ts +8 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
- package/src/nocobase-buildin-plugin/index.tsx +0 -2
- package/src/settings-center/AdminSettingsLayout.tsx +10 -2
- package/src/settings-center/SystemSettingsPage.tsx +1 -2
- package/src/settings-center/plugin-manager/PluginCard.tsx +2 -2
- package/src/settings-center/utils.tsx +0 -6
|
@@ -8,15 +8,54 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Popover as AntdPopover, type PopoverProps } from 'antd';
|
|
11
|
-
import React, { useCallback, useRef } from 'react';
|
|
11
|
+
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
12
12
|
import { getZIndex, useZIndexContext, zIndexContext } from './zIndexContext';
|
|
13
13
|
|
|
14
14
|
export const ICON_POPUP_Z_INDEX = 2000;
|
|
15
15
|
|
|
16
|
+
function parseZIndex(value?: string | null) {
|
|
17
|
+
if (!value || value === 'auto') {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const zIndex = Number(value);
|
|
22
|
+
return Number.isFinite(zIndex) ? zIndex : undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getElementZIndex(element: HTMLElement) {
|
|
26
|
+
return parseZIndex(window.getComputedStyle(element).zIndex) ?? parseZIndex(element.style.zIndex);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getContainingPopupZIndex(element: HTMLElement | null) {
|
|
30
|
+
if (!element || typeof window === 'undefined') {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let current: HTMLElement | null = element;
|
|
35
|
+
let maxZIndex = 0;
|
|
36
|
+
|
|
37
|
+
while (current && current !== document.documentElement) {
|
|
38
|
+
const zIndex = getElementZIndex(current);
|
|
39
|
+
if (typeof zIndex === 'number' && zIndex > maxZIndex) {
|
|
40
|
+
maxZIndex = zIndex;
|
|
41
|
+
}
|
|
42
|
+
current = current.parentElement;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return maxZIndex;
|
|
46
|
+
}
|
|
47
|
+
|
|
16
48
|
export const StablePopover = (props: PopoverProps) => {
|
|
17
49
|
const parentZIndex = useZIndexContext();
|
|
18
|
-
const
|
|
19
|
-
const target = useRef(null);
|
|
50
|
+
const [containingPopupZIndex, setContainingPopupZIndex] = useState(parentZIndex);
|
|
51
|
+
const target = useRef<EventTarget | null>(null);
|
|
52
|
+
const triggerRef = useRef<HTMLDivElement | null>(null);
|
|
53
|
+
const zIndex = getZIndex('drawer', Math.max(parentZIndex, containingPopupZIndex), 1);
|
|
54
|
+
|
|
55
|
+
useLayoutEffect(() => {
|
|
56
|
+
const nextZIndex = Math.max(parentZIndex, getContainingPopupZIndex(triggerRef.current));
|
|
57
|
+
setContainingPopupZIndex((previousZIndex) => (previousZIndex === nextZIndex ? previousZIndex : nextZIndex));
|
|
58
|
+
}, [parentZIndex]);
|
|
20
59
|
|
|
21
60
|
const avoidClose = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
|
22
61
|
target.current = e.target;
|
|
@@ -36,7 +75,7 @@ export const StablePopover = (props: PopoverProps) => {
|
|
|
36
75
|
);
|
|
37
76
|
|
|
38
77
|
return (
|
|
39
|
-
<div className="popover-with-stop-propagation" onClick={avoidClose}>
|
|
78
|
+
<div ref={triggerRef} className="popover-with-stop-propagation" onClick={avoidClose}>
|
|
40
79
|
<zIndexContext.Provider value={zIndex}>
|
|
41
80
|
<AntdPopover {...props} zIndex={zIndex} onOpenChange={onOpenChange} />
|
|
42
81
|
</zIndexContext.Provider>
|
|
@@ -0,0 +1,34 @@
|
|
|
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 { render, screen, waitFor } from '@testing-library/react';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { describe, expect, it } from 'vitest';
|
|
13
|
+
import { StablePopover } from '../Popover';
|
|
14
|
+
|
|
15
|
+
describe('StablePopover', () => {
|
|
16
|
+
it('renders above the containing popup layer', async () => {
|
|
17
|
+
render(
|
|
18
|
+
<div style={{ position: 'relative', zIndex: 5000 }}>
|
|
19
|
+
<StablePopover open content={<div>Icon picker popup</div>}>
|
|
20
|
+
<button type="button">Select icon</button>
|
|
21
|
+
</StablePopover>
|
|
22
|
+
</div>,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect(screen.getByText('Icon picker popup')).toBeInTheDocument();
|
|
26
|
+
|
|
27
|
+
await waitFor(() => {
|
|
28
|
+
const popover = document.querySelector<HTMLElement>('.ant-popover');
|
|
29
|
+
|
|
30
|
+
expect(popover).toBeInTheDocument();
|
|
31
|
+
expect(Number(popover?.style.zIndex)).toBeGreaterThan(5000);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -39,5 +39,12 @@ export * from './collection-manager/interfaces';
|
|
|
39
39
|
export * from './collection-manager/template-fields';
|
|
40
40
|
export * from './data-source';
|
|
41
41
|
export * from './flow';
|
|
42
|
-
export {
|
|
42
|
+
export {
|
|
43
|
+
DEFAULT_DATA_SOURCE_KEY,
|
|
44
|
+
IconPicker,
|
|
45
|
+
isTitleField,
|
|
46
|
+
isTitleFieldInterface,
|
|
47
|
+
NocoBaseDesktopRouteType,
|
|
48
|
+
} from './flow-compat';
|
|
49
|
+
export type { NocoBaseDesktopRoute } from './flow-compat';
|
|
43
50
|
export { default as AntdAppProvider } from './theme/AntdAppProvider';
|
|
@@ -11,7 +11,7 @@ import { FlowEngine, FlowEngineProvider, observer } from '@nocobase/flow-engine'
|
|
|
11
11
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { createMemoryRouter, Outlet, RouterProvider, useOutlet } from 'react-router-dom';
|
|
14
|
-
import { describe, expect, it } from 'vitest';
|
|
14
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
15
15
|
import { BaseLayoutModel } from '../../flow/admin-shell/BaseLayoutModel';
|
|
16
16
|
import { LayoutContentRoute } from '../LayoutContentRoute';
|
|
17
17
|
import { LayoutRoute } from '../LayoutRoute';
|
|
@@ -106,6 +106,46 @@ describe('LayoutRoute', () => {
|
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
it('does not activate desktop route loading for generic layouts', async () => {
|
|
110
|
+
const activateLayout = vi.fn(() => vi.fn());
|
|
111
|
+
const engine = new FlowEngine();
|
|
112
|
+
engine.registerModels({ TestLayoutModel });
|
|
113
|
+
engine.context.defineProperty('routeRepository', {
|
|
114
|
+
value: {
|
|
115
|
+
activateLayout,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
engine.context.defineProperty('app', {
|
|
119
|
+
value: {
|
|
120
|
+
layoutManager: {
|
|
121
|
+
getLayout: () => layout,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const router = createMemoryRouter(
|
|
127
|
+
[
|
|
128
|
+
{
|
|
129
|
+
id: layout.routeName,
|
|
130
|
+
path: layout.routePath,
|
|
131
|
+
element: <LayoutRoute layoutRouteName="test" />,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
{
|
|
135
|
+
initialEntries: ['/test'],
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
render(
|
|
140
|
+
<FlowEngineProvider engine={engine}>
|
|
141
|
+
<RouterProvider router={router} />
|
|
142
|
+
</FlowEngineProvider>,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
expect(await screen.findByTestId('layout-route')).toHaveTextContent('test');
|
|
146
|
+
expect(activateLayout).not.toHaveBeenCalled();
|
|
147
|
+
});
|
|
148
|
+
|
|
109
149
|
it('syncs nested page route before the layout renders its outlet', async () => {
|
|
110
150
|
const nestedLayout: LayoutDefinition = {
|
|
111
151
|
...layout,
|
|
@@ -355,7 +355,6 @@ export class NocoBaseBuildInPlugin extends Plugin<any, Application> {
|
|
|
355
355
|
title: this.app.i18n.t('System settings'),
|
|
356
356
|
icon: 'SettingOutlined',
|
|
357
357
|
aclSnippet: 'pm.system-settings.system-settings',
|
|
358
|
-
sort: -100,
|
|
359
358
|
});
|
|
360
359
|
this.app.pluginSettingsManager.addPageTabItem({
|
|
361
360
|
menuKey: 'system-settings',
|
|
@@ -363,7 +362,6 @@ export class NocoBaseBuildInPlugin extends Plugin<any, Application> {
|
|
|
363
362
|
title: this.app.i18n.t('System settings'),
|
|
364
363
|
componentLoader: () => import('../settings-center/SystemSettingsPage'),
|
|
365
364
|
aclSnippet: 'pm.system-settings.system-settings',
|
|
366
|
-
sort: -100,
|
|
367
365
|
});
|
|
368
366
|
// Parent menu for security-related plugin settings (password policy, locked users, etc.). Registered here in the buildin plugin so any pro plugin can attach page tabs to `menuKey: 'security'` without each one re-registering the same parent.
|
|
369
367
|
this.app.pluginSettingsManager.addMenuItem({
|
|
@@ -209,6 +209,9 @@ export const InternalAdminSettingsLayout = () => {
|
|
|
209
209
|
style={{
|
|
210
210
|
background: token.colorBgContainer,
|
|
211
211
|
borderInlineEnd: `${token.lineWidth}px solid ${token.colorBorderSecondary}`,
|
|
212
|
+
minHeight: 0,
|
|
213
|
+
overflowY: 'auto',
|
|
214
|
+
overflowX: 'hidden',
|
|
212
215
|
}}
|
|
213
216
|
>
|
|
214
217
|
<Menu
|
|
@@ -239,11 +242,12 @@ export const InternalAdminSettingsLayout = () => {
|
|
|
239
242
|
<Layout.Content
|
|
240
243
|
style={{
|
|
241
244
|
background: token.colorBgLayout,
|
|
245
|
+
flex: 1,
|
|
242
246
|
display: 'flex',
|
|
243
247
|
flexDirection: 'column',
|
|
244
248
|
minWidth: 0,
|
|
245
|
-
|
|
246
|
-
|
|
249
|
+
minHeight: 0,
|
|
250
|
+
overflow: 'hidden',
|
|
247
251
|
}}
|
|
248
252
|
>
|
|
249
253
|
<PageHeader
|
|
@@ -273,6 +277,10 @@ export const InternalAdminSettingsLayout = () => {
|
|
|
273
277
|
/>
|
|
274
278
|
<div
|
|
275
279
|
style={{
|
|
280
|
+
flex: 1,
|
|
281
|
+
minHeight: 0,
|
|
282
|
+
boxSizing: 'border-box',
|
|
283
|
+
overflow: 'auto',
|
|
276
284
|
padding: token.paddingLG,
|
|
277
285
|
}}
|
|
278
286
|
>
|
|
@@ -221,7 +221,6 @@ export const SystemSettingsPage = () => {
|
|
|
221
221
|
return (
|
|
222
222
|
<div
|
|
223
223
|
style={{
|
|
224
|
-
minHeight: '100%',
|
|
225
224
|
background: token.colorBgContainer,
|
|
226
225
|
borderRadius: token.borderRadiusLG,
|
|
227
226
|
padding: token.paddingLG,
|
|
@@ -240,7 +239,7 @@ export const SystemSettingsPage = () => {
|
|
|
240
239
|
<Form.Item
|
|
241
240
|
name="raw_title"
|
|
242
241
|
label={t('System title')}
|
|
243
|
-
rules={[{ required: true, message: t('Please enter') + t('System title') }]}
|
|
242
|
+
rules={[{ required: true, message: t('Please enter') + ' ' + t('System title') }]}
|
|
244
243
|
>
|
|
245
244
|
<Input.TextArea autoSize={{ minRows: 2, maxRows: 4 }} />
|
|
246
245
|
</Form.Item>
|
|
@@ -116,7 +116,7 @@ export const PluginCard: FC<PluginCardProps> = ({ data }) => {
|
|
|
116
116
|
});
|
|
117
117
|
|
|
118
118
|
const openSettings = useMemoizedFn(() => {
|
|
119
|
-
navigate(app.pluginSettingsManager.
|
|
119
|
+
navigate(app.pluginSettingsManager.getPluginSettingsRoutePath(name));
|
|
120
120
|
});
|
|
121
121
|
|
|
122
122
|
const cardClassName = useMemo(
|
|
@@ -180,7 +180,7 @@ export const PluginCard: FC<PluginCardProps> = ({ data }) => {
|
|
|
180
180
|
<ReadOutlined /> {t('Docs')}
|
|
181
181
|
</a>
|
|
182
182
|
)}
|
|
183
|
-
{enabled && app.pluginSettingsManager.
|
|
183
|
+
{enabled && app.pluginSettingsManager.hasPluginSettings(name) && (
|
|
184
184
|
<a
|
|
185
185
|
onClick={(e) => {
|
|
186
186
|
e.stopPropagation();
|
|
@@ -85,12 +85,6 @@ export function filterVisibleSettings(settings: readonly PluginSettingsPageType[
|
|
|
85
85
|
*/
|
|
86
86
|
export function sortTopLevelSettings(settings: PluginSettingsPageType[] = []) {
|
|
87
87
|
return [...settings].sort((a, b) => {
|
|
88
|
-
if (a.name === SYSTEM_SETTINGS_SETTING_NAME && b.name !== SYSTEM_SETTINGS_SETTING_NAME) {
|
|
89
|
-
return -1;
|
|
90
|
-
}
|
|
91
|
-
if (b.name === SYSTEM_SETTINGS_SETTING_NAME && a.name !== SYSTEM_SETTINGS_SETTING_NAME) {
|
|
92
|
-
return 1;
|
|
93
|
-
}
|
|
94
88
|
if ((a.sort || 0) !== (b.sort || 0)) {
|
|
95
89
|
return (a.sort || 0) - (b.sort || 0);
|
|
96
90
|
}
|