@steedos/standard-object-database 2.7.0-beta.2 → 2.7.0-beta.21

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 (26) hide show
  1. package/main/default/objectTranslations/_object_reload_logs.en/_object_reload_logs.en.objectTranslation.yml +1 -1
  2. package/main/default/objectTranslations/_object_reload_logs.zh-CN/_object_reload_logs.zh-CN.objectTranslation.yml +1 -1
  3. package/main/default/objectTranslations/object_actions.en/object_actions.en.objectTranslation.yml +4 -0
  4. package/main/default/objectTranslations/object_actions.zh-CN/object_actions.zh-CN.objectTranslation.yml +4 -0
  5. package/main/default/objectTranslations/object_fields.en/object_fields.en.objectTranslation.yml +8 -2
  6. package/main/default/objectTranslations/object_fields.zh-CN/object_fields.zh-CN.objectTranslation.yml +8 -2
  7. package/main/default/objectTranslations/objects.en/objects.en.objectTranslation.yml +2 -0
  8. package/main/default/objectTranslations/objects.zh-CN/objects.zh-CN.objectTranslation.yml +2 -0
  9. package/main/default/objects/0.objects_reload.object.js +7 -0
  10. package/main/default/objects/_object_reload_logs.object.yml +1 -1
  11. package/main/default/objects/object_actions.object.yml +7 -0
  12. package/main/default/objects/object_fields.object.yml +30 -9
  13. package/main/default/objects/objects/buttons/reset.button.js +16 -0
  14. package/main/default/objects/objects/buttons/reset.button.yml +79 -0
  15. package/main/default/objects/objects.core.js +4 -4
  16. package/main/default/objects/objects.object.yml +7 -1
  17. package/main/default/pages/design_field_layout.page.amis.json +65 -47
  18. package/main/default/pages/object_fields_form.page.amis.json +42 -3
  19. package/main/default/services/database-objects.service.js +19 -2
  20. package/main/default/services/object_fields.service.js +2 -0
  21. package/main/default/triggers/object_actions.trigger.js +24 -28
  22. package/main/default/triggers/object_fields.trigger.js +25 -1
  23. package/main/default/triggers/object_validation_rules.trigger.js +2 -21
  24. package/main/default/triggers/objects.trigger.js +12 -5
  25. package/package.json +4 -4
  26. package/package.service.js +2 -3
@@ -6,7 +6,7 @@ fields:
6
6
  label:
7
7
  help:
8
8
  description:
9
- change_date:
9
+ change_data:
10
10
  label:
11
11
  help:
12
12
  description:
@@ -6,7 +6,7 @@ fields:
6
6
  label:
7
7
  help:
8
8
  description:
9
- change_date:
9
+ change_data:
10
10
  label:
11
11
  help:
12
12
  description:
@@ -2,6 +2,10 @@ name: object_actions
2
2
  label: Object Action
3
3
  description:
4
4
  fields:
5
+ description:
6
+ label: Description
7
+ help:
8
+ description:
5
9
  object:
6
10
  label: Object
7
11
  help:
@@ -2,6 +2,10 @@ name: object_actions
2
2
  label: 操作按钮
3
3
  description:
4
4
  fields:
5
+ description:
6
+ label: 备注
7
+ help:
8
+ description:
5
9
  object:
6
10
  label: 所属对象
7
11
  help:
@@ -110,8 +110,12 @@ fields:
110
110
  label: Reference to field
111
111
  help: The value of the associated object saved to the current object field; For example, after object A is associated with object B, when A1 record is associated with B1 record, B1 record will be stored by default_ Save the ID in the A1 record. If the foreign key field is modified, the 'foreign key field' will be replaced_ Store the ID in the A1 record.
112
112
  description: The default is the primary key, and the default value is _id.
113
+ filters:
114
+ label: Lookup Relationship Filters Condition
115
+ help: When the field type is Lookup Relationship or Master Detail Relationship, filtering conditions can be configured for the field, filtering option list; The field values can be configured as formulas, and the fields referenced in the formulas need to be configured in Dependent Fields at the same time
116
+ description:
113
117
  filtersFunction:
114
- label: filters Function
118
+ label: Lookup Relationship Filters Function
115
119
  help:
116
120
  description:
117
121
  optionsFunction:
@@ -165,7 +169,7 @@ fields:
165
169
  description:
166
170
  auto_fill_mapping:
167
171
  label: Auto Fill Mapping
168
- help: When the data is selected, the field values in the reference object are automatically filled into the current form field according to the following mapping.
172
+ help: In a form, after you fill in one field, other fields are automatically filled according to preset rules. For example, in the New Payment history form, after selecting a contract, the amount of the contract is automatically filled into the payment amount field.
169
173
  description:
170
174
  auto_fill_mapping.$:
171
175
  label: Auto Fill Mapping
@@ -383,6 +387,8 @@ fields:
383
387
  label: Enable Enhanced Lookup
384
388
  help:
385
389
  description:
390
+ is_customize:
391
+ label: Customize
386
392
  groups:
387
393
  external_data_source: External data source
388
394
  advanced: Advanced
@@ -107,8 +107,12 @@ fields:
107
107
  label: 外键字段
108
108
  help: 关联的对象保存到当前对象字段的值;例如:A对象关联B对象后,当A1记录关联了B1记录,默认会存B1记录的_id存到A1记录中。如果修改了外键字段后,会将“外键字段”替换_id存储到A1记录中。
109
109
  description: '默认为主键,默认值是_id'
110
+ filters:
111
+ label: 相关表过滤条件
112
+ help: 当字段类型为相关表关系或主/子表关系时,可以为该字段配置过滤条件,过滤选项列表;其中字段值可以配置为公式,公式中引用的字段需要同时配置在依赖的字段中
113
+ description:
110
114
  filtersFunction:
111
- label: 过滤器函数
115
+ label: 相关表过滤器函数
112
116
  help:
113
117
  description:
114
118
  optionsFunction:
@@ -157,7 +161,7 @@ fields:
157
161
  description:
158
162
  auto_fill_mapping:
159
163
  label: 自动填充规则
160
- help: 选择数据后,将按以下映射关系将引用对象中的字段值自动填充到当前表单字段中。
164
+ help: 在表单中,填写某个字段后,会根据预设规则自动填充其他字段。例如,在新建付款记录表单中,选择合同后,会自动将合同的金额填入付款金额字段。
161
165
  description:
162
166
  auto_fill_mapping.$:
163
167
  label: 自动填充规则
@@ -359,6 +363,8 @@ fields:
359
363
  label: 启用弹出窗口查找模式
360
364
  help:
361
365
  description:
366
+ is_customize:
367
+ label: 自定义
362
368
  groups:
363
369
  external_data_source: 外部数据源
364
370
  advanced: 高级
@@ -202,6 +202,8 @@ fields:
202
202
  label: After Edit
203
203
  compactLayouts:
204
204
  label: Highlight Fields
205
+ is_customize:
206
+ label: Customize
205
207
  groups:
206
208
  external_data_source: External data source
207
209
  switch: Switch
@@ -201,6 +201,8 @@ fields:
201
201
  label: 编辑页面显示之后
202
202
  compactLayouts:
203
203
  label: 高亮字段
204
+ is_customize:
205
+ label: 自定义
204
206
  groups:
205
207
  external_data_source: 外部数据源
206
208
  switch: 功能开关
@@ -1,3 +1,10 @@
1
+ /*
2
+ * @Author: baozhoutao@steedos.com
3
+ * @Date: 2022-08-05 14:17:44
4
+ * @LastEditors: baozhoutao@steedos.com
5
+ * @LastEditTime: 2024-03-20 13:34:23
6
+ * @Description:
7
+ */
1
8
  var objectql = require('@steedos/objectql');
2
9
  var objectCore = require('./objects.core.js');
3
10
 
@@ -3,7 +3,7 @@ hidden: true
3
3
  fields:
4
4
  object_name:
5
5
  type: text
6
- change_date:
6
+ change_data:
7
7
  type: object
8
8
  blackbox: true
9
9
  change_time:
@@ -38,7 +38,9 @@ fields:
38
38
  # omit: true
39
39
  # hidden: true
40
40
  label: Visible
41
+ is_wide: false
41
42
  sort_no: 150
43
+ defaultValue: true
42
44
  'on':
43
45
  type: lookup
44
46
  label: 'On'
@@ -137,6 +139,11 @@ fields:
137
139
  visible_on: "{{global.mode ==='read' ? true : false}}"
138
140
  disabled: true
139
141
  sort_no: 500
142
+ description:
143
+ label: Description
144
+ type: textarea
145
+ is_wide: true
146
+ sort_no: 450
140
147
  form:
141
148
  initialValues: !!js/function |
142
149
  function(){
@@ -25,8 +25,6 @@ fields:
25
25
  label: Label
26
26
  is_name: true
27
27
  sort_no: 120
28
- amis:
29
- disabledOn: "${is_system == true}"
30
28
  _name:
31
29
  type: text
32
30
  label: Field Name
@@ -364,8 +362,20 @@ fields:
364
362
  sort_no: 220
365
363
  amis:
366
364
  disabledOn: "${is_system == true}"
365
+ filters:
366
+ label: Lookup Relationship Filters Condition
367
+ type: code
368
+ is_wide: true
369
+ hidden: false
370
+ readonly: false
371
+ sort_no: 447
372
+ group: Advanced
373
+ visible_on: "{{(['lookup', 'master_detail'].indexOf(formData.type) > -1 ? true: false) && !!formData.reference_to}}"
374
+ inlineHelpText: vWhen the field type is Lookup Relationship or Master Detail Relationship, filtering conditions can be configured for the field, filtering option list; The field values can be configured as formulas, and the fields referenced in the formulas need to be configured in Dependent Fields at the same time
375
+ amis:
376
+ disabledOn: "${is_system == true}"
367
377
  filtersFunction:
368
- label: filters Function
378
+ label: Lookup Relationship Filters Function
369
379
  type: code
370
380
  language: javascript
371
381
  is_wide: true
@@ -525,7 +535,6 @@ fields:
525
535
  sort_no: 280
526
536
  amis:
527
537
  enableDialog: false
528
- disabledOn: "${is_system == true}"
529
538
  auto_fill_mapping.$:
530
539
  label: Auto Fill Mapping
531
540
  blackbox: true
@@ -571,18 +580,23 @@ fields:
571
580
  };
572
581
  var currentFilter = [];
573
582
  var referenceObject = BuilderAmisObject && BuilderAmisObject.AmisLib && BuilderAmisObject.AmisLib.getUISchemaSync(values.reference_to);
574
- var fromField = referenceObject && referenceObject.fields[values.auto_fill_mapping__from];
583
+ var fromField = referenceObject && referenceObject.fields[values.from];
575
584
 
576
585
  if (fromField && fromField.data_type) {
577
586
  currentFilter.push(['type', 'in', fieldFilters[fromField.data_type] || fromField.data_type.split()]);
578
587
  }else if (fromField) {
579
588
  currentFilter.push(['type', 'in', fieldFilters[fromField.type] || fromField.type.split()]);
580
589
  if (fromField.type == "lookup" || fromField.type == "master_detail") {
581
- if (fromField.reference_to) {
582
- currentFilter.push(['reference_to', '=', fromField.reference_to]);
590
+ if(fromField.reference_to === "users"){
591
+ currentFilter.push([['reference_to', '=', "users"],"or", ['reference_to', '=', "space_users"]]);
583
592
  }
584
- if (fromField.reference_to_field) {
585
- currentFilter.push(['reference_to_field', '=', fromField.reference_to_field]);
593
+ else{
594
+ if (fromField.reference_to) {
595
+ currentFilter.push(['reference_to', '=', fromField.reference_to]);
596
+ }
597
+ if (fromField.reference_to_field) {
598
+ currentFilter.push(['reference_to_field', '=', fromField.reference_to_field]);
599
+ }
586
600
  }
587
601
  }
588
602
  }
@@ -936,6 +950,9 @@ fields:
936
950
  type: boolean
937
951
  label: Enable Enhanced Lookup
938
952
  hidden: true # 这里不可以用 visible_on: "{{false}}",否则在界面上新建字段时会被默认设置为false
953
+ is_customize:
954
+ type: boolean
955
+ readonly: true
939
956
  paging:
940
957
  enabled: false
941
958
  list_views:
@@ -951,6 +968,9 @@ list_views:
951
968
  - hidden
952
969
  - readonly
953
970
  - is_system
971
+ - is_customize
972
+ extra_columns:
973
+ - reference_to #GraphQL查询对象字段时,如果过滤条件中有按reference_to过滤,要查询返回的字段不配置reference_to的话过滤结果不对,解决了#6649
954
974
  sort:
955
975
  - field_name: sort_no
956
976
  order: asc
@@ -968,6 +988,7 @@ list_views:
968
988
  - hidden
969
989
  - readonly
970
990
  - is_system
991
+ - is_customize
971
992
  label: 自定义
972
993
  filters:
973
994
  - ["is_system","<>",true]
@@ -0,0 +1,16 @@
1
+ /*
2
+ * @Author: baozhoutaon@hotoa.com
3
+ * @Date: 2022-03-29 20:33:44
4
+ * @LastEditors: baozhoutao@steedos.com
5
+ * @LastEditTime: 2024-03-21 10:45:57
6
+ * @Description:
7
+ */
8
+ module.exports = {
9
+ resetVisible: function (object_name, record_id, permission, data) {
10
+ if(Meteor.settings.public.enable_saas){
11
+ return false;
12
+ }
13
+ var record = data && data.record;
14
+ return record && record.is_system && record.is_customize && record.created;
15
+ }
16
+ }
@@ -0,0 +1,79 @@
1
+ name: reset
2
+ amis_schema: |-
3
+ {
4
+ "type": "service",
5
+ "body": [
6
+ {
7
+ "type": "button",
8
+ "label": "重置",
9
+ "id": "u:delete_object",
10
+ "onEvent": {
11
+ "click": {
12
+ "actions": [
13
+ {
14
+ "actionType": "dialog",
15
+ "dialog": {
16
+ "type": "dialog",
17
+ "title": "重置对象: ${record.label}",
18
+ "body": [
19
+ {
20
+ "type": "tpl",
21
+ "tpl": "<div>\n<div style=\"text-align: left;\">重置一个自定义对象进行以下操作:</div>\n<ul>\n<li style=\"text-align: left;\">删除自定义的对象</li>\n<li style=\"text-align: left;\">删除自定义对象的字段</li>\n</ul>\n</div>",
22
+ "inline": true,
23
+ "id": "u:6d0819fc0bda"
24
+ }
25
+ ],
26
+ "id": "u:b5c0f98dc113",
27
+ "closeOnEsc": false,
28
+ "closeOnOutside": false,
29
+ "showCloseButton": true,
30
+ "data": {
31
+ "&": "$$",
32
+ "recordId": "${recordId}"
33
+ },
34
+ "onEvent": {
35
+ "confirm": {
36
+ "weight": 0,
37
+ "actions": [
38
+ {
39
+ "componentId": "",
40
+ "args": {
41
+ "api": {
42
+ "url": "/service/api/~database-objects/reset",
43
+ "method": "post",
44
+ "data": {
45
+ "objectName": "${record.name}"
46
+ }
47
+ },
48
+ "messages": {}
49
+ },
50
+ "actionType": "ajax"
51
+ },
52
+ {
53
+ "actionType": "custom",
54
+ "script": "window.location.reload();"
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ }
60
+ }
61
+ ],
62
+ "weight": 0
63
+ }
64
+ }
65
+ }
66
+ ],
67
+ "regions": [
68
+ "body"
69
+ ],
70
+ "data": {
71
+ },
72
+ "bodyClassName": "p-0",
73
+ "id": "u:46d1821365fc"
74
+ }
75
+ is_enable: true
76
+ label: 重置
77
+ 'on': record_only_more
78
+ type: amis_button
79
+ visible: true
@@ -284,7 +284,7 @@ function getObjectFromDB(objectName) {
284
284
 
285
285
  function reloadObject(changeLog){
286
286
  var objectName = changeLog.object_name;
287
- var data = changeLog.change_date;
287
+ var data = changeLog.change_data;
288
288
  const objectRecord = Creator.getCollection("objects").findOne({
289
289
  name: objectName
290
290
  })
@@ -298,7 +298,7 @@ function reloadObject(changeLog){
298
298
  fields: [],
299
299
  actions: []
300
300
  }
301
- if(!objectRecord && objectDataSourceName){
301
+ if((!objectRecord || objectRecord.is_system == true) && objectDataSourceName){
302
302
 
303
303
  switch (data.type) {
304
304
  case 'field':
@@ -383,14 +383,14 @@ function triggerReloadObject(objectName, type, value, event){
383
383
  const objectRecord = Creator.getCollection("objects").findOne({
384
384
  name: objectName
385
385
  })
386
- if(objectRecord){
386
+ if(objectRecord && objectRecord.is_system != true){
387
387
  //TODO 待支持动态加载related_list后, 删除此行代码
388
388
  // console.log(`triggerReloadObject===>`, objectName)
389
389
  Creator.getCollection("objects").update({name: objectName}, {$set: {reload_time: new Date()}})
390
390
  }else{
391
391
  Creator.getCollection("_object_reload_logs").insert({
392
392
  object_name: objectName,
393
- change_date: {
393
+ change_data: {
394
394
  type: type,
395
395
  event: event,
396
396
  value: value
@@ -443,6 +443,9 @@ fields:
443
443
  extend:
444
444
  type: text
445
445
  hidden: true
446
+ is_customize:
447
+ type: boolean
448
+ readonly: true
446
449
  paging:
447
450
  enabled: false
448
451
  relatedList:
@@ -490,6 +493,7 @@ list_views:
490
493
  - in_development
491
494
  - is_enable
492
495
  - is_system
496
+ - is_customize
493
497
  label: All
494
498
  filter_scope: space
495
499
  extra_columns:
@@ -505,9 +509,10 @@ list_views:
505
509
  - in_development
506
510
  - is_enable
507
511
  - is_system
512
+ - is_customize
508
513
  label: Customize
509
514
  filters:
510
- - ["is_system","<>",true]
515
+ - ["is_customize","<>",true]
511
516
  filter_scope: space
512
517
  extra_columns:
513
518
  - datasource
@@ -522,6 +527,7 @@ list_views:
522
527
  - in_development
523
528
  - is_enable
524
529
  - is_system
530
+ - is_customize
525
531
  label: System
526
532
  filters:
527
533
  - ["is_system","=",true]
@@ -32,62 +32,80 @@
32
32
  "type": "dialog",
33
33
  "title": "设置分组",
34
34
  "size": "lg",
35
+ "data": {
36
+ "&": "$$",
37
+ "groups": "${groups|filter:is_default:isFalse|filter:is_hidden:isFalse}",
38
+ "designObjectName": "${designObjectName}"
39
+ },
35
40
  "body": [
36
41
  {
37
42
  "type": "form",
38
43
  "mode": "normal",
39
44
  "body": [
40
45
  {
41
- "type": "steedos-input-table",
42
- "enableDialog": false,
43
- "fields": [
46
+ "type": "service",
47
+ "body": [
44
48
  {
45
- "name": "group_name",
46
- "label": "名称",
47
- "type": "text",
48
- "amis": {
49
- "disabledOn": "${is_default || is_hidden}"
50
- },
51
- "id": "u:31952daa443c"
52
- },
53
- {
54
- "name": "visible_on",
55
- "label": "显示条件",
56
- "type": "text",
57
- "amis": {
58
- "disabledOn": "${is_default || is_hidden}"
59
- },
60
- "id": "u:8d7551abcd28",
61
- "value": null
62
- },
63
- {
64
- "name": "collapsed",
65
- "label": "默认折叠",
66
- "amis": {
67
- "disabledOn": "${is_default || is_hidden}"
68
- },
69
- "type": "boolean"
49
+ "type": "steedos-input-table",
50
+ "enableDialog": false,
51
+ "fields": [
52
+ {
53
+ "name": "group_name",
54
+ "label": "名称",
55
+ "type": "text",
56
+ "id": "u:31952daa443c"
57
+ },
58
+ {
59
+ "name": "visible_on",
60
+ "label": "显示条件",
61
+ "type": "text",
62
+ "amis": {
63
+ "type": "input-formula",
64
+ "name": "formula",
65
+ "evalMode": false,
66
+ "variableMode": "tabs",
67
+ "variables": "${variables}"
68
+ },
69
+ "id": "u:8d7551abcd28",
70
+ "value": null
71
+ },
72
+ {
73
+ "name": "collapsed",
74
+ "label": "默认折叠",
75
+ "type": "boolean"
76
+ }
77
+ ],
78
+ "columns": [
79
+ {
80
+ "name": "group_name"
81
+ },
82
+ {
83
+ "name": "visible_on"
84
+ },
85
+ {
86
+ "name": "collapsed",
87
+ "width": 50
88
+ }
89
+ ],
90
+ "name": "groups",
91
+ "addable": true,
92
+ "editable": true,
93
+ "removable": true,
94
+ "draggable": false,
95
+ "id": "u:776ec89804c0",
96
+ "label": "",
97
+ "visibleOn": "${variables}"
70
98
  }
71
99
  ],
72
- "columns": [
73
- {
74
- "name": "group_name"
75
- },
76
- {
77
- "name": "visible_on"
78
- },
79
- {
80
- "name": "collapsed",
81
- "width": 50
100
+ "api": {
101
+ "method": "get",
102
+ "url": "${context.rootUrl}/service/api/@${designObjectName}/uiSchema",
103
+ "adaptor": "payload = {data: {variables: SteedosUI.getFormulaVariables(payload.fields)}};return payload;",
104
+ "cache": 30000,
105
+ "headers": {
106
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
82
107
  }
83
- ],
84
- "name": "groups",
85
- "addable": true,
86
- "editable": true,
87
- "removable": true,
88
- "draggable": false,
89
- "id": "u:776ec89804c0",
90
- "label": ""
108
+ }
91
109
  }
92
110
  ]
93
111
  }
@@ -97,7 +115,7 @@
97
115
  "actions": [
98
116
  {
99
117
  "actionType": "custom",
100
- "script": "///整理分组数据\nconst defaultGroupName = \"未分组\";\nconst hiddenGroupName = \"隐藏\";\nlet setting_groups = _.cloneDeep(event.data.groups);\nif (!_.find(setting_groups, { is_default: true })) {\n setting_groups.unshift({\n \"id\": defaultGroupName,\n \"group_name\": defaultGroupName,\n \"visible_on\": \"\",\n \"is_default\": true\n })\n}\nif (!_.find(setting_groups, { is_hidden: true })) {\n setting_groups.push({\n id: hiddenGroupName,\n group_name: hiddenGroupName,\n visible_on: \"\",\n is_hidden: true\n });\n}\nsetting_groups.forEach(function (group) {\n if (group.is_hidden) {\n group.group_name = hiddenGroupName;\n group.visible_on = \"\";\n }\n if (group.is_default) {\n group.group_name = defaultGroupName;\n group.visible_on = \"\";\n }\n if (!group.id) {\n group.id = group.group_name;\n }\n if (!group.visible_on) {\n group.visible_on = \"\"\n }\n})\n\n//整理字段与分组关系的数据\nlet fieldForGroup = {};\nlet oldGroup = _.cloneDeep(event.data.fieldForGroup);\nsetting_groups.forEach(function (group) {\n if (_.has(oldGroup, group.id)) {\n fieldForGroup[group.id] = oldGroup[group.id];\n oldGroup = _.omit(oldGroup, group.id);\n } else {\n fieldForGroup[group.id] = [];\n }\n})\nif (oldGroup && !_.isEmpty(oldGroup)) {\n _.forEach(oldGroup, function (value, key) {\n fieldForGroup[defaultGroupName] = _.unionBy(fieldForGroup[defaultGroupName], value);\n });\n}\n\n//未分组 放在所有分组开头,隐藏 放在所有分组最后\nconst defaultGroup = fieldForGroup[defaultGroupName];\nconst hiddenGroup = fieldForGroup[hiddenGroupName];\ndelete fieldForGroup[defaultGroupName];\ndelete fieldForGroup[hiddenGroupName];\nfieldForGroup = _.merge({ [defaultGroupName]: defaultGroup }, fieldForGroup, { [hiddenGroupName]: hiddenGroup });\n\n//根据fieldForGroup调整groups顺序,设置分组与保存时需要groups按照顺序\nconst keys = _.keys(fieldForGroup);\nsetting_groups = _.sortBy(setting_groups, function (group) { return _.findIndex(keys, function (key) { return key == group.group_name }) });\n\ndoAction({\n actionType: 'setValue',\n componentId: 'service_field_design',\n args: {\n value: {\n groups: setting_groups\n }\n }\n});\n\ndoAction({\n actionType: 'setValue',\n componentId: \"form_field_design\",\n args: {\n value: { design_field: fieldForGroup }\n }\n});"
118
+ "script": "///整理分组数据\nconst defaultGroupName = \"未分组\";\nconst hiddenGroupName = \"隐藏\";\nlet setting_groups = _.cloneDeep(event.data.groups);\nif (!_.find(setting_groups, { is_default: true })) {\n setting_groups.unshift({\n \"id\": defaultGroupName,\n \"group_name\": defaultGroupName,\n \"visible_on\": \"\",\n \"is_default\": true\n })\n}\nif (!_.find(setting_groups, { is_hidden: true })) {\n setting_groups.push({\n id: hiddenGroupName,\n group_name: hiddenGroupName,\n visible_on: \"\",\n is_hidden: true\n });\n}\nsetting_groups.forEach(function (group) {\n if (!group.id || group.id != group.group_name) {\n group.id = group.group_name;\n }\n if (/\\$\\{.+\\}/.test(group.visible_on)) {\n group.visible_on = group.visible_on.replaceAll('${', '\\\\${');\n }\n})\n\n//整理字段与分组关系的数据\nlet fieldForGroup = {};\nlet oldGroup = _.cloneDeep(event.data.fieldForGroup);\nsetting_groups.forEach(function (group) {\n if (_.has(oldGroup, group.id)) {\n fieldForGroup[group.id] = oldGroup[group.id];\n oldGroup = _.omit(oldGroup, group.id);\n } else {\n fieldForGroup[group.id] = [];\n }\n})\nif (oldGroup && !_.isEmpty(oldGroup)) {\n _.forEach(oldGroup, function (value, key) {\n fieldForGroup[defaultGroupName] = _.unionBy(fieldForGroup[defaultGroupName], value);\n });\n}\n\n//未分组 放在所有分组开头,隐藏 放在所有分组最后\nconst defaultGroup = fieldForGroup[defaultGroupName];\nconst hiddenGroup = fieldForGroup[hiddenGroupName];\ndelete fieldForGroup[defaultGroupName];\ndelete fieldForGroup[hiddenGroupName];\nfieldForGroup = _.merge({ [defaultGroupName]: defaultGroup }, fieldForGroup, { [hiddenGroupName]: hiddenGroup });\n\n//根据fieldForGroup调整groups顺序,设置分组与保存时需要groups按照顺序\nconst keys = _.keys(fieldForGroup);\nsetting_groups = _.sortBy(setting_groups, function (group) { return _.findIndex(keys, function (key) { return key == group.group_name }) });\n\ndoAction({\n actionType: 'setValue',\n componentId: 'service_field_design',\n args: {\n value: {\n groups: setting_groups\n }\n }\n});\n\ndoAction({\n actionType: 'setValue',\n componentId: \"form_field_design\",\n args: {\n value: { design_field: fieldForGroup }\n }\n});"
101
119
  }
102
120
  ]
103
121
  }
@@ -25,8 +25,8 @@
25
25
  ]
26
26
  }
27
27
  },
28
- "initApiAdaptor": "const defaultValue_field_value = payload.data.defaultValue; if(defaultValue_field_value && _.isString(defaultValue_field_value) && defaultValue_field_value.indexOf('{')>-1 ){ payload.data.defaultValue_formula = defaultValue_field_value; delete payload.data.defaultValue; } return payload;",
29
- "apiRequestAdaptor": "if(formData.defaultValue_formula){ formData.defaultValue = formData.defaultValue_formula } __saveData = JSON.stringify(JSON.stringify(formData)); api.data = {query: query.replace('{__saveData}', __saveData)}; api.data.query = api.data.query.replace('object_fields__update', 'object_fields__upsert')",
28
+ "initApiAdaptor": "const defaultValue_field_value = payload.data.defaultValue;\nif (defaultValue_field_value && _.isString(defaultValue_field_value) && defaultValue_field_value.indexOf('{') > -1) {\n payload.data.defaultValue_formula = defaultValue_field_value;\n delete payload.data.defaultValue;\n}\n\nif (recordId) {\n var data = payload.data;\n if (data) {\n data.filters = window.amisConvert.filtersToConditions(data.filters || []);\n }\n payload.data = data;\n}\nreturn payload;",
29
+ "apiRequestAdaptor": "if (formData.defaultValue_formula) {\n formData.defaultValue = formData.defaultValue_formula\n}\nif (formData.filters) {\n formData.filters = window.amisConvert.conditionsToFilters(formData.filters);\n}\n__saveData = JSON.stringify(JSON.stringify(formData));\napi.data = { query: query.replace('{__saveData}', __saveData) };\napi.data.query = api.data.query.replace('object_fields__update', 'object_fields__upsert');",
30
30
  "submitSuccActions": [
31
31
  {
32
32
  "actionType": "custom",
@@ -142,8 +142,39 @@
142
142
  }
143
143
  ]
144
144
  }
145
- }
145
+ },
146
+ "disabledOn": "${is_system == true}",
147
+ "searchable": true
148
+ }
149
+ },
150
+ "filters": {
151
+ "amis": {
152
+ "type": "condition-builder",
153
+ "description": "",
154
+ "id": "u:a9f2232e30d7",
155
+ "source": {
156
+ "method": "get",
157
+ "url": "${context.rootUrl}/service/api/amis-metadata-listviews/getFilterFields?objectName=${reference_to}",
158
+ "dataType": "json",
159
+ "headers": {
160
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
161
+ }
162
+ },
163
+ "className": "col-span-2 m-0"
146
164
  }
165
+ },
166
+ "filtersFunction": {
167
+ "hidden": true
168
+ },
169
+ "visible_on": {
170
+ "amis": {
171
+ "type": "input-formula",
172
+ "name": "formula",
173
+ "evalMode": false,
174
+ "variableMode": "tabs",
175
+ "variables": "${VisibleVariables}",
176
+ "id": "u:618105d5bfad"
177
+ }
147
178
  }
148
179
  },
149
180
  "form": {
@@ -151,6 +182,14 @@
151
182
  }
152
183
  }
153
184
  ],
185
+ "api": {
186
+ "method": "get",
187
+ "url": "${context.rootUrl}/service/api/@${_master.record.name}/uiSchema",
188
+ "adaptor": "const VisibleVariables = SteedosUI.getFormulaVariables(payload.fields);\nconst defaultVariables = [VisibleVariables[1]];\npayload = {\n data: {\n VisibleVariables,\n defaultVariables\n }\n};\nreturn payload;",
189
+ "headers": {
190
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
191
+ }
192
+ },
154
193
  "data": {
155
194
  "context": {}
156
195
  },
@@ -2,10 +2,15 @@
2
2
  * @Author: baozhoutao@steedos.com
3
3
  * @Date: 2023-04-21 16:25:07
4
4
  * @LastEditors: baozhoutao@steedos.com
5
- * @LastEditTime: 2023-05-18 09:26:18
5
+ * @LastEditTime: 2024-03-21 11:58:43
6
6
  * @Description:
7
7
  */
8
8
  var packageServiceName = '~database-objects'
9
+
10
+ const { getObject } = require('@steedos/objectql');
11
+
12
+ const sleep = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
13
+
9
14
  function isPatternTrigger(data){
10
15
  const {listenTo} = data;
11
16
  if(listenTo === '*'){
@@ -36,7 +41,19 @@ module.exports = {
36
41
  * Actions
37
42
  */
38
43
  actions: {
39
-
44
+ resetObject: {
45
+ rest: {
46
+ method: "POST",
47
+ path: "/reset"
48
+ },
49
+ async handler(ctx) {
50
+ const { objectName } = ctx.params;
51
+ await getObject('objects').directDelete({filters: ['name','=', objectName]});
52
+ await getObject('object_fields').directDelete({filters: ['object','=', objectName]});
53
+ await sleep(2 * 1000)
54
+ return true;
55
+ }
56
+ }
40
57
  },
41
58
 
42
59
  /**
@@ -230,6 +230,8 @@ module.exports = {
230
230
  "evalMode": false,
231
231
  "type": "input-formula",
232
232
  "placeholder": "公式",
233
+ "variableMode": "tabs",
234
+ "variables": "${defaultVariables}", //公式编辑器内引用的变量,在对象字段表单微页面内定义
233
235
  // "disabledOn": "!!this.defaultValue && !!this.defaultValue.toString()",
234
236
  "className": {
235
237
  "defaultValue_field_formula": true,
@@ -2,7 +2,7 @@
2
2
  * @Author: sunhaolin@hotoa.com
3
3
  * @Date: 2022-05-28 11:07:57
4
4
  * @LastEditors: baozhoutao@steedos.com
5
- * @LastEditTime: 2023-10-16 13:58:22
5
+ * @LastEditTime: 2024-03-20 16:00:17
6
6
  * @Description:
7
7
  */
8
8
  const InternalData = require('@steedos/standard-objects').internalData;
@@ -12,20 +12,18 @@ const sleep = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
12
12
  module.exports = {
13
13
  beforeInsert: async function(){
14
14
  const { doc } = this;
15
+ delete doc.visible_type
15
16
  doc.visible;
16
17
  },
17
18
  beforeUpdate: async function(){
18
19
  const { doc } = this;
20
+ delete doc.visible_type
19
21
  doc.visible;
20
22
  },
21
23
  beforeFind: async function () {
22
24
  delete this.query.fields;
23
25
  },
24
26
 
25
- beforeAggregate: async function () {
26
- delete this.query.fields;
27
- },
28
-
29
27
  afterFind: async function(){
30
28
  let filters = InternalData.parserFilters(this.query.filters)
31
29
  const { spaceId } = this;
@@ -52,32 +50,21 @@ module.exports = {
52
50
  }
53
51
  }
54
52
  }
55
- },
56
- afterAggregate: async function(){
57
- let filters = InternalData.parserFilters(this.query.filters)
58
- const { spaceId } = this;
59
53
 
60
- let objectName = filters.object;
61
- if(!objectName && filters._id && filters._id.indexOf(".") > -1){
62
- objectName = filters._id.split('.')[0];
63
- }
54
+ // _.each(this.data.values, (item)=>{
55
+ // if(item.visibleOn){
56
+ // item.visible_type = "expression"
57
+ // }else if(item.visible === true){
58
+ // item.visible_type = "static"
59
+ // }
60
+ // })
64
61
 
65
- let dataList = await InternalData.getObjectActions(objectName, this.userId);
66
- if (!_.isEmpty(dataList)) {
67
- dataList.forEach((doc) => {
68
- if (!_.find(this.data.values, (value) => {
69
- return value.name === doc.name
70
- })) {
71
- this.data.values.push(Object.assign({_id: `${objectName}.${doc.name}`}, doc));
72
- }
73
- })
74
- const records = objectql.getSteedosSchema().metadataDriver.find(this.data.values, this.query, spaceId);
75
- if (records.length > 0) {
76
- this.data.values = records;
77
- } else {
78
- this.data.values.length = 0;
62
+ _.each(this.data.values, (item)=>{
63
+ if(item.visible != false){
64
+ item.visible = true
79
65
  }
80
- }
66
+ })
67
+
81
68
  },
82
69
  afterCount: async function(){
83
70
  delete this.query.fields;
@@ -95,6 +82,15 @@ module.exports = {
95
82
  }
96
83
  }
97
84
  }
85
+
86
+ if(this.data.values){
87
+ if(this.data.values.visibleOn){
88
+ this.data.values.visible_type = "expression"
89
+ }else if(this.data.values.visible === true){
90
+ this.data.values.visible_type = "static"
91
+ }
92
+ }
93
+
98
94
  },
99
95
  afterDelete: async function(){
100
96
  await sleep(1000 * 2);
@@ -217,6 +217,12 @@ const initSummaryDoc = async (doc) => {
217
217
 
218
218
  module.exports = {
219
219
  afterFind: async function(){
220
+
221
+
222
+ _.each(this.data.values, (item)=>{
223
+ item.is_customize = true
224
+ })
225
+
220
226
  let filters = InternalData.parserFilters(this.query.filters);
221
227
  let objectName = filters.object;
222
228
  if(!objectName && filters._id && filters._id.indexOf(".") > -1){
@@ -243,7 +249,12 @@ module.exports = {
243
249
  if(obj){
244
250
  this.data.values = _.map(this.data.values, (item)=>{
245
251
  if(item.is_system){
246
- return Object.assign(item, _.find(obj.fields, (field)=>{return field.name === item.name}))
252
+ const mField = _.find(obj.fields, (field)=>{return field.name === item.name})
253
+ if(mField){
254
+ return Object.assign(item, mField, mField?.override || {})
255
+ }else{
256
+ return item;
257
+ }
247
258
  }else{
248
259
  return item;
249
260
  }
@@ -262,6 +273,15 @@ module.exports = {
262
273
  if(query.fields && _.isArray(query.fields) && !_.include(query.fields, 'type')){
263
274
  query.fields.push('type')
264
275
  }
276
+
277
+
278
+ let filters = InternalData.parserFilters(this.query.filters);
279
+ if(filters._id && _.isString(filters._id) && filters._id.indexOf(".") > -1){
280
+ const [objectName, fieldName] = filters._id.split('.');
281
+ query.filters = [['object', '=', objectName], ['name', '=', fieldName]]
282
+ }
283
+
284
+
265
285
  },
266
286
  beforeAggregate: async function(){
267
287
  const { query } = this;
@@ -300,10 +320,13 @@ module.exports = {
300
320
  this.data.values = field;
301
321
  }
302
322
  }
323
+ }else{
324
+ this.data.values.is_customize = true
303
325
  }
304
326
  },
305
327
  beforeInsert: async function () {
306
328
  let doc = this.doc;
329
+ delete doc.is_customize
307
330
  validateDoc(doc);
308
331
  await checkFormulaInfiniteLoop(doc);
309
332
  await checkMasterDetailTypeField(doc);
@@ -328,6 +351,7 @@ module.exports = {
328
351
  },
329
352
  beforeUpdate: async function () {
330
353
  let { doc, object_name, id} = this;
354
+ delete doc.is_customize
331
355
  validateDoc(doc);
332
356
  // const dbDoc = await objectql.getObject(object_name).findOne(id)
333
357
  const dbDoc = objectql.wrapAsync(async function(){
@@ -18,7 +18,7 @@ module.exports = {
18
18
  },
19
19
  afterFind: async function(){
20
20
  const { spaceId } = this;
21
- let dataList = register.getAllObjectValidationRules();
21
+ let dataList = await register.getAllObjectValidationRules();
22
22
  if (!_.isEmpty(dataList)) {
23
23
  dataList.forEach((doc) => {
24
24
  if (!_.find(this.data.values, (value) => {
@@ -36,25 +36,6 @@ module.exports = {
36
36
  }
37
37
 
38
38
  },
39
- afterAggregate: async function(){
40
- const { spaceId } = this;
41
- let dataList = register.getAllObjectValidationRules();
42
- if (!_.isEmpty(dataList)) {
43
- dataList.forEach((doc) => {
44
- if (!_.find(this.data.values, (value) => {
45
- return value.name === doc.name
46
- })) {
47
- this.data.values.push(doc);
48
- }
49
- })
50
- const records = objectql.getSteedosSchema().metadataDriver.find(this.data.values, this.query, spaceId);
51
- if (records.length > 0) {
52
- this.data.values = records;
53
- } else {
54
- this.data.values.length = 0;
55
- }
56
- }
57
- },
58
39
  afterCount: async function(){
59
40
  delete this.query.fields;
60
41
  let result = await objectql.getObject(this.object_name).find(this.query, await auth.getSessionByUserId(this.userId, this.spaceId))
@@ -62,7 +43,7 @@ module.exports = {
62
43
  },
63
44
  afterFindOne: async function(){
64
45
  if (_.isEmpty(this.data.values)) {
65
- const all = register.getAllObjectValidationRules();
46
+ const all = await register.getAllObjectValidationRules();
66
47
  const id = this.id;
67
48
  this.data.values = _.find(all, function (item) {
68
49
  return item._id === id
@@ -17,15 +17,15 @@ module.exports = {
17
17
  afterFind: async function(){
18
18
  let userId = this.userId
19
19
  let spaceId = this.spaceId;
20
- for (const doc of this.data.values) {
21
- doc.fields = Object.assign({}, doc.fields, await InternalData.getDefaultSysFields(doc.name, userId)) ;
22
- }
23
- // this.data.values = this.data.values.concat(await InternalData.findObjects(userId, this.query.filters));
20
+
21
+ _.each(this.data.values, (item)=>{
22
+ item.is_customize = true
23
+ })
24
24
 
25
25
  this.data.values = this.data.values.concat(await InternalData.getObjects(userId));
26
26
 
27
27
  this.data.values = objectql.getSteedosSchema().metadataDriver.find(this.data.values, this.query, spaceId);
28
-
28
+
29
29
  _.each(this.data.values, function(value){
30
30
  if(value){
31
31
  delete value.actions;
@@ -44,6 +44,8 @@ module.exports = {
44
44
  afterFindOne: async function(){
45
45
  if(_.isEmpty(this.data.values)){
46
46
  this.data.values = await InternalData.getObject(this.id, this.userId);
47
+ }else{
48
+ this.data.values.is_customize = true
47
49
  }
48
50
  if(this.data.values){
49
51
  delete this.data.values.actions;
@@ -104,8 +106,13 @@ module.exports = {
104
106
  // })
105
107
  await sleep(1000 * 2)
106
108
  },
109
+ beforeInsert: async function () {
110
+ let doc = this.doc;
111
+ delete doc.is_customize
112
+ },
107
113
  beforeUpdate: async function () {
108
114
  const { doc, id, object_name } = this;
115
+ delete doc.is_customize
109
116
  // 如果用户修改了apiname,则校验 数据源必须一致为default数据源;且数据库中不能有新的apiname对应的表
110
117
  if (_.has(doc, 'name')) {
111
118
  const obj = this.getObject(object_name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steedos/standard-object-database",
3
- "version": "2.7.0-beta.2",
3
+ "version": "2.7.0-beta.21",
4
4
  "main": "package.service.js",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -12,10 +12,10 @@
12
12
  "description": "steedos package",
13
13
  "dependencies": {
14
14
  "@steedos-widgets/amis-lib": "^1.0.22",
15
- "@steedos/metadata-core": "2.7.0-beta.2",
16
- "@steedos/standard-objects": "2.7.0-beta.2"
15
+ "@steedos/metadata-core": "2.7.0-beta.21",
16
+ "@steedos/standard-objects": "2.7.0-beta.21"
17
17
  },
18
18
  "repository": {},
19
19
  "license": "MIT",
20
- "gitHead": "09bc89238d07c7abc29e163c73dc85f0bf8b0402"
20
+ "gitHead": "a537a0f77a8e8a804c9413b3be3a7e2f843f9b7d"
21
21
  }
@@ -2,7 +2,7 @@
2
2
  * @Author: sunhaolin@hotoa.com
3
3
  * @Date: 1985-10-26 16:15:00
4
4
  * @LastEditors: baozhoutao@steedos.com
5
- * @LastEditTime: 2024-02-29 10:24:41
5
+ * @LastEditTime: 2024-03-20 14:30:13
6
6
  * @Description:
7
7
  */
8
8
  "use strict";
@@ -115,8 +115,7 @@ module.exports = {
115
115
  }
116
116
  }
117
117
  if(data.is_system){
118
- // 'label' 先禁止编辑label , 目前由于i18n的问题导致 label无效.
119
- data = _.pick(data, ['defaultValue', 'group', 'rows', 'sort_no', 'is_wide', 'index', 'sortable', 'searchable', 'filterable', 'visible_on', 'inlineHelpText', 'description', 'amis', 'required', 'unique', 'readonly', 'hidden', 'deleted_lookup_record_behavior', 'enable_thousands', 'autonumber_enable_modify']);
118
+ data = _.pick(data, ['label', 'defaultValue', 'group', 'rows', 'sort_no', 'is_wide', 'index', 'sortable', 'searchable', 'filterable', 'visible_on', 'inlineHelpText', 'description', 'amis', 'required', 'unique', 'readonly', 'hidden', 'deleted_lookup_record_behavior', 'enable_thousands', 'autonumber_enable_modify', 'auto_fill_mapping']);
120
119
  }
121
120
  return object.update(id, data, userSession)
122
121
  },