mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 15:39:24 +08:00
fix: data scope
This commit is contained in:
parent
4e3fd75c8e
commit
afc285f697
@ -8,31 +8,32 @@
|
||||
*/
|
||||
|
||||
export {
|
||||
useCancelAction,
|
||||
useCollectionFilterOptions,
|
||||
useSortFields,
|
||||
useLinkageCollectionFilterOptions,
|
||||
useCollectionFieldsOptions,
|
||||
isDeleteButtonDisabled,
|
||||
useCancelAction,
|
||||
useCollectionFieldsOptions,
|
||||
useCollectionFilterOptions,
|
||||
useCollectionFilterOptionsV2,
|
||||
useLinkageCollectionFilterOptions,
|
||||
useSortFields,
|
||||
} from './action-hooks';
|
||||
export * from './CollectionHistoryProvider';
|
||||
export * from './CollectionManagerProvider';
|
||||
export * from './CollectionManagerSchemaComponentProvider';
|
||||
export * from './collectionPlugin';
|
||||
export * from './CollectionProvider_deprecated';
|
||||
export * from './Configuration';
|
||||
export { useFieldInterfaceOptions } from './Configuration/interfaces';
|
||||
export * from './context';
|
||||
export * from './hooks';
|
||||
export * from './interfaces';
|
||||
export * from './interfaces/properties';
|
||||
export * as interfacesProperties from './interfaces/properties';
|
||||
export * from './interfaces/types';
|
||||
export * from './mixins/InheritanceCollectionMixin';
|
||||
export * from './ResourceActionProvider';
|
||||
export * from './sub-table';
|
||||
export { UnSupportFields } from './templates/components/UnSupportFields';
|
||||
export { getConfigurableProperties } from './templates/properties';
|
||||
export * from './templates/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 { UnSupportFields } from './templates/components/UnSupportFields';
|
||||
|
@ -8,28 +8,23 @@ import {
|
||||
SchemaSettingsModalItem,
|
||||
TableBlockProvider,
|
||||
useTableBlockProps,
|
||||
Variable,
|
||||
} from '@nocobase/client';
|
||||
import { mockApp } from '@nocobase/client/demo-utils';
|
||||
import { property } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
const DataScopeEditor = (props) => {
|
||||
// const { getFields } = useCollectionFilterOptionsV2('roles');
|
||||
const getSchema = () => ({
|
||||
type: 'object',
|
||||
title: 'Set the data scope',
|
||||
properties: {
|
||||
// enum: getFields(),
|
||||
filter: {
|
||||
'x-component': 'Filter',
|
||||
'x-component-props': {
|
||||
collectionName: 'users',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return <SchemaSettingsModalItem title="Data Scope" width={800} onSubmit={(v) => null} schema={getSchema} />;
|
||||
};
|
||||
const scopes = [
|
||||
{
|
||||
label: 'Date',
|
||||
value: '$date',
|
||||
children: [
|
||||
{ label: 'Now', value: 'now' },
|
||||
{ label: 'Today', value: 'today_with_tz' },
|
||||
{ label: 'Today', value: 'today_without_tz' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const dataScopeSettings = new SchemaSettings({
|
||||
name: 'dataScopeSettings',
|
||||
@ -38,7 +33,96 @@ const dataScopeSettings = new SchemaSettings({
|
||||
name: 'data scope',
|
||||
Component: SchemaSettingsDataScope,
|
||||
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>
|
||||
|
||||
#### 2. Filter 组件
|
||||
<code src="./demos/filter-demo.tsx"></code>
|
||||
|
||||
<!-- #### 2. 数据范围
|
||||
<code src="./demos/data-scope-demo.tsx"></code> -->
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user