@nocobase/plugin-map 0.9.1-alpha.2 → 0.9.2-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.
Files changed (85) hide show
  1. package/docs/en-US/changelog.md +1 -0
  2. package/docs/en-US/index.md +1 -0
  3. package/docs/en-US/installation.md +1 -0
  4. package/docs/en-US/tabs.json +18 -0
  5. package/docs/en-US/usage.md +1 -0
  6. package/docs/zh-CN/changelog.md +1 -0
  7. package/docs/zh-CN/index.md +1 -0
  8. package/docs/zh-CN/installation.md +1 -0
  9. package/docs/zh-CN/tabs.json +18 -0
  10. package/docs/zh-CN/usage.md +1 -0
  11. package/lib/client/block/MapActionInitializers.d.ts +89 -0
  12. package/lib/client/block/MapActionInitializers.js +93 -0
  13. package/lib/client/block/MapBlock.d.ts +1 -0
  14. package/lib/client/block/MapBlock.js +358 -0
  15. package/lib/client/block/MapBlockDesigner.d.ts +1 -0
  16. package/lib/client/block/MapBlockDesigner.js +196 -0
  17. package/lib/client/block/MapBlockInitializer.d.ts +1 -0
  18. package/lib/client/block/MapBlockInitializer.js +122 -0
  19. package/lib/client/block/MapBlockProvider.d.ts +5 -0
  20. package/lib/client/block/MapBlockProvider.js +91 -0
  21. package/lib/client/block/index.d.ts +2 -0
  22. package/lib/client/block/index.js +58 -0
  23. package/lib/client/block/utils.d.ts +56 -0
  24. package/lib/client/block/utils.js +102 -0
  25. package/lib/client/components/AMap.d.ts +32 -6
  26. package/lib/client/components/AMap.js +152 -203
  27. package/lib/client/components/Configuration.js +11 -45
  28. package/lib/client/components/Designer.js +6 -40
  29. package/lib/client/components/Map.d.ts +4 -1
  30. package/lib/client/components/Map.js +4 -18
  31. package/lib/client/components/ReadPretty.js +12 -29
  32. package/lib/client/components/Search.js +31 -65
  33. package/lib/client/constants.js +0 -2
  34. package/lib/client/fields/circle.js +3 -8
  35. package/lib/client/fields/index.js +0 -5
  36. package/lib/client/fields/lineString.js +3 -8
  37. package/lib/client/fields/point.js +3 -8
  38. package/lib/client/fields/polygon.js +3 -8
  39. package/lib/client/fields/schema.d.ts +1 -2
  40. package/lib/client/fields/schema.js +3 -18
  41. package/lib/client/hooks/index.js +0 -2
  42. package/lib/client/hooks/useMapConfiguration.d.ts +1 -0
  43. package/lib/client/hooks/useMapConfiguration.js +28 -8
  44. package/lib/client/index.d.ts +1 -0
  45. package/lib/client/index.js +8 -26
  46. package/lib/client/initialize.d.ts +1 -1
  47. package/lib/client/initialize.js +4 -21
  48. package/lib/client/locale/index.js +6 -13
  49. package/lib/client/locale/pt-BR.d.ts +46 -0
  50. package/lib/client/locale/pt-BR.js +54 -0
  51. package/lib/client/locale/zh-CN.d.ts +5 -2
  52. package/lib/client/locale/zh-CN.js +21 -18
  53. package/lib/index.js +0 -2
  54. package/lib/server/actions/index.js +0 -11
  55. package/lib/server/collections/mapConfiguration.d.ts +1 -1
  56. package/lib/server/collections/mapConfiguration.js +1 -3
  57. package/lib/server/fields/circle.js +3 -22
  58. package/lib/server/fields/index.js +0 -8
  59. package/lib/server/fields/lineString.js +3 -22
  60. package/lib/server/fields/point.js +3 -23
  61. package/lib/server/fields/polygon.js +3 -21
  62. package/lib/server/helpers/index.js +0 -12
  63. package/lib/server/index.js +0 -2
  64. package/lib/server/plugin.js +0 -24
  65. package/lib/server/value-parsers/index.js +0 -21
  66. package/package.json +8 -5
  67. package/src/client/block/MapActionInitializers.tsx +97 -0
  68. package/src/client/block/MapBlock.tsx +308 -0
  69. package/src/client/block/MapBlockDesigner.tsx +161 -0
  70. package/src/client/block/MapBlockInitializer.tsx +76 -0
  71. package/src/client/block/MapBlockProvider.tsx +55 -0
  72. package/src/client/block/index.tsx +35 -0
  73. package/src/client/block/utils.ts +81 -0
  74. package/src/client/components/AMap.tsx +148 -71
  75. package/src/client/components/Configuration.tsx +2 -1
  76. package/src/client/components/Map.tsx +5 -2
  77. package/src/client/components/ReadPretty.tsx +6 -5
  78. package/src/client/fields/schema.ts +4 -7
  79. package/src/client/hooks/useMapConfiguration.ts +32 -9
  80. package/src/client/index.tsx +11 -7
  81. package/src/client/initialize.tsx +2 -2
  82. package/src/client/locale/index.ts +4 -3
  83. package/src/client/locale/pt-BR.ts +49 -0
  84. package/src/client/locale/zh-CN.ts +22 -19
  85. package/src/server/collections/mapConfiguration.ts +8 -8
@@ -0,0 +1,161 @@
1
+ import { ISchema, useField, useFieldSchema } from '@formily/react';
2
+ import {
3
+ FilterBlockType,
4
+ FixedBlockDesignerItem,
5
+ GeneralSchemaDesigner,
6
+ SchemaSettings,
7
+ mergeFilter,
8
+ useCollection,
9
+ useCollectionFilterOptions,
10
+ useCollectionManager,
11
+ useDesignable,
12
+ useSchemaTemplate,
13
+ } from '@nocobase/client';
14
+ import set from 'lodash/set';
15
+ import React from 'react';
16
+ import { useTranslation } from 'react-i18next';
17
+ import { useMapTranslation } from '../locale';
18
+ import { useMapBlockContext } from './MapBlockProvider';
19
+
20
+ export const MapBlockDesigner = () => {
21
+ const { name, title } = useCollection();
22
+ const field = useField();
23
+ const fieldSchema = useFieldSchema();
24
+ const dataSource = useCollectionFilterOptions(name);
25
+ const { service } = useMapBlockContext();
26
+ const { t: mapT } = useMapTranslation();
27
+ const { t } = useTranslation();
28
+ const { dn } = useDesignable();
29
+ const { getCollectionFieldsOptions } = useCollectionManager();
30
+ const collection = useCollection();
31
+ const defaultFilter = fieldSchema?.['x-decorator-props']?.params?.filter || {};
32
+ const defaultResource = fieldSchema?.['x-decorator-props']?.resource;
33
+ const fieldNames = fieldSchema?.['x-decorator-props']?.['fieldNames'] || {};
34
+ const defaultZoom = fieldSchema?.['x-component-props']?.['zoom'] || 13;
35
+
36
+ const template = useSchemaTemplate();
37
+
38
+ const mapFieldOptions = getCollectionFieldsOptions(collection?.name, ['point', 'lineString', 'polygon']);
39
+ const markerFieldOptions = getCollectionFieldsOptions(collection?.name, 'string');
40
+
41
+ return (
42
+ <GeneralSchemaDesigner template={template} title={title || name}>
43
+ <SchemaSettings.BlockTitleItem />
44
+ <FixedBlockDesignerItem />
45
+ <SchemaSettings.SelectItem
46
+ title={mapT('Map field')}
47
+ value={fieldNames.field}
48
+ options={mapFieldOptions}
49
+ onChange={(v) => {
50
+ const fieldNames = field.decoratorProps.fieldNames || {};
51
+ fieldNames['field'] = v;
52
+ field.decoratorProps.fieldNames = fieldNames;
53
+ fieldSchema['x-decorator-props']['fieldNames'] = fieldNames;
54
+ service.refresh();
55
+ dn.emit('patch', {
56
+ schema: {
57
+ ['x-uid']: fieldSchema['x-uid'],
58
+ 'x-decorator-props': field.decoratorProps,
59
+ },
60
+ });
61
+ dn.refresh();
62
+ }}
63
+ />
64
+ <SchemaSettings.SelectItem
65
+ title={mapT('Marker field')}
66
+ value={fieldNames.marker}
67
+ options={markerFieldOptions}
68
+ onChange={(v) => {
69
+ const fieldNames = field.decoratorProps.fieldNames || {};
70
+ fieldNames['marker'] = v;
71
+ field.decoratorProps.fieldNames = fieldNames;
72
+ fieldSchema['x-decorator-props']['fieldNames'] = fieldNames;
73
+ service.refresh();
74
+ dn.emit('patch', {
75
+ schema: {
76
+ ['x-uid']: fieldSchema['x-uid'],
77
+ 'x-decorator-props': field.decoratorProps,
78
+ },
79
+ });
80
+ dn.refresh();
81
+ }}
82
+ />
83
+ <SchemaSettings.ModalItem
84
+ title={mapT('The default zoom level of the map')}
85
+ schema={
86
+ {
87
+ type: 'object',
88
+ title: mapT('Set default zoom level'),
89
+ properties: {
90
+ zoom: {
91
+ title: mapT('Zoom'),
92
+ default: defaultZoom,
93
+ 'x-component': 'InputNumber',
94
+ 'x-decorator': 'FormItem',
95
+ 'x-component-props': {
96
+ precision: 0,
97
+ },
98
+ },
99
+ },
100
+ } as ISchema
101
+ }
102
+ onSubmit={({ zoom }) => {
103
+ set(fieldSchema, 'x-component-props.zoom', zoom);
104
+ Object.assign(field.componentProps, fieldSchema['x-component-props']);
105
+ dn.emit('patch', {
106
+ schema: {
107
+ 'x-uid': fieldSchema['x-uid'],
108
+ 'x-component-props': field.componentProps,
109
+ },
110
+ });
111
+ dn.refresh();
112
+ }}
113
+ ></SchemaSettings.ModalItem>
114
+ <SchemaSettings.ModalItem
115
+ title={t('Set the data scope')}
116
+ schema={
117
+ {
118
+ type: 'object',
119
+ title: t('Set the data scope'),
120
+ properties: {
121
+ filter: {
122
+ default: defaultFilter,
123
+ // title: '数据范围',
124
+ enum: dataSource,
125
+ 'x-component': 'Filter',
126
+ 'x-component-props': {},
127
+ },
128
+ },
129
+ } as ISchema
130
+ }
131
+ onSubmit={({ filter }) => {
132
+ const params = field.decoratorProps.params || {};
133
+ params.filter = filter;
134
+ field.decoratorProps.params = params;
135
+ fieldSchema['x-decorator-props']['params'] = params;
136
+ const filters = service.params?.[1]?.filters || {};
137
+ service.run(
138
+ { ...service.params?.[0], filter: mergeFilter([...Object.values(filters), filter]), page: 1 },
139
+ { filters },
140
+ );
141
+ dn.emit('patch', {
142
+ schema: {
143
+ ['x-uid']: fieldSchema['x-uid'],
144
+ 'x-decorator-props': fieldSchema['x-decorator-props'],
145
+ },
146
+ });
147
+ }}
148
+ />
149
+ <SchemaSettings.ConnectDataBlocks type={FilterBlockType.TABLE} emptyDescription={t('No blocks to connect')} />
150
+ <SchemaSettings.Divider />
151
+ <SchemaSettings.Template componentName={'Map'} collectionName={name} resourceName={defaultResource} />
152
+ <SchemaSettings.Divider />
153
+ <SchemaSettings.Remove
154
+ removeParentsIfNoChildren
155
+ breakRemoveOn={{
156
+ 'x-component': 'Grid',
157
+ }}
158
+ />
159
+ </GeneralSchemaDesigner>
160
+ );
161
+ };
@@ -0,0 +1,76 @@
1
+ import { TableOutlined } from '@ant-design/icons';
2
+ import { DataBlockInitializer, SchemaComponent, SchemaComponentOptions, useCollectionManager } from '@nocobase/client';
3
+ import { SchemaOptionsContext } from '@formily/react';
4
+ import { FormDialog, FormLayout } from '@formily/antd';
5
+ import React, { useContext } from 'react';
6
+ import { useMapTranslation } from '../locale';
7
+ import { createMapBlockSchema } from './utils';
8
+
9
+ export const MapBlockInitializer = (props) => {
10
+ const { insert } = props;
11
+ const options = useContext(SchemaOptionsContext);
12
+ const { getCollectionFieldsOptions } = useCollectionManager();
13
+ const { t } = useMapTranslation();
14
+
15
+ return (
16
+ <DataBlockInitializer
17
+ {...props}
18
+ componentType={'Map'}
19
+ icon={<TableOutlined />}
20
+ onCreateBlockSchema={async ({ item }) => {
21
+ const mapFieldOptions = getCollectionFieldsOptions(item.name, ['point', 'lineString', 'polygon']);
22
+ const markerFieldOptions = getCollectionFieldsOptions(item.name, 'string');
23
+ const values = await FormDialog(t('Create map block'), () => {
24
+ return (
25
+ <SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
26
+ <FormLayout layout={'vertical'}>
27
+ <SchemaComponent
28
+ schema={{
29
+ properties: {
30
+ field: {
31
+ title: t('Map field'),
32
+ enum: mapFieldOptions,
33
+ required: true,
34
+ 'x-component': 'Select',
35
+ 'x-decorator': 'FormItem',
36
+ default: mapFieldOptions[0]?.value
37
+ },
38
+ marker: {
39
+ title: t('Marker field'),
40
+ enum: markerFieldOptions,
41
+ 'x-component': 'Select',
42
+ 'x-decorator': 'FormItem',
43
+ 'x-reactions': (field) => {
44
+ const value = field.form.values.field
45
+ console.log("🚀 ~ file: MapBlockInitializer.tsx:45 ~ values ~ value:", value)
46
+ console.log("🚀 ~ file: MapBlockInitializer.tsx:50 ~ values ~ mapFieldOptions:", mapFieldOptions)
47
+
48
+ if (!value) {
49
+ return
50
+ }
51
+ const item = mapFieldOptions.find((item) => item.value === value).type
52
+ field.hidden = item !== 'point'
53
+ },
54
+ },
55
+ },
56
+ }}
57
+ />
58
+ </FormLayout>
59
+ </SchemaComponentOptions>
60
+ );
61
+ }).open({
62
+ initialValues: {},
63
+ });
64
+ insert(
65
+ createMapBlockSchema({
66
+ collection: item.name,
67
+ fieldNames: {
68
+ ...values,
69
+ },
70
+ }),
71
+ );
72
+ }}
73
+ title={t('Map block')}
74
+ />
75
+ );
76
+ };
@@ -0,0 +1,55 @@
1
+ import { useField, useFieldSchema } from '@formily/react';
2
+ import { BlockProvider, FixedBlockWrapper, SchemaComponentOptions, useBlockRequestContext } from '@nocobase/client';
3
+ import React, { createContext, useContext, useState } from 'react';
4
+
5
+ export const MapBlockContext = createContext<any>({});
6
+
7
+ const InternalMapBlockProvider = (props) => {
8
+ const { fieldNames } = props;
9
+ const fieldSchema = useFieldSchema();
10
+ const field = useField();
11
+ const { resource, service } = useBlockRequestContext();
12
+ const [selectedRecordKeys, setSelectedRecordKeys] = useState([]);
13
+
14
+ return (
15
+ <FixedBlockWrapper>
16
+ <SchemaComponentOptions scope={{ selectedRecordKeys }}>
17
+ <MapBlockContext.Provider
18
+ value={{
19
+ field,
20
+ service,
21
+ resource,
22
+ fieldNames,
23
+ fixedBlock: fieldSchema?.['x-decorator-props']?.fixedBlock,
24
+ selectedRecordKeys,
25
+ setSelectedRecordKeys,
26
+ }}
27
+ >
28
+ {props.children}
29
+ </MapBlockContext.Provider>
30
+ </SchemaComponentOptions>
31
+ </FixedBlockWrapper>
32
+ );
33
+ };
34
+
35
+ export const MapBlockProvider = (props) => {
36
+ return (
37
+ <BlockProvider {...props} params={{ ...props.params, paginate: false }}>
38
+ <InternalMapBlockProvider {...props} />
39
+ </BlockProvider>
40
+ );
41
+ };
42
+
43
+ export const useMapBlockContext = () => {
44
+ return useContext(MapBlockContext);
45
+ };
46
+
47
+ export const useMapBlockProps = () => {
48
+ const ctx = useMapBlockContext();
49
+
50
+ return {
51
+ ...ctx,
52
+ dataSource: ctx?.service?.data?.data,
53
+ zoom: ctx?.field?.componentProps?.zoom || 13,
54
+ };
55
+ };
@@ -0,0 +1,35 @@
1
+ import { SchemaComponentOptions, SchemaInitializerContext, SchemaInitializerProvider } from '@nocobase/client';
2
+ import React, { useContext, useEffect } from 'react';
3
+ import { generateNTemplate } from '../locale';
4
+ import { MapActionInitializers } from './MapActionInitializers';
5
+ import { MapBlock } from './MapBlock';
6
+ import { MapBlockDesigner } from './MapBlockDesigner';
7
+ import { MapBlockInitializer } from './MapBlockInitializer';
8
+ import { MapBlockProvider, useMapBlockProps } from './MapBlockProvider';
9
+
10
+ export const MapBlockOptions: React.FC = (props) => {
11
+ const items = useContext(SchemaInitializerContext);
12
+ const children = items.BlockInitializers.items[0].children;
13
+
14
+ useEffect(() => {
15
+ if (!children.find((item) => item.component === 'MapBlockInitializer')) {
16
+ children.push({
17
+ key: 'mapBlock',
18
+ type: 'item',
19
+ title: generateNTemplate('Map'),
20
+ component: 'MapBlockInitializer',
21
+ });
22
+ }
23
+ }, []);
24
+
25
+ return (
26
+ <SchemaInitializerProvider initializers={{ MapActionInitializers }}>
27
+ <SchemaComponentOptions
28
+ scope={{ useMapBlockProps }}
29
+ components={{ MapBlockInitializer, MapBlockDesigner, MapBlockProvider, MapBlock }}
30
+ >
31
+ {props.children}
32
+ </SchemaComponentOptions>
33
+ </SchemaInitializerProvider>
34
+ );
35
+ };
@@ -0,0 +1,81 @@
1
+ import { ISchema } from '@formily/react';
2
+ import { uid } from '@formily/shared';
3
+
4
+ export const createMapBlockSchema = (options) => {
5
+ const { collection, resource, fieldNames, ...others } = options;
6
+ const schema: ISchema = {
7
+ type: 'void',
8
+ 'x-acl-action': `${resource || collection}:list`,
9
+ 'x-decorator': 'MapBlockProvider',
10
+ 'x-decorator-props': {
11
+ collection: collection,
12
+ resource: resource || collection,
13
+ action: 'list',
14
+ fieldNames,
15
+ params: {
16
+ paginate: false,
17
+ },
18
+ ...others,
19
+ },
20
+ 'x-designer': 'MapBlockDesigner',
21
+ 'x-component': 'CardItem',
22
+ // 保存当前筛选区块所能过滤的数据区块
23
+ 'x-filter-targets': [],
24
+ properties: {
25
+ actions: {
26
+ type: 'void',
27
+ 'x-initializer': 'MapActionInitializers',
28
+ 'x-component': 'ActionBar',
29
+ 'x-component-props': {
30
+ style: {
31
+ marginBottom: 16,
32
+ },
33
+ },
34
+ properties: {},
35
+ },
36
+ [uid()]: {
37
+ type: 'void',
38
+ 'x-component': 'MapBlock',
39
+ 'x-component-props': {
40
+ useProps: '{{ useMapBlockProps }}',
41
+ },
42
+ properties: {
43
+ drawer: {
44
+ type: 'void',
45
+ 'x-component': 'Action.Drawer',
46
+ 'x-component-props': {
47
+ className: 'nb-action-popup',
48
+ },
49
+ title: '{{ t("View record") }}',
50
+ properties: {
51
+ tabs: {
52
+ type: 'void',
53
+ 'x-component': 'Tabs',
54
+ 'x-component-props': {},
55
+ 'x-initializer': 'TabPaneInitializers',
56
+ properties: {
57
+ tab1: {
58
+ type: 'void',
59
+ title: '{{t("Details")}}',
60
+ 'x-component': 'Tabs.TabPane',
61
+ 'x-designer': 'Tabs.Designer',
62
+ 'x-component-props': {},
63
+ properties: {
64
+ grid: {
65
+ type: 'void',
66
+ 'x-component': 'Grid',
67
+ 'x-initializer': 'RecordBlockInitializers',
68
+ properties: {},
69
+ },
70
+ },
71
+ },
72
+ },
73
+ },
74
+ },
75
+ },
76
+ },
77
+ },
78
+ },
79
+ };
80
+ return schema;
81
+ };