705b7449f0
* refactor: plugin manager page * fix: bug * feat: addByNpm api * fix: improve the addByNpm * feat: improve applicationPlugins:list api * fix: re-download npm package when restart app * fix: plugin delete api * feat: plugin detail api * feat: zipUrl add api * fix: upload api bug * fix: plugin detail info * feat: upgrade api * fix: upload api * feat: handle plugin load error * feat: support authToken * feat: muti lang * fix: build error * fix: self review * Update plugin-manager.ts * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * fix: bugs * fix: detail click and remove isOfficial * fix: upgrade no refresh * fix: file size and type check * fix: bug * fix: upgrade error * fix: bug * fix: bug * fix: plugin card layout * fix: handling exceptional cases * fix: tgz file support * fix: macos compress file * fix: bug * fix: bug * fix: bug * fix: bug * fix: add upgrade npm type * fix: bugs * fix: bug * fix: change plugins static expose url * fix: api prefix * fix: bug * fix: add nginx `/static/plugin/` path * fix: bugs and pr docker build no dts * fix: bug * fix: build tools bug * fix: improve code * fix: build bug * feat: improve plugin info * fix: ui bug * fix: plugin document bug * feat: improve code * feat: improve code * feat: process dev deps check * feat: improve code * feat: process.env.IS_DEV_CMD * fix: do not delete the plugin package * feat: plugin symlink * fix: tsx watch --ignore=./storage/plugins/** * fix: test error * fix: improve code * fix: improve code * fix: emitStartedEvent * fix: improve code * fix: type error * fix: test error * test: console.log * fix: createStoragePluginSymLink * fix: clientStaticMiddleware rename to clientStaticUtils * feat: build tools support plugins folder * fix: 350px * fix: error * feat: client dev support plugin folder * fix: clear cli options * fix: typeError: Converting circular structure to JSON * fix: plugin name * chore: restart application after command * feat: upgrade error & docs * Update v14-changelog.md * Update v14-changelog.md * Update v14-changelog.md * fix: gateway test * refactor(plugin-workflow): add ready state for gracefully tearing down * Revert "chore: restart application after command" This reverts commit 5015274f8e4e06e506e15754b672330330e8c7f8. * chore: stop application whe restart * T 1218 change plugin folder (#2629) * feat: change folder name * feat: change `pm create` command * feat: revert plugin name change * fix: delete samples * feat: change plugins folder * fix: pm create * feat: update docs * fix: link package error * fix: docs * fix: create command * fix: pm add error * fix: create add build * fix: pm creatre + add * feat: add tar command * fix: docs * fix: bug * fix: docs --------- Co-authored-by: chenos <chenlinxh@gmail.com> * feat: docs * Update your-fisrt-plugin.md * Update your-fisrt-plugin.md * chore: application reload * chore: test * fix: pm add error * chore: preset install skip exists plugin * fix: createIfNotExists --------- Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: chareice <chareice@live.com> Co-authored-by: Zhou <zhou.working@gmail.com> Co-authored-by: mytharcher <mytharcher@gmail.com>
187 lines
5.2 KiB
TypeScript
187 lines
5.2 KiB
TypeScript
import type { Field } from '@formily/core';
|
|
import { ISchema, useForm } from '@formily/react';
|
|
import { IField, interfacesProperties, useCollectionManager, useRecord } from '@nocobase/client';
|
|
import lodash from 'lodash';
|
|
import { NAMESPACE } from './locale';
|
|
|
|
const { defaultProps } = interfacesProperties;
|
|
|
|
const APPENDS = 'appends';
|
|
const TARGET_FIELD = 'targetField';
|
|
|
|
export const useTopRecord = () => {
|
|
let record = useRecord();
|
|
|
|
while (record && Object.keys(record.__parent).length > 0) {
|
|
record = record.__parent;
|
|
}
|
|
return record;
|
|
};
|
|
|
|
function useRecordCollection() {
|
|
const { getCollectionField } = useCollectionManager();
|
|
const record = useTopRecord();
|
|
const formValues = useForm().values;
|
|
return getCollectionField(`${record.name}.${formValues.targetField}`)?.target;
|
|
}
|
|
|
|
const onTargetFieldChange = (field: Field) => {
|
|
field.value; // for watch
|
|
const targetField = field.query(`.${APPENDS}`).take() as Field | undefined;
|
|
console.log(field.path);
|
|
if (!targetField) return;
|
|
!targetField.getState().disabled && targetField.setValue([]);
|
|
};
|
|
|
|
function MakeFieldsPathOptions(fields, appends = []) {
|
|
const { getCollection } = useCollectionManager();
|
|
const options = [];
|
|
fields.forEach((field) => {
|
|
if (['belongsTo', 'hasOne', 'hasMany', 'belongsToMany'].includes(field.type)) {
|
|
const currentAppends = appends.filter((key) => `${key}.`.startsWith(`${field.name}.`));
|
|
if (currentAppends.length) {
|
|
const nextCollection = getCollection(field.target);
|
|
const nextAppends = currentAppends
|
|
.filter((key) => key !== field.name)
|
|
.map((key) => key.replace(`${field.name}.`, ''))
|
|
.filter((key) => key);
|
|
options.push({
|
|
label: field.uiSchema?.title ?? field.name,
|
|
value: field.name,
|
|
children: MakeFieldsPathOptions(nextCollection.fields, nextAppends),
|
|
});
|
|
}
|
|
} else {
|
|
options.push({
|
|
label: field.uiSchema?.title ?? field.name,
|
|
value: field.name,
|
|
});
|
|
}
|
|
});
|
|
return options;
|
|
}
|
|
|
|
const recordPickerViewer = {
|
|
type: 'void',
|
|
title: `{{t('View record')}}`,
|
|
'x-component': 'RecordPicker.Viewer',
|
|
'x-component-props': {
|
|
className: 'nb-action-popup',
|
|
},
|
|
properties: {
|
|
tabs: {
|
|
type: 'void',
|
|
'x-component': 'Tabs',
|
|
'x-component-props': {},
|
|
// 'x-initializer': 'TabPaneInitializers',
|
|
properties: {
|
|
tab1: {
|
|
type: 'void',
|
|
title: `{{t('Detail')}}`,
|
|
'x-component': 'Tabs.TabPane',
|
|
'x-designer': 'Tabs.Designer',
|
|
'x-component-props': {},
|
|
properties: {
|
|
grid: {
|
|
type: 'void',
|
|
'x-component': 'Grid',
|
|
'x-initializer': 'SnapshotBlockInitializers',
|
|
properties: {},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
export const snapshot: IField = {
|
|
name: 'snapshot',
|
|
type: 'object',
|
|
group: 'advanced',
|
|
title: `{{t('Snapshot', {ns: '${NAMESPACE}'})}}`,
|
|
description: `{{t('When adding a new record, create a snapshot for its relational record and save in the current record. The snapshot is not updated when the record is subsequently updated.', {ns: '${NAMESPACE}'})}}`,
|
|
default: {
|
|
type: 'snapshot',
|
|
// name,
|
|
uiSchema: {
|
|
// title,
|
|
'x-component': 'SnapshotRecordPicker',
|
|
'x-component-props': {
|
|
multiple: true,
|
|
fieldNames: {
|
|
label: 'id',
|
|
value: 'id',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
schemaInitialize(schema: ISchema, { field, readPretty, action, block }) {
|
|
schema['properties'] = {
|
|
viewer: lodash.cloneDeep(recordPickerViewer),
|
|
};
|
|
},
|
|
initialize: (values: any) => {},
|
|
usePathOptions(field) {
|
|
const { appends = [], targetCollection } = field;
|
|
const { getCollection } = useCollectionManager();
|
|
const { fields } = getCollection(targetCollection);
|
|
|
|
const result = MakeFieldsPathOptions(fields, appends);
|
|
|
|
return [
|
|
{
|
|
label: `{{t('Snapshot data', { ns: '${NAMESPACE}' })}}`,
|
|
value: 'data',
|
|
children: result,
|
|
},
|
|
];
|
|
},
|
|
properties: {
|
|
...defaultProps,
|
|
[TARGET_FIELD]: {
|
|
type: 'string',
|
|
title: `{{t('The association field to snapshot', {ns: '${NAMESPACE}'})}}`,
|
|
required: true,
|
|
'x-decorator': 'FormItem',
|
|
'x-component': 'SnapshotOwnerCollectionFieldsSelect',
|
|
'x-disabled': '{{ !createOnly || isOverride }}',
|
|
'x-reactions': [
|
|
{
|
|
target: APPENDS,
|
|
when: '{{$self.value != undefined}}',
|
|
fulfill: {
|
|
state: {
|
|
visible: true,
|
|
},
|
|
},
|
|
otherwise: {
|
|
state: {
|
|
visible: false,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
[APPENDS]: {
|
|
type: 'string',
|
|
title: `{{t("Snapshot the snapshot's association fields", {ns: "${NAMESPACE}"})}}`,
|
|
'x-decorator': 'FormItem',
|
|
'x-component': 'AppendsTreeSelect',
|
|
'x-component-props': {
|
|
multiple: true,
|
|
useCollection: useRecordCollection,
|
|
},
|
|
'x-reactions': [
|
|
{
|
|
dependencies: [TARGET_FIELD],
|
|
when: '{{$deps[0]}}',
|
|
fulfill: {
|
|
run: '{{$self.setValue($self.value)}}',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
};
|