mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 23:49:27 +08:00
fix: data scope
This commit is contained in:
parent
4e3fd75c8e
commit
afc285f697
@ -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';
|
|
||||||
|
@ -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} />;
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -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();
|
@ -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();
|
@ -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> -->
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user