@steedos/service-plugin-amis 2.2.36 → 2.2.39

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.
@@ -43,8 +43,46 @@
43
43
  }
44
44
  });
45
45
 
46
+ const normalizeLink = (to, location = window.location) => {
47
+ to = to || '';
48
+
49
+ if (to && to[0] === '#') {
50
+ to = location.pathname + location.search + to;
51
+ } else if (to && to[0] === '?') {
52
+ to = location.pathname + to;
53
+ }
54
+
55
+ const idx = to.indexOf('?');
56
+ const idx2 = to.indexOf('#');
57
+ let pathname = ~idx
58
+ ? to.substring(0, idx)
59
+ : ~idx2
60
+ ? to.substring(0, idx2)
61
+ : to;
62
+ let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';
63
+ let hash = ~idx2 ? to.substring(idx2) : location.hash;
64
+
65
+ if (!pathname) {
66
+ pathname = location.pathname;
67
+ } else if (pathname[0] != '/' && !/^https?\:\/\//.test(pathname)) {
68
+ let relativeBase = location.pathname;
69
+ const paths = relativeBase.split('/');
70
+ paths.pop();
71
+ let m;
72
+ while ((m = /^\.\.?\//.exec(pathname))) {
73
+ if (m[0] === '../') {
74
+ paths.pop();
75
+ }
76
+ pathname = pathname.substring(m[0].length);
77
+ }
78
+ pathname = paths.concat(pathname).join('/');
79
+ }
80
+
81
+ return pathname + search + hash;
82
+ };
83
+
46
84
  const AmisEnv = {
47
- getModalContainer: ()=>{
85
+ getModalContainer: (props)=>{
48
86
  let div = document.querySelector("#amisModalContainer");
49
87
  if(!div){
50
88
  div = document.createElement('div');
@@ -55,24 +93,58 @@
55
93
  }
56
94
  return div;
57
95
  },
96
+ jumpTo: (to, action) => {
97
+ if (to === 'goBack') {
98
+ return window.history.back();
99
+ }
100
+
101
+ to = normalizeLink(to);
102
+
103
+ if (action && action.actionType === 'url') {
104
+ action.blank === false ? (window.location.href = to) : window.open(to);
105
+ return;
106
+ }
107
+
108
+ // 主要是支持 nav 中的跳转
109
+ if (action && to && action.target) {
110
+ window.open(to, action.target);
111
+ return;
112
+ }
113
+
114
+ if (/^https?:\/\//.test(to)) {
115
+ window.location.replace(to);
116
+ } else {
117
+ FlowRouter.go(to);
118
+ }
119
+ },
58
120
  theme: 'antd',
59
121
  };
60
122
 
61
123
  const AmisRender = function (props) {
62
- const env = props.env;
124
+ let env = props.env;
63
125
  const schema = props.schema;
64
126
  const data = props.data;
65
127
  const name = props.name;
128
+ if(props.pageType === 'form'){
129
+ env = Object.assign({
130
+ getModalContainer: ()=>{
131
+ return document.querySelector('.amis-scope');
132
+ }
133
+ }, env);
134
+ }
66
135
  return (React.createElement("div", { className: "amis-scope" }, AmisSDK.AmisRender(schema, {data, name}, Object.assign({}, AmisEnv, env))));
67
136
  };
68
137
 
69
- Builder.registerComponent(AmisRender, {
70
- name: 'Amis',
71
- inputs: [
72
- { name: 'schema', type: 'object' },
73
- { name: 'data', type: 'object' },
74
- { name: 'name', type: 'string' }
75
- ]
138
+ //Amis SDK 中已清理了monaco, 所以这里需要提前注册,否则会导致amis code类型报错
139
+ Builder.initMonaco().then(()=>{
140
+ Builder.registerComponent(AmisRender, {
141
+ name: 'Amis',
142
+ inputs: [
143
+ { name: 'schema', type: 'object' },
144
+ { name: 'data', type: 'object' },
145
+ { name: 'name', type: 'string' }
146
+ ]
147
+ });
76
148
  });
77
149
  });
78
150
  });
@@ -0,0 +1,156 @@
1
+ /*
2
+ * @Author: baozhoutao@steedos.com
3
+ * @Date: 2022-05-20 17:42:20
4
+ * @LastEditors: baozhoutao@steedos.com
5
+ * @LastEditTime: 2022-06-01 15:44:44
6
+ * @Description: 提供辅助函数
7
+ */
8
+ (function(){
9
+ // # 日期类型: date, datetime 支持操作符: "=", "<>", "<", ">", "<=", ">="
10
+ // # 文本类型: text, textarea, html 支持操作符: "=", "<>", "contains", "notcontains", "startswith"
11
+ // # 选择类型: lookup, master_detail, select 支持操作符: "=", "<>"
12
+ // # 数值类型: currency, number 支持操作符: "=", "<>", "<", ">", "<=", ">="
13
+ // # 布尔类型: boolean 支持操作符: "=", "<>"
14
+ // # 数组类型: checkbox, [text] 支持操作符: "=", "<>"
15
+
16
+ const DATE_DATETIME_BETWEEN_VALUES = ['last_year', 'this_year', 'next_year', 'last_quarter', 'this_quarter', 'next_quarter', 'last_month', 'this_month', 'next_month', 'last_week', 'this_week', 'next_week', 'yestday', 'today', 'tomorrow', 'last_7_days', 'last_30_days', 'last_60_days', 'last_90_days', 'last_120_days', 'next_7_days', 'next_30_days', 'next_60_days', 'next_90_days', 'next_120_days'];
17
+
18
+ /**
19
+ *
20
+ */
21
+
22
+ const opMaps = {
23
+ equal: '=',
24
+ not_equal: '!=',
25
+ less: '<',
26
+ less_or_equal: '<=',
27
+ greater: '>',
28
+ greater_or_equal: '>=',
29
+ between: 'between',
30
+ not_between: 'not_between', // TODO 不支持待@steedos/filters 增强
31
+ is_empty: 'is_empty', // TODO 不支持待@steedos/filters 增强
32
+ is_not_empty: 'is_not_empty', // TODO 不支持待@steedos/filters 增强
33
+ select_equals: '=',
34
+ select_not_equals: '!=',
35
+ select_any_in: 'in',
36
+ select_not_any_in: '<>',
37
+ like: 'contains',
38
+ not_like: 'notcontains',
39
+ starts_with: 'startswith',
40
+ ends_with: 'endswith'
41
+ }
42
+
43
+ const isGroup = (item)=>{
44
+ return _.has(item, 'conjunction');
45
+ }
46
+
47
+ const conditionGroupToFilters = (group)=>{
48
+ const filters = [];
49
+ const {conjunction, children} = group;
50
+ if(conjunction && children){
51
+ children.forEach((item)=>{
52
+ if(filters.length > 0){
53
+ filters.push(conjunction);
54
+ }
55
+ if(isGroup(item)){
56
+ const filter = conditionGroupToFilters(item);
57
+ if(filter && filter.length > 0){
58
+ filters.push(filter)
59
+ }
60
+ }else{
61
+ const filter = conditionItemToFilters(item);
62
+ if(filter){
63
+ filters.push(filter)
64
+ }
65
+ }
66
+ })
67
+ }
68
+ return filters;
69
+ };
70
+
71
+ const conditionItemToFilters = (item)=>{
72
+ const { left , op, right } = item;
73
+ if(left && left.type === 'field'){
74
+ if(op){
75
+ if(op.startsWith('between:')){
76
+ const array = op.split(':');
77
+ return [left.field, array[0], array[1]];
78
+ }else{
79
+ if(right != null){
80
+ return [left.field, opMaps[op], right]
81
+ }
82
+ }
83
+ }
84
+ }
85
+ };
86
+
87
+ // const conditionChildrenToFilters = (children)=>{
88
+
89
+ // }
90
+ const filterToConditionItem = (filter)=>{
91
+ if(filter.length === 3){
92
+ const op =lodash.findKey(opMaps, (value)=>{ return value === filter[1]});
93
+ if(op === 'between' && lodash.includes(DATE_DATETIME_BETWEEN_VALUES, filter[2])){
94
+ return {
95
+ left:{
96
+ type: 'field',
97
+ field: filter[0]
98
+ },
99
+ op: `${op}:${filter[2]}`
100
+ }
101
+ }else{
102
+ return {
103
+ left:{
104
+ type: 'field',
105
+ field: filter[0]
106
+ },
107
+ op: op,
108
+ right: filter[2]
109
+ }
110
+ }
111
+ }else{
112
+ console.warn(`无效的filter:${JSON.stringify(filter)}`)
113
+ }
114
+ }
115
+
116
+ const filterObjectToArray = (filter)=>{
117
+ if(!lodash.isArray(filter) && lodash.isObject(filter)){
118
+ return [filter.field, filter.operation, filter.value];
119
+ };
120
+ return filter;
121
+ }
122
+
123
+ const filtersToConditionGroup = (filters)=>{
124
+ filters = filterObjectToArray(filters);
125
+
126
+ const conditions = {
127
+ conjunction: 'and',
128
+ children: []
129
+ };
130
+ if(!filters || filters.length ==0){
131
+ return conditions
132
+ }
133
+ filters.forEach((filter)=>{
134
+ filter = filterObjectToArray(filter);
135
+ if(filter === 'or' || filter === 'and'){
136
+ conditions.conjunction = filter;
137
+ }else{
138
+ if(filter.length === 3 && filter.indexOf("and") == -1 && filter.indexOf("or") == -1){
139
+ conditions.children.push(filterToConditionItem(filter));
140
+ }else{
141
+ conditions.children.push(filtersToConditionGroup(filter));
142
+ }
143
+ }
144
+ });
145
+ return conditions;
146
+ }
147
+
148
+ window.amisConvert = {
149
+ conditionsToFilters: (conditions)=>{
150
+ return conditionGroupToFilters(conditions);
151
+ },
152
+ filtersToConditions: (filters)=>{
153
+ return filtersToConditionGroup(filters);
154
+ }
155
+ }
156
+ })()
@@ -0,0 +1,153 @@
1
+ /*
2
+ * @Author: baozhoutao@steedos.com
3
+ * @Date: 2022-05-20 17:42:20
4
+ * @LastEditors: baozhoutao@steedos.com
5
+ * @LastEditTime: 2022-06-01 18:26:42
6
+ * @Description: 提供辅助函数
7
+ */
8
+ (function(){
9
+ const filtersAmisSchema = {
10
+ "type": "page",
11
+ "title": "过滤器",
12
+ "name": "steedos-filters",
13
+ "body": [
14
+ {
15
+ "type": "form",
16
+ "title": "过滤器",
17
+ "body": [
18
+ {
19
+ "label": "",
20
+ "type": "condition-builder",
21
+ "name": "filters",
22
+ "description": "",
23
+ "id": "filters",
24
+ "source": {
25
+ "method": "get",
26
+ "url": "${context.rootUrl}/service/api/amis-metadata-listviews/getFilterFields?objectName=${objectName}",
27
+ "dataType": "json"
28
+ },
29
+ "disabled": false
30
+ }
31
+ ],
32
+ "id": "filtersForm",
33
+ "wrapWithPanel": false
34
+ }
35
+ ],
36
+ "regions": [
37
+ "body"
38
+ ],
39
+ "data": {
40
+ "recordId": "",
41
+ "initialValues": {
42
+ },
43
+ "appId": "builder",
44
+ "title": ""
45
+ }
46
+ };
47
+
48
+ //使用原creator逻辑
49
+ const canSaveFilters = function() {
50
+ var current_filter_items, current_filter_logic, current_filter_scope, is_filter_list_disabled, list_view_obj, original_filter_items, original_filter_logic, original_filter_scope;
51
+ list_view_obj = Creator.Collections.object_listviews.findOne(Session.get("list_view_id"));
52
+ is_filter_list_disabled = !list_view_obj || list_view_obj.owner !== Meteor.userId();
53
+ if (is_filter_list_disabled) {
54
+ return false;
55
+ }
56
+ if (list_view_obj) {
57
+ original_filter_scope = list_view_obj.filter_scope;
58
+ original_filter_items = list_view_obj.filters;
59
+ original_filter_logic = list_view_obj.filter_logic;
60
+ current_filter_logic = Session.get("filter_logic");
61
+ current_filter_scope = Session.get("filter_scope");
62
+ current_filter_items = Session.get("filter_items");
63
+ if (original_filter_scope === current_filter_scope && JSON.stringify(original_filter_items) === JSON.stringify(current_filter_items)) {
64
+ if ((!current_filter_logic && !original_filter_logic) || (current_filter_logic === original_filter_logic)) {
65
+ return false;
66
+ } else {
67
+ return true;
68
+ }
69
+ } else {
70
+ return true;
71
+ }
72
+ }
73
+ }
74
+
75
+ Creator.showListFilter = (objectName, listView, data, props)=>{
76
+ const pageName = `${objectName}-list-filter`;
77
+ const canSave = canSaveFilters();
78
+ return Steedos.Page.render(SteedosUI.Drawer, {
79
+ name: pageName,
80
+ render_engine: 'amis',
81
+ schema: filtersAmisSchema,
82
+ object_name: Session.get("object_name"),
83
+ type: 'page'
84
+ }, Object.assign({drawerName: pageName}, data, {
85
+ objectName: Session.get("object_name"), // TODO 应该传入变量
86
+ filters: window.amisConvert.filtersToConditions(Session.get("filter_items")),
87
+ title: "过滤器"
88
+ }), {
89
+ props: {
90
+ mask: false,
91
+ width: 550,
92
+ style: null,
93
+ extra: React.createElement(
94
+ SteedosUI.components.Space,
95
+ {},
96
+ [
97
+ React.createElement(SteedosUI.components.Button, {
98
+ onClick: function(){
99
+ SteedosUI.getRef(pageName)?.close();
100
+ }
101
+ } ,'取消'),
102
+ React.createElement(SteedosUI.components.Button, {
103
+ onClick: canSave ? function(){
104
+
105
+ const formValues = window.amisScopes[pageName].getComponentById("filtersForm").getValues()
106
+ const filters = window.amisConvert.conditionsToFilters(formValues.filters);
107
+ Session.set("filter_items", filters);
108
+
109
+ //使用原creator逻辑
110
+ var filter_items, filter_scope, format_logic, list_view_id;
111
+ list_view_id = Session.get("list_view_id");
112
+ filter_items = Session.get("filter_items");
113
+ filter_scope = Session.get("filter_scope");
114
+ filter_items = _.map(filter_items, function(obj) {
115
+ if (_.isEmpty(obj)) {
116
+ return false;
117
+ } else {
118
+ return obj;
119
+ }
120
+ });
121
+ filter_items = _.compact(filter_items);
122
+ format_logic = null;
123
+ if (Creator.validateFilters(filter_items, format_logic)) {
124
+ Session.set("list_view_visible", false);
125
+ filter_items.forEach(function(item) {
126
+ delete item.start_value;
127
+ return delete item.end_value;
128
+ });
129
+ return Meteor.call("update_filters", list_view_id, filter_items, filter_scope, format_logic, function(error, result) {
130
+ Session.set("list_view_visible", true);
131
+ if (error) {
132
+ return console.log("error", error);
133
+ } else if (result) {
134
+ SteedosUI.getRef(pageName)?.close();
135
+ return Session.set("filter_items", filter_items);
136
+ }
137
+ });
138
+ }
139
+ } : function(){
140
+ const formValues = window.amisScopes[pageName].getComponentById("filtersForm").getValues()
141
+ const filters = window.amisConvert.conditionsToFilters(formValues.filters);
142
+ Session.set("filter_items", filters);
143
+ SteedosUI.getRef(pageName)?.close();
144
+ },
145
+ type: 'primary'
146
+ } , canSave ? '保存': '应用')
147
+ ]
148
+ )
149
+ }
150
+ });
151
+ }
152
+
153
+ })()