@nocobase/plugin-workflow-aggregate 1.0.0-alpha.2 → 1.0.0-alpha.3

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.
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import React from 'react';
2
10
  import { SchemaInitializerItemType, useCollectionDataSource } from '@nocobase/client';
3
11
  import { FilterDynamicComponent, Instruction } from '@nocobase/plugin-workflow/client';
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import { Plugin } from '@nocobase/client';
2
10
  export default class extends Plugin {
3
11
  afterAdd(): Promise<void>;
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  (function(e,t){typeof exports=="object"&&typeof module!="undefined"?t(exports,require("@nocobase/client"),require("react/jsx-runtime"),require("@formily/react"),require("antd"),require("react"),require("@nocobase/plugin-workflow/client"),require("react-i18next")):typeof define=="function"&&define.amd?define(["exports","@nocobase/client","react/jsx-runtime","@formily/react","antd","react","@nocobase/plugin-workflow/client","react-i18next"],t):(e=typeof globalThis!="undefined"?globalThis:e||self,t(e["@nocobase/plugin-workflow-aggregate"]={},e["@nocobase/client"],e.jsxRuntime,e["@formily/react"],e.antd,e.react,e["@nocobase/plugin-workflow"],e["react-i18next"]))})(this,function(e,t,o,r,S,h,s,b){"use strict";var J=Object.defineProperty,W=Object.defineProperties;var Y=Object.getOwnPropertyDescriptors;var I=Object.getOwnPropertySymbols;var O=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var j=(e,t,o)=>t in e?J(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,N=(e,t)=>{for(var o in t||(t={}))O.call(t,o)&&j(e,o,t[o]);if(I)for(var o of I(t))A.call(t,o)&&j(e,o,t[o]);return e},V=(e,t)=>W(e,Y(t));var G=(e,t)=>{var o={};for(var r in e)O.call(e,r)&&t.indexOf(r)<0&&(o[r]=e[r]);if(e!=null&&I)for(var r of I(e))t.indexOf(r)<0&&A.call(e,r)&&(o[r]=e[r]);return o};var g=(e,t,o)=>(j(e,typeof t!="symbol"?t+"":t,o),o);var C=(e,t,o)=>new Promise((r,S)=>{var h=i=>{try{b(o.next(i))}catch(v){S(v)}},s=i=>{try{b(o.throw(i))}catch(v){S(v)}},b=i=>i.done?r(i.value):Promise.resolve(i.value).then(h,s);b((o=o.apply(e,t)).next())});const i="workflow-aggregate";function v(l,c={}){const{t:n}=B(c);return n(l)}function B(l){return b.useTranslation(i,l)}function K(l){return["hasMany","belongsToMany"].includes(l.type)}function P(){const l=t.useCompile();return[s.nodesOptions,s.triggerOptions].map(c=>{var d;const n=(d=c.useOptions({types:[K],appends:null,depth:4}))==null?void 0:d.filter(Boolean);return{label:l(c.label),value:c.value,key:c.value,children:l(n),disabled:n&&!n.length}})}function R(d){var u=d,{value:l,onChange:c}=u,n=G(u,["value","onChange"]);const{setValuesIn:x}=r.useForm(),{getCollection:k}=t.useCollectionManager_deprecated(),M=P(),[F,q]=h.useState(M),{associatedKey:_="",name:z}=l!=null?l:{};let w=[];const D=_.match(/^{{(.*)}}$/);D&&(w=[...D[1].trim().split(".").slice(0,-1),z]);const U=m=>C(this,null,function*(){var p;const a=m[m.length-1];!((p=a.children)!=null&&p.length)&&!a.isLeaf&&a.loadChildren&&(yield a.loadChildren(a),q(f=>[...f]))});h.useEffect(()=>{C(this,null,function*(){var p;if(!w||F.length<=1)return;let a=null;for(let f=0;f<w.length;f++){const T=w[f];try{f===0?a=F.find(y=>y.value===T):(a.loadChildren&&!((p=a.children)!=null&&p.length)&&(yield a.loadChildren(a)),a=a.children.find(y=>y.value===T))}catch(y){console.error(y)}}q([...F])})},[l,F.length]);const Q=h.useCallback((m,a)=>{if(!(m!=null&&m.length)){x("collection",null),c({});return}const{field:p}=a.pop();if(!p||!["hasMany","belongsToMany"].includes(p.type))return;const{collectionName:f,target:T,name:y,dataSourceKey:$}=p,X=k(f,$).fields.find(H=>H.primaryKey);x("collection",`${$}:${T}`),c({name:y,associatedKey:`{{${m.slice(0,-1).join(".")}.${X.name}}}`,associatedCollection:t.joinCollectionName($,f)})},[c]);return o.jsx(S.Cascader,V(N({},n),{value:w,options:F,changeOnSelect:!0,onChange:Q,loadData:U}))}class E extends s.Instruction{constructor(){super(...arguments);g(this,"title",`{{t("Aggregate", { ns: "${i}" })}}`);g(this,"type","aggregate");g(this,"group","collection");g(this,"description",`{{t("Counting, summing, finding maximum, minimum, and average values for multiple records of a collection or associated data of a record.", { ns: "${i}" })}}`);g(this,"fieldset",{aggregator:{type:"string",title:`{{t("Aggregator function", { ns: "${i}" })}}`,"x-decorator":"FormItem","x-component":"Radio.Group",enum:[{label:"COUNT",value:"count"},{label:"SUM",value:"sum"},{label:"AVG",value:"avg"},{label:"MIN",value:"min"},{label:"MAX",value:"max"}],required:!0,default:"count"},associated:{type:"boolean",title:`{{t("Target type", { ns: "${i}" })}}`,"x-decorator":"FormItem","x-component":"Radio.Group",enum:[{label:`{{t("Data of collection", { ns: "${i}" })}}`,value:!1},{label:`{{t("Data of associated collection", { ns: "${i}" })}}`,value:!0}],required:!0,default:!1,"x-reactions":[{target:"collection",effects:["onFieldValueChange"],fulfill:{state:{value:null}}},{target:"association",effects:["onFieldValueChange"],fulfill:{state:{value:null}}}]},collectionField:{type:"void","x-decorator":"SchemaComponentContext.Provider","x-decorator-props":{value:{designable:!1}},"x-component":"Grid",properties:{row:{type:"void","x-component":"Grid.Row",properties:{target:{type:"void","x-component":"Grid.Col",properties:{collection:{type:"string",required:!0,"x-decorator":"FormItem","x-component":"DataSourceCollectionCascader",title:`{{t("Data of collection", { ns: "${i}" })}}`,"x-reactions":[{dependencies:["associated"],fulfill:{state:{display:'{{$deps[0] ? "hidden" : "visible"}}'}}},{target:"params.field",effects:["onFieldValueChange"],fulfill:{state:{value:null}}},{target:"params.filter",effects:["onFieldValueChange"],fulfill:{state:{value:null}}}]},association:{type:"object",title:`{{t("Data of associated collection", { ns: "${i}" })}}`,"x-decorator":"FormItem","x-component":"AssociatedConfig","x-component-props":{changeOnSelect:!0},"x-reactions":[{dependencies:["associated"],fulfill:{state:{visible:"{{!!$deps[0]}}"}}}],required:!0}}},field:{type:"void","x-component":"Grid.Col",properties:{"params.field":{type:"string",title:`{{t("Field to aggregate", { ns: "${i}" })}}`,"x-decorator":"FormItem","x-component":"FieldsSelect","x-component-props":{filter(n){return!n.hidden&&n.interface&&!["belongsTo","hasOne","hasMany","belongsToMany"].includes(n.type)}},required:!0,"x-reactions":[{dependencies:["collection"],fulfill:{state:{visible:"{{!!$deps[0]}}"}}}]}}}}}}},params:{type:"object",properties:{distinct:{type:"boolean",title:`{{t("Distinct", { ns: "${i}" })}}`,"x-decorator":"FormItem","x-component":"Checkbox","x-reactions":[{dependencies:["collection","aggregator"],fulfill:{state:{visible:'{{!!$deps[0] && ["count"].includes($deps[1])}}'}}}]},filter:{type:"object",title:'{{t("Filter")}}',"x-decorator":"FormItem","x-component":"Filter","x-use-component-props":()=>{const{values:n}=r.useForm(),[d,u]=t.parseCollectionName(n==null?void 0:n.collection);return{options:t.useCollectionFilterOptions(u,d),className:t.css`
2
11
  position: relative;
3
12
  width: 100%;
@@ -1,14 +1,23 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  module.exports = {
2
11
  "@formily/react": "2.3.0",
3
12
  "antd": "5.12.8",
4
13
  "react": "18.2.0",
5
- "@nocobase/client": "1.0.0-alpha.2",
6
- "@nocobase/plugin-workflow": "1.0.0-alpha.2",
14
+ "@nocobase/client": "1.0.0-alpha.3",
15
+ "@nocobase/plugin-workflow": "1.0.0-alpha.3",
7
16
  "react-i18next": "11.18.6",
8
- "@nocobase/data-source-manager": "1.0.0-alpha.2",
9
- "@nocobase/database": "1.0.0-alpha.2",
10
- "@nocobase/server": "1.0.0-alpha.2",
11
- "@nocobase/plugin-workflow-test": "1.0.0-alpha.2",
12
- "@nocobase/test": "1.0.0-alpha.2",
13
- "@nocobase/utils": "1.0.0-alpha.2"
17
+ "@nocobase/data-source-manager": "1.0.0-alpha.3",
18
+ "@nocobase/database": "1.0.0-alpha.3",
19
+ "@nocobase/server": "1.0.0-alpha.3",
20
+ "@nocobase/plugin-workflow-test": "1.0.0-alpha.3",
21
+ "@nocobase/test": "1.0.0-alpha.3",
22
+ "@nocobase/utils": "1.0.0-alpha.3"
14
23
  };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,10 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  export * from './server';
2
10
  export { default } from './server';
package/dist/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  var __create = Object.create;
2
11
  var __defProp = Object.defineProperty;
3
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  export declare const NAMESPACE = "workflow-aggregate";
2
10
  export declare function useLang(key: string, options?: {}): string;
3
11
  export declare function usePluginTranslation(options: any): import("react-i18next").UseTranslationResponse<"workflow-aggregate", undefined>;
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  var __defProp = Object.defineProperty;
2
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
12
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import { Processor, Instruction, FlowNodeModel } from '@nocobase/plugin-workflow';
2
10
  export default class extends Instruction {
3
11
  run(node: FlowNodeModel, input: any, processor: Processor): Promise<{
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  var __defProp = Object.defineProperty;
2
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
12
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  import { Plugin } from '@nocobase/server';
2
10
  export default class extends Plugin {
3
11
  load(): Promise<void>;
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  var __create = Object.create;
2
11
  var __defProp = Object.defineProperty;
3
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1 +1,9 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
1
9
  export { default } from './Plugin';
@@ -1,3 +1,12 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
1
10
  var __create = Object.create;
2
11
  var __defProp = Object.defineProperty;
3
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "工作流:聚合查询节点",
5
5
  "description": "Used to aggregate data against the database in workflow, such as: statistics, sum, average, etc.",
6
6
  "description.zh-CN": "可用于在工作流中对数据库进行聚合查询,如:统计数量、求和、平均值等。",
7
- "version": "1.0.0-alpha.2",
7
+ "version": "1.0.0-alpha.3",
8
8
  "license": "AGPL-3.0",
9
9
  "main": "./dist/server/index.js",
10
10
  "homepage": "https://docs.nocobase.com/handbook/workflow-aggregate",
@@ -21,7 +21,7 @@
21
21
  "@nocobase/server": "1.x",
22
22
  "@nocobase/test": "1.x"
23
23
  },
24
- "gitHead": "f89dbc9e67d58404a2e484a5e124f739f340dcf8",
24
+ "gitHead": "7ccb137c7616cba5d238f87368239640e1d9ace1",
25
25
  "keywords": [
26
26
  "Workflow"
27
27
  ]
@@ -1,413 +0,0 @@
1
- import { useForm } from '@formily/react';
2
- import { Cascader } from 'antd';
3
- import React, { useCallback, useEffect, useState } from 'react';
4
-
5
- import {
6
- SchemaComponentContext,
7
- SchemaInitializerItemType,
8
- css,
9
- joinCollectionName,
10
- parseCollectionName,
11
- useCollectionDataSource,
12
- useCollectionFilterOptions,
13
- useCollectionManager_deprecated,
14
- useCompile,
15
- } from '@nocobase/client';
16
-
17
- import {
18
- FieldsSelect,
19
- FilterDynamicComponent,
20
- ValueBlock,
21
- BaseTypeSets,
22
- defaultFieldNames,
23
- nodesOptions,
24
- triggerOptions,
25
- Instruction,
26
- } from '@nocobase/plugin-workflow/client';
27
-
28
- import { NAMESPACE, useLang } from '../locale';
29
-
30
- function matchToManyField(field): boolean {
31
- // const fieldPrefix = `${field.name}.`;
32
- return ['hasMany', 'belongsToMany'].includes(field.type);
33
- }
34
-
35
- function useAssociatedFields() {
36
- const compile = useCompile();
37
- return [nodesOptions, triggerOptions].map((item) => {
38
- const children = item
39
- .useOptions({
40
- types: [matchToManyField],
41
- appends: null,
42
- depth: 4,
43
- })
44
- ?.filter(Boolean);
45
- return {
46
- label: compile(item.label),
47
- value: item.value,
48
- key: item.value,
49
- children: compile(children),
50
- disabled: children && !children.length,
51
- };
52
- });
53
- }
54
-
55
- function AssociatedConfig({ value, onChange, ...props }): JSX.Element {
56
- const { setValuesIn } = useForm();
57
- const { getCollection } = useCollectionManager_deprecated();
58
- const baseOptions = useAssociatedFields();
59
- const [options, setOptions] = useState(baseOptions);
60
-
61
- const { associatedKey = '', name: fieldName } = value ?? {};
62
- let p = [];
63
- const matched = associatedKey.match(/^{{(.*)}}$/);
64
- if (matched) {
65
- p = [...matched[1].trim().split('.').slice(0, -1), fieldName];
66
- }
67
-
68
- const loadData = async (selectedOptions) => {
69
- const option = selectedOptions[selectedOptions.length - 1];
70
- if (!option.children?.length && !option.isLeaf && option.loadChildren) {
71
- await option.loadChildren(option);
72
- setOptions((prev) => [...prev]);
73
- }
74
- };
75
-
76
- useEffect(() => {
77
- const run = async () => {
78
- if (!p || options.length <= 1) {
79
- return;
80
- }
81
- let prevOption = null;
82
-
83
- for (let i = 0; i < p.length; i++) {
84
- const key = p[i];
85
- try {
86
- if (i === 0) {
87
- prevOption = options.find((item) => item.value === key);
88
- } else {
89
- if (prevOption.loadChildren && !prevOption.children?.length) {
90
- await prevOption.loadChildren(prevOption);
91
- }
92
- prevOption = prevOption.children.find((item) => item.value === key);
93
- }
94
- } catch (err) {
95
- console.error(err);
96
- }
97
- }
98
- setOptions([...options]);
99
- };
100
-
101
- run();
102
- // NOTE: watch `options.length` and it only happens once
103
- }, [value, options.length]);
104
-
105
- const onSelectChange = useCallback(
106
- (path, option) => {
107
- if (!path?.length) {
108
- setValuesIn('collection', null);
109
- onChange({});
110
- return;
111
- }
112
-
113
- // const associationFieldName = path.pop();
114
- const { field } = option.pop();
115
- if (!field || !['hasMany', 'belongsToMany'].includes(field.type)) {
116
- return;
117
- }
118
- // need to get:
119
- // * source collection (from node.config)
120
- // * target collection (from field name)
121
- const { collectionName, target, name, dataSourceKey } = field;
122
-
123
- const collection = getCollection(collectionName, dataSourceKey);
124
- const primaryKeyField = collection.fields.find((f) => f.primaryKey);
125
-
126
- setValuesIn('collection', `${dataSourceKey}:${target}`);
127
-
128
- onChange({
129
- name,
130
- // primary key data path
131
- associatedKey: `{{${path.slice(0, -1).join('.')}.${primaryKeyField.name}}}`,
132
- // data associated collection name
133
- associatedCollection: joinCollectionName(dataSourceKey, collectionName),
134
- });
135
- },
136
- [onChange],
137
- );
138
-
139
- return (
140
- <Cascader
141
- {...props}
142
- value={p}
143
- options={options}
144
- changeOnSelect
145
- onChange={onSelectChange}
146
- loadData={loadData as any}
147
- />
148
- );
149
- }
150
-
151
- // based on collection:
152
- // { collection, field }
153
-
154
- // based on data associated collection
155
- // { key: '{{$context.data.id}}', collection: "collection.association", field }
156
- // select data based
157
-
158
- export default class extends Instruction {
159
- title = `{{t("Aggregate", { ns: "${NAMESPACE}" })}}`;
160
- type = 'aggregate';
161
- group = 'collection';
162
- description = `{{t("Counting, summing, finding maximum, minimum, and average values for multiple records of a collection or associated data of a record.", { ns: "${NAMESPACE}" })}}`;
163
- fieldset = {
164
- aggregator: {
165
- type: 'string',
166
- title: `{{t("Aggregator function", { ns: "${NAMESPACE}" })}}`,
167
- 'x-decorator': 'FormItem',
168
- 'x-component': 'Radio.Group',
169
- enum: [
170
- { label: 'COUNT', value: 'count' },
171
- { label: 'SUM', value: 'sum' },
172
- { label: 'AVG', value: 'avg' },
173
- { label: 'MIN', value: 'min' },
174
- { label: 'MAX', value: 'max' },
175
- ],
176
- required: true,
177
- default: 'count',
178
- },
179
- associated: {
180
- type: 'boolean',
181
- title: `{{t("Target type", { ns: "${NAMESPACE}" })}}`,
182
- 'x-decorator': 'FormItem',
183
- 'x-component': 'Radio.Group',
184
- enum: [
185
- { label: `{{t("Data of collection", { ns: "${NAMESPACE}" })}}`, value: false },
186
- { label: `{{t("Data of associated collection", { ns: "${NAMESPACE}" })}}`, value: true },
187
- ],
188
- required: true,
189
- default: false,
190
- 'x-reactions': [
191
- {
192
- target: 'collection',
193
- effects: ['onFieldValueChange'],
194
- fulfill: {
195
- state: {
196
- value: null,
197
- },
198
- },
199
- },
200
- {
201
- target: 'association',
202
- effects: ['onFieldValueChange'],
203
- fulfill: {
204
- state: {
205
- value: null,
206
- },
207
- },
208
- },
209
- ],
210
- },
211
- collectionField: {
212
- type: 'void',
213
- 'x-decorator': 'SchemaComponentContext.Provider',
214
- 'x-decorator-props': {
215
- value: { designable: false },
216
- },
217
- 'x-component': 'Grid',
218
- properties: {
219
- row: {
220
- type: 'void',
221
- 'x-component': 'Grid.Row',
222
- properties: {
223
- target: {
224
- type: 'void',
225
- 'x-component': 'Grid.Col',
226
- properties: {
227
- collection: {
228
- type: 'string',
229
- required: true,
230
- 'x-decorator': 'FormItem',
231
- 'x-component': 'DataSourceCollectionCascader',
232
- title: `{{t("Data of collection", { ns: "${NAMESPACE}" })}}`,
233
- 'x-reactions': [
234
- {
235
- dependencies: ['associated'],
236
- fulfill: {
237
- state: {
238
- display: '{{$deps[0] ? "hidden" : "visible"}}',
239
- },
240
- },
241
- },
242
- {
243
- target: 'params.field',
244
- effects: ['onFieldValueChange'],
245
- fulfill: {
246
- state: {
247
- value: null,
248
- },
249
- },
250
- },
251
- {
252
- target: 'params.filter',
253
- effects: ['onFieldValueChange'],
254
- fulfill: {
255
- state: {
256
- value: null,
257
- },
258
- },
259
- },
260
- ],
261
- },
262
- association: {
263
- type: 'object',
264
- title: `{{t("Data of associated collection", { ns: "${NAMESPACE}" })}}`,
265
- 'x-decorator': 'FormItem',
266
- 'x-component': 'AssociatedConfig',
267
- 'x-component-props': {
268
- changeOnSelect: true,
269
- },
270
- 'x-reactions': [
271
- {
272
- dependencies: ['associated'],
273
- fulfill: {
274
- state: {
275
- visible: '{{!!$deps[0]}}',
276
- },
277
- },
278
- },
279
- ],
280
- required: true,
281
- },
282
- },
283
- },
284
- field: {
285
- type: 'void',
286
- 'x-component': 'Grid.Col',
287
- properties: {
288
- 'params.field': {
289
- type: 'string',
290
- title: `{{t("Field to aggregate", { ns: "${NAMESPACE}" })}}`,
291
- 'x-decorator': 'FormItem',
292
- 'x-component': 'FieldsSelect',
293
- 'x-component-props': {
294
- filter(field) {
295
- return (
296
- !field.hidden &&
297
- field.interface &&
298
- !['belongsTo', 'hasOne', 'hasMany', 'belongsToMany'].includes(field.type)
299
- );
300
- },
301
- },
302
- required: true,
303
- 'x-reactions': [
304
- {
305
- dependencies: ['collection'],
306
- fulfill: {
307
- state: {
308
- visible: '{{!!$deps[0]}}',
309
- },
310
- },
311
- },
312
- ],
313
- },
314
- },
315
- },
316
- },
317
- },
318
- },
319
- },
320
- params: {
321
- type: 'object',
322
- properties: {
323
- distinct: {
324
- type: 'boolean',
325
- title: `{{t("Distinct", { ns: "${NAMESPACE}" })}}`,
326
- 'x-decorator': 'FormItem',
327
- 'x-component': 'Checkbox',
328
- 'x-reactions': [
329
- {
330
- dependencies: ['collection', 'aggregator'],
331
- fulfill: {
332
- state: {
333
- visible: '{{!!$deps[0] && ["count"].includes($deps[1])}}',
334
- },
335
- },
336
- },
337
- ],
338
- },
339
- filter: {
340
- type: 'object',
341
- title: '{{t("Filter")}}',
342
- 'x-decorator': 'FormItem',
343
- 'x-component': 'Filter',
344
- 'x-use-component-props': () => {
345
- // eslint-disable-next-line react-hooks/rules-of-hooks
346
- const { values } = useForm();
347
- const [dataSourceName, collectionName] = parseCollectionName(values?.collection);
348
- // eslint-disable-next-line react-hooks/rules-of-hooks
349
- const options = useCollectionFilterOptions(collectionName, dataSourceName);
350
- return {
351
- options,
352
- className: css`
353
- position: relative;
354
- width: 100%;
355
- `,
356
- };
357
- },
358
- 'x-component-props': {
359
- dynamicComponent: 'FilterDynamicComponent',
360
- },
361
- 'x-reactions': [
362
- {
363
- dependencies: ['collection'],
364
- fulfill: {
365
- state: {
366
- visible: '{{!!$deps[0]}}',
367
- },
368
- },
369
- },
370
- ],
371
- },
372
- },
373
- },
374
- };
375
- scope = {
376
- useCollectionDataSource,
377
- };
378
- components = {
379
- SchemaComponentContext,
380
- FilterDynamicComponent,
381
- FieldsSelect,
382
- ValueBlock,
383
- AssociatedConfig,
384
- };
385
- useVariables({ key, title }, { types, fieldNames = defaultFieldNames }) {
386
- if (
387
- types &&
388
- !types.some((type) => type in BaseTypeSets || Object.values(BaseTypeSets).some((set) => set.has(type)))
389
- ) {
390
- return null;
391
- }
392
- return {
393
- [fieldNames.value]: key,
394
- [fieldNames.label]: title,
395
- };
396
- }
397
- useInitializers(node): SchemaInitializerItemType | null {
398
- // eslint-disable-next-line react-hooks/rules-of-hooks
399
- const resultTitle = useLang('Query result');
400
- if (!node.config.collection) {
401
- return null;
402
- }
403
-
404
- return {
405
- name: `#${node.id}`,
406
- type: 'item',
407
- title: node.title ?? `#${node.id}`,
408
- Component: ValueBlock.Initializer,
409
- node,
410
- resultTitle,
411
- };
412
- }
413
- }