fix: data scope

This commit is contained in:
sheldon66 2025-03-30 21:34:05 +08:00
parent 4e3fd75c8e
commit afc285f697
5 changed files with 409 additions and 30 deletions

View File

@ -8,31 +8,32 @@
*/ */
export { export {
useCancelAction,
useCollectionFilterOptions,
useSortFields,
useLinkageCollectionFilterOptions,
useCollectionFieldsOptions,
isDeleteButtonDisabled, isDeleteButtonDisabled,
useCancelAction,
useCollectionFieldsOptions,
useCollectionFilterOptions,
useCollectionFilterOptionsV2,
useLinkageCollectionFilterOptions,
useSortFields,
} from './action-hooks'; } from './action-hooks';
export * from './CollectionHistoryProvider';
export * from './CollectionManagerProvider'; export * from './CollectionManagerProvider';
export * from './CollectionManagerSchemaComponentProvider'; export * from './CollectionManagerSchemaComponentProvider';
export * from './collectionPlugin';
export * from './CollectionProvider_deprecated'; export * from './CollectionProvider_deprecated';
export * from './Configuration'; export * from './Configuration';
export { useFieldInterfaceOptions } from './Configuration/interfaces'; export { useFieldInterfaceOptions } from './Configuration/interfaces';
export * from './context'; export * from './context';
export * from './hooks'; export * from './hooks';
export * from './interfaces';
export * from './interfaces/properties';
export * as interfacesProperties from './interfaces/properties'; export * as interfacesProperties from './interfaces/properties';
export * from './interfaces/types'; export * from './interfaces/types';
export * from './mixins/InheritanceCollectionMixin';
export * from './ResourceActionProvider'; export * from './ResourceActionProvider';
export * from './sub-table';
export { UnSupportFields } from './templates/components/UnSupportFields';
export { getConfigurableProperties } from './templates/properties'; export { getConfigurableProperties } from './templates/properties';
export * from './templates/types'; export * from './templates/types';
export * from './types'; export * from './types';
export * from './interfaces';
export * from './interfaces/properties';
export * from './collectionPlugin';
export * from './mixins/InheritanceCollectionMixin';
export * from './sub-table';
export * from './CollectionHistoryProvider';
export * from './utils'; export * from './utils';
export { UnSupportFields } from './templates/components/UnSupportFields';

View File

@ -8,28 +8,23 @@ import {
SchemaSettingsModalItem, SchemaSettingsModalItem,
TableBlockProvider, TableBlockProvider,
useTableBlockProps, useTableBlockProps,
Variable,
} from '@nocobase/client'; } from '@nocobase/client';
import { mockApp } from '@nocobase/client/demo-utils'; import { mockApp } from '@nocobase/client/demo-utils';
import { property } from 'lodash'; import { property } from 'lodash';
import React from 'react'; import React from 'react';
const DataScopeEditor = (props) => { const scopes = [
// const { getFields } = useCollectionFilterOptionsV2('roles'); {
const getSchema = () => ({ label: 'Date',
type: 'object', value: '$date',
title: 'Set the data scope', children: [
properties: { { label: 'Now', value: 'now' },
// enum: getFields(), { label: 'Today', value: 'today_with_tz' },
filter: { { label: 'Today', value: 'today_without_tz' },
'x-component': 'Filter', ],
'x-component-props': { },
collectionName: 'users', ];
},
},
},
});
return <SchemaSettingsModalItem title="Data Scope" width={800} onSubmit={(v) => null} schema={getSchema} />;
};
const dataScopeSettings = new SchemaSettings({ const dataScopeSettings = new SchemaSettings({
name: 'dataScopeSettings', name: 'dataScopeSettings',
@ -38,7 +33,96 @@ const dataScopeSettings = new SchemaSettings({
name: 'data scope', name: 'data scope',
Component: SchemaSettingsDataScope, Component: SchemaSettingsDataScope,
componentProps: { componentProps: {
collectionName: 'users', collectionName: 'date_collection',
},
useComponentProps() {
return {
collectionName: 'date_collection',
dynamicComponent: (props) => {
const { collectionField } = props;
let scopes = [];
// For date/datetime fields
if (['date', 'datetime'].includes(collectionField?.interface)) {
scopes = [
{
label: 'Date',
value: '$date',
children: [
{
label: 'Now',
value: 'now',
},
{
label: 'Today',
value: 'today',
},
{
label: 'Yesterday',
value: 'yesterday',
},
{
label: 'Tomorrow',
value: 'tomorrow',
},
],
},
];
}
// For number fields
else if (['integer', 'number', 'percent'].includes(collectionField?.interface)) {
scopes = [
{
label: 'Number',
value: '$number',
children: [
{
label: 'Random',
value: 'random',
},
{
label: 'Maximum',
value: 'max',
},
{
label: 'Minimum',
value: 'min',
},
],
},
];
}
// For string fields
else if (['input', 'textarea', 'markdown'].includes(collectionField?.interface)) {
scopes = [
{
label: 'String',
value: '$string',
children: [
{
label: 'Current User',
value: 'currentUser',
children: [
{
label: 'Name',
value: 'name',
},
{
label: 'Email',
value: 'email',
},
],
},
],
},
];
}
return <Variable.Input {...props} scope={scopes} />;
},
};
}, },
}, },
], ],

View File

@ -0,0 +1,192 @@
import { ISchema, Schema, useField, useFieldSchema } from '@formily/react';
import {
Plugin,
SchemaComponent,
SchemaSettings,
SchemaSettingsModalItem,
Variable,
VariableEvaluateProvider,
useVariableEvaluateContext,
CollectionField,
} from '@nocobase/client';
import { mockApp } from '@nocobase/client/demo-utils';
import { dayjs } from '@nocobase/utils/client';
import React from 'react';
const DefaultValueEditor = () => {
const fieldSchema = useFieldSchema();
const collectionField = fieldSchema['x-component-props']?.['field'];
const fieldType = collectionField?.interface;
// Define date variable scopes based on field type
const dateScopes = {
date: [
{ label: 'Today', value: 'today_dateOnly' },
{ label: 'Yesterday', value: 'yesterday_dateOnly' },
{ label: 'Tomorrow', value: 'tomorrow_dateOnly' },
],
datetime: [
{ label: 'Now', value: 'now_withTZ' },
{ label: 'Today', value: 'today_withTZ' },
{ label: 'Yesterday', value: 'yesterday_withTZ' },
{ label: 'Tomorrow', value: 'tomorrow_withTZ' },
],
datetimeNoTz: [
{ label: 'Now', value: 'now_withoutTZ' },
{ label: 'Today', value: 'today_withoutTZ' },
{ label: 'Yesterday', value: 'yesterday_withoutTZ' },
{ label: 'Tomorrow', value: 'tomorrow_withoutTZ' },
],
};
const scope = dateScopes[fieldType] || [];
// Define data with various date formats
const data = {
// Date only formats
today_dateOnly: dayjs().format('YYYY-MM-DD'),
yesterday_dateOnly: dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
tomorrow_dateOnly: dayjs().add(1, 'day').format('YYYY-MM-DD'),
// Datetime with timezone formats
now_withTZ: new Date().toISOString(),
today_withTZ: dayjs().startOf('day').toISOString(),
yesterday_withTZ: dayjs().subtract(1, 'day').startOf('day').toISOString(),
tomorrow_withTZ: dayjs().add(1, 'day').startOf('day').toISOString(),
// Datetime without timezone formats
now_withoutTZ: dayjs().format('YYYY-MM-DD HH:mm:ss'),
today_withoutTZ: dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),
yesterday_withoutTZ: dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
tomorrow_withoutTZ: dayjs().add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
};
const defaultValueSchema = {
type: 'object',
'x-component-props': {
data,
context: {},
},
properties: {
variable: {
'x-decorator': 'FormItem',
'x-component': 'VariableInput',
},
value: {
'x-decorator': 'FormItem',
'x-component': 'VariableValue',
},
},
};
const VariableInput = (props) => {
return (
<VariableEvaluateProvider data={data} context={{}}>
<Variable.Input scope={scope} {...props} />
</VariableEvaluateProvider>
);
};
return (
<VariableEvaluateProvider data={data} context={{}}>
<SchemaSettingsModalItem
title={'Set default value'}
width={800}
onSubmit={(v) => null}
schema={defaultValueSchema}
components={{ VariableInput }}
/>
</VariableEvaluateProvider>
);
};
const dateSettings = new SchemaSettings({
name: 'dateSettings',
items: [
{
name: 'defaultValue',
Component: DefaultValueEditor,
},
],
});
const schema: ISchema = {
type: 'void',
name: 'root',
'x-decorator': 'FormBlockProvider',
'x-decorator-props': {
collection: 'date_collection', // users 数据表
dataSource: 'main', // 多数据源标识,可以不写,默认为 main
},
'x-component': 'FormV2',
properties: {
dateonly: {
type: 'string',
title: 'DateOnly',
'x-decorator': 'FormItem',
'x-component': 'CollectionField',
'x-settings': 'dateSettings',
required: true,
},
datetime: {
type: 'string',
title: 'Datetime with Timezone',
'x-decorator': 'FormItem',
'x-component': 'CollectionField',
'x-settings': 'dateSettings',
'x-component-props': {
field: {
interface: 'datetime',
type: 'date',
uiSchema: {
'x-component': 'DatePicker',
'x-component-props': {
showTime: true,
utc: true,
},
},
},
},
required: true,
},
datetime_withoutTZ: {
type: 'string',
title: 'Datetime without Timezone',
'x-decorator': 'FormItem',
'x-component': 'CollectionField',
'x-settings': 'dateSettings',
'x-component-props': {
field: {
interface: 'datetimeNoTz',
type: 'datetimeNoTz',
uiSchema: {
'x-component': 'DatePicker',
'x-component-props': {
showTime: true,
utc: false,
},
},
},
},
required: true,
},
},
};
const Demo = () => {
return <SchemaComponent schema={schema} />;
};
class DemoPlugin extends Plugin {
async load() {
this.app.router.add('root', { path: '/', Component: Demo });
}
}
const app = mockApp({
designable: true,
plugins: [DemoPlugin],
schemaSettings: [dateSettings],
});
export default app.getRootComponent();

View File

@ -0,0 +1,99 @@
import {
AntdSchemaComponentProvider,
Filter,
Plugin,
SchemaComponent,
useCollectionFilterOptionsV2,
Variable,
VariableEvaluateProvider,
} from '@nocobase/client';
import { mockApp } from '@nocobase/client/demo-utils';
import PluginVariableFiltersClient from '@nocobase/plugin-variable-helpers/client';
import { dayjs } from '@nocobase/utils/client';
import { now } from 'lodash';
import React, { useCallback } from 'react';
const scope = [
{ label: 'v1', value: 'v1' },
{ label: 'Date', value: '$nDate', children: [{ label: 'Now', value: 'now' }] },
];
const Demo = () => {
const useFilterProps = () => {
const dynamicComponent = useCallback((props) => {
const data = {
// Date only formats
today_dateOnly: dayjs().format('YYYY-MM-DD'),
yesterday_dateOnly: dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
tomorrow_dateOnly: dayjs().add(1, 'day').format('YYYY-MM-DD'),
now_ts_s: new Date().getTime(),
};
const dateScopesByType = {
dateOnly: [
{ label: 'Today', value: 'today_dateOnly' },
{ label: 'Yesterday', value: 'yesterday_dateOnly' },
{ label: 'Tomorrow', value: 'tomorrow_dateOnly' },
],
datetime: [
{ label: 'Now', value: 'now_withTZ' },
{ label: 'Today', value: 'today_withTZ' },
{ label: 'Yesterday', value: 'yesterday_withTZ' },
{ label: 'Tomorrow', value: 'tomorrow_withTZ' },
],
unixTimestamp: [{ label: 'Now', value: 'now_ts_s' }],
datetimeNoTz: [
{ label: 'Now', value: 'now_withoutTZ' },
{ label: 'Today', value: 'today_withoutTZ' },
{ label: 'Yesterday', value: 'yesterday_withoutTZ' },
{ label: 'Tomorrow', value: 'tomorrow_withoutTZ' },
],
};
const { collectionField } = props;
const scope = dateScopesByType[collectionField?.type] || [];
return (
<VariableEvaluateProvider data={data} context={{}}>
<Variable.Input scope={scope} {...props} />
</VariableEvaluateProvider>
);
}, []);
return { dynamicComponent, collectionName: 'date_collection' };
};
const { getFields } = useCollectionFilterOptionsV2('date_collection');
const schema = {
type: 'void',
name: 'root',
'x-decorator': 'FormBlockProvider',
'x-decorator-props': {
collection: 'date_collection', // users 数据表
dataSource: 'main', // 多数据源标识,可以不写,默认为 main
},
properties: {
filter: {
enum: getFields(),
name: 'filter',
type: 'object',
title: 'Filter',
'x-component': 'Filter',
'x-component-props': {
collectionName: 'date_collection',
},
'x-use-component-props': 'useFilterProps',
},
},
};
return (
<AntdSchemaComponentProvider>
<SchemaComponent schema={schema} scope={{ useFilterProps }} components={{ Filter }} />
</AntdSchemaComponentProvider>
);
};
class DemoPlugin extends Plugin {
async load() {
this.app.router.add('root', { path: '/', Component: Demo });
}
}
const app = mockApp({ plugins: [DemoPlugin, PluginVariableFiltersClient] });
export default app.getRootComponent();

View File

@ -77,6 +77,9 @@ const scope = [
<code src="./demos/form-default-value.tsx"></code> <code src="./demos/form-default-value.tsx"></code>
#### 2. Filter 组件
<code src="./demos/filter-demo.tsx"></code>
<!-- #### 2. 数据范围 <!-- #### 2. 数据范围
<code src="./demos/data-scope-demo.tsx"></code> --> <code src="./demos/data-scope-demo.tsx"></code> -->