@steedos-widgets/amis-lib 1.3.17-beta.2 → 1.3.18

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.
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _$1 from 'lodash';
2
- import ___default, { isEmpty, isArray, each, find, endsWith, cloneDeep, forEach, includes, trimEnd, isBoolean, omitBy, isNil, toArray, mergeWith, get, map, isString, union, has, slice, defaultsDeep as defaultsDeep$1, isObject as isObject$1, filter, startsWith } from 'lodash';
2
+ import ___default, { isEmpty, isArray, each, find, endsWith, cloneDeep, forEach, includes, trimEnd, isBoolean, omitBy, isNil, toArray, mergeWith, get, map, isString, union, has, slice, defaultsDeep as defaultsDeep$1, isObject as isObject$1, clone, filter, startsWith } from 'lodash';
3
3
  import i18next from 'i18next';
4
4
  export { default as i18next } from 'i18next';
5
5
  import { initReactI18next } from 'react-i18next';
@@ -1986,9 +1986,9 @@ function getFieldWidth(width){
1986
1986
  const defaultWidth = "unset";//用于使table内的td标签下生成div,实现将快速编辑按钮固定在右侧的效果,并不是为了unset效果
1987
1987
  if(typeof width == 'string'){
1988
1988
  if(isNaN(width)){
1989
- return width;
1989
+ return width || defaultWidth;
1990
1990
  }else {
1991
- return Number(width);
1991
+ return Number(width) || defaultWidth;
1992
1992
  }
1993
1993
  }else if(typeof width == 'number'){
1994
1994
  return width;
@@ -2089,6 +2089,7 @@ async function getTableColumns(fields, options){
2089
2089
  width: getFieldWidth(field.width),
2090
2090
  toggled: field.toggled,
2091
2091
  className,
2092
+ inputClassName: "inline",
2092
2093
  static: true,
2093
2094
  }, field.amis, {name: field.name});
2094
2095
  }
@@ -2126,6 +2127,7 @@ async function getTableColumns(fields, options){
2126
2127
  tpl: tpl,
2127
2128
  toggled: field.toggled,
2128
2129
  className,
2130
+ inputClassName: "inline",
2129
2131
  static: true,
2130
2132
  options: field.type === 'html' ? {html: true} : null
2131
2133
  // toggled: true
@@ -2147,8 +2149,8 @@ async function getTableColumns(fields, options){
2147
2149
  const href = Router.getObjectDetailPath({
2148
2150
  ...options, formFactor: options.formFactor, appId: "${appId}", objectName: options.objectName || "${objectName}", recordId: `\${${options.idFieldName}}`
2149
2151
  });
2150
- columns[0].type = "tpl";
2151
- columns[0].tpl = `<a href="${href}">\${${columns[0].name}}</a>`;
2152
+ columns[1].type = "tpl";
2153
+ columns[1].tpl = `<a href="${href}">\${${columns[1].name}}</a>`;
2152
2154
  }
2153
2155
  return columns;
2154
2156
  }
@@ -2615,19 +2617,25 @@ async function getTableApi(mainObject, fields, options){
2615
2617
  if(options.isRelated){
2616
2618
  api.url += "&recordId=${_master.recordId}";
2617
2619
  }
2618
- // api.cache = 3000;
2619
-
2620
+ api.cache = 3000;
2620
2621
  api.data.$term = "$term";
2621
2622
  api.data.term = "$term";
2622
2623
  api.data.$self = "$$";
2623
2624
  api.data.self = "$$";
2624
2625
  api.data.filter = "$filter";
2625
- api.data.__filterFormValues = "${__filterFormValues}";
2626
- api.data.__serachBoxValues = "${__serachBoxValues}";
2627
2626
  api.data.loaded = "${loaded}";
2628
2627
  api.data.listViewId = "${listViewId}";
2629
2628
  api.data.listName = "${listName}";
2630
2629
  api.requestAdaptor = `
2630
+ let __changedFilterFormValues = api.data.$self.__changedFilterFormValues || {};
2631
+ let __changedSearchBoxValues = api.data.$self.__changedSearchBoxValues || {};
2632
+ // 把表单搜索和快速搜索中的change事件中记录的过滤条件也拼到$self中,是为解决触发搜索请求时,两边输入的过滤条件都带上,即:
2633
+ // 有时在搜索表单中输入过滤条件事,忘记点击回车键或搜索按钮,而是进一步修改快速搜索框中的关键字点击其中回车键触发搜索
2634
+ // 这种情况下,触发的搜索请求中没有带上搜索表单中输入的过滤条件。
2635
+ // 反过来先在快速搜索框中输入过滤条件却不点击其中回车键触发搜索,而是到搜索表单中触发搜索请求也是一样的。
2636
+ // 这里直接合并到api.data.$self,而不是后面定义的selfData变量,是因为可以省去在接收适配器中写一样的合并逻辑
2637
+ // 如果有问题可以改为合并到selfData变量中,但是要在接收适配器中写上一样的合并逻辑,否则里面的过滤条件不会存入本地存储中
2638
+ Object.assign(api.data.$self, __changedSearchBoxValues, __changedFilterFormValues);
2631
2639
  // selfData 中的数据由 CRUD 控制. selfData中,只能获取到 CRUD 给定的data. 无法从数据链中获取数据.
2632
2640
  let selfData = JSON.parse(JSON.stringify(api.data.$self));
2633
2641
  // 保留一份初始data,以供自定义发送适配器中获取原始数据。
@@ -2697,11 +2705,7 @@ async function getTableApi(mainObject, fields, options){
2697
2705
  userFilters = [["${valueField.name}", "=", selfData.value]];
2698
2706
  }
2699
2707
 
2700
- const __filterFormValues = api.data.__filterFormValues;
2701
- const __serachBoxValues = api.data.__serachBoxValues;
2702
- // 筛选按钮
2703
- const filterSelfData = __filterFormValues ? __filterFormValues : selfData;
2704
- var searchableFilter = SteedosUI.getSearchFilter(filterSelfData) || [];
2708
+ var searchableFilter = SteedosUI.getSearchFilter(selfData) || [];
2705
2709
  if(searchableFilter.length > 0){
2706
2710
  if(userFilters.length > 0 ){
2707
2711
  userFilters = [userFilters, 'and', searchableFilter];
@@ -2722,8 +2726,7 @@ async function getTableApi(mainObject, fields, options){
2722
2726
  })
2723
2727
  }
2724
2728
 
2725
- const keyWords = __serachBoxValues ? __serachBoxValues.__keywords : selfData.__keywords;
2726
- var keywordsFilters = SteedosUI.getKeywordsSearchFilter(keyWords, allowSearchFields);
2729
+ var keywordsFilters = SteedosUI.getKeywordsSearchFilter(selfData.__keywords, allowSearchFields);
2727
2730
  if(keywordsFilters && keywordsFilters.length > 0){
2728
2731
  userFilters.push(keywordsFilters);
2729
2732
  }
@@ -2843,7 +2846,25 @@ async function getTableApi(mainObject, fields, options){
2843
2846
  if(enable_tree){
2844
2847
  const records = payload.data.rows || [];
2845
2848
  const getTreeOptions = SteedosUI.getTreeOptions
2846
- payload.data.rows = getTreeOptions(records,{"valueField":"_id"});
2849
+ let isTreeOptionsComputed = false;
2850
+ if(records.length === 1 && records[0].children){
2851
+ isTreeOptionsComputed = true;
2852
+ }
2853
+ if(!isTreeOptionsComputed){
2854
+ // 如果api接口设置在缓存,缓存期间并不会重新请求接口,payload.data.rows是上次计算后的结果
2855
+ payload.data.rows = getTreeOptions(records,{"valueField":"_id"});
2856
+ }
2857
+ try{
2858
+ setTimeout(() => {
2859
+ let expandBtn = $('.steedos-object-listview-content .antd-Table-content .antd-Table-table thead .antd-Table-expandBtn');
2860
+ if(expandBtn && expandBtn.length > 0 && !expandBtn.hasClass("is-active")){
2861
+ expandBtn[0].click();
2862
+ }
2863
+ }, 600);
2864
+ }
2865
+ catch(ex){
2866
+ console.error("tree数据格式展开异常:", ex);
2867
+ }
2847
2868
  }
2848
2869
 
2849
2870
 
@@ -2876,19 +2897,6 @@ async function getTableApi(mainObject, fields, options){
2876
2897
  selfData.page = localListViewProps.page || 1;
2877
2898
  }
2878
2899
  }
2879
-
2880
- // 列表视图(对象表格)筛选按钮表单输入框输入内容后,如果不按回车键或者搜索按钮,selfData中该输入框是没有最新值的。
2881
- const __filterFormValues = api.body.__filterFormValues;
2882
- if(__filterFormValues){
2883
- let filterFormValues = JSON.parse(JSON.stringify(__filterFormValues)) || {};
2884
- selfData = Object.assign({}, selfData, filterFormValues);
2885
- }
2886
- // “搜索此列表”搜索框同理。
2887
- const __serachBoxValues = api.body.__serachBoxValues;
2888
- if(__serachBoxValues){
2889
- let serachBoxValues = JSON.parse(JSON.stringify(__serachBoxValues)) || {};
2890
- selfData = Object.assign({}, selfData, serachBoxValues);
2891
- }
2892
2900
 
2893
2901
  delete selfData.context;
2894
2902
  delete selfData.global;
@@ -5663,6 +5671,7 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
5663
5671
  const filterFormSchema = await getObjectFieldsFilterFormSchema(ctx);
5664
5672
  const keywordsSearchBoxName = ctx.keywordsSearchBoxName || "__keywords";
5665
5673
  const onSearchScript = `
5674
+ // console.log("===onSearchScript=form==");
5666
5675
  const scope = event.context.scoped;
5667
5676
  var filterForm = scope.parent.parent.getComponents().find(function(n){
5668
5677
  return n.props.type === "form";
@@ -5719,25 +5728,13 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
5719
5728
  crudService && crudService.setData({isFieldsFilterEmpty, showFieldsFilter});
5720
5729
  `;
5721
5730
  const onCancelScript = `
5722
- doAction(
5723
- {
5724
- "componentId": 'service_${ctx.crudId}',
5725
- "actionType": "setValue",
5726
- "args": {
5727
- "value": {
5728
- "__filterFormValues": null
5729
- }
5730
- }
5731
- }
5732
- )
5731
+ // console.log("===onCancelScript=form==");
5733
5732
  const scope = event.context.scoped;
5734
5733
  var filterForm = scope.parent.parent.getComponents().find(function(n){
5735
5734
  return n.props.type === "form";
5736
5735
  });
5737
5736
  var filterFormValues = filterForm.getValues();
5738
- var listView = scope.parent.parent.parent.getComponents().find(function(n){
5739
- return n.props.type === "crud";
5740
- });
5737
+ let crud = SteedosUI.getClosestAmisComponentByType(scope, "crud");
5741
5738
  const removedValues = {};
5742
5739
  for(var k in filterFormValues){
5743
5740
  if(/^__searchable__/.test(k)){
@@ -5752,7 +5749,7 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
5752
5749
  if(localListViewProps){
5753
5750
  localListViewProps = JSON.parse(localListViewProps);
5754
5751
  for(var k in localListViewProps){
5755
- if(k !== "__keywords"){
5752
+ if(/^__searchable__/.test(k)){
5756
5753
  removedValues[k] = null;
5757
5754
  }
5758
5755
  }
@@ -5763,20 +5760,35 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
5763
5760
  //lookup字段保留快速搜索条件
5764
5761
  removedValues[keywordsSearchBoxName] = filterFormValues[keywordsSearchBoxName];
5765
5762
  }
5766
- filterForm.reset();
5767
- setTimeout(()=>{
5768
- listView.handleFilterSubmit(removedValues);
5769
- }, 100);
5770
- const filterService = filterForm.context.getComponents().find(function(n){
5771
- return n.props.type === "service";
5772
- });
5773
- filterService.setData({showFieldsFilter: !!!filterService.props.data.showFieldsFilter});
5763
+ filterForm.setValues(removedValues);//会把表单提交到toolbar的快速搜索区域,造成在快速搜索框中触发搜索时再次把搜索表单中的字段值清除掉的bug,已单独在快速搜索框那边添加搜索事件代码处理过了
5764
+ // 以下方法都无法实现清除表单值
5765
+ // filterForm.setValues({}, true)
5766
+ // filterForm.reset();
5767
+ // filterForm.handleAction({},{
5768
+ // "actionType": "setValue",
5769
+ // "args": {
5770
+ // "value": removedValues
5771
+ // }
5772
+ // });
5773
+ // 下面触发clear动作可以清除表单值,且不会把表单提交到toolbar的快速搜索区域,但是会把金额等范围字段清空成非范围字段
5774
+ // filterForm.handleAction({},{
5775
+ // "actionType": "clear"
5776
+ // });
5777
+
5778
+ // 清除__changedFilterFormValues中的值
5779
+ crud && crud.setData({__changedFilterFormValues: {}});
5780
+ filterForm.handleFormSubmit(event);
5781
+ // crud.handleFilterSubmit(removedValues);
5782
+
5783
+ let filterFormService = SteedosUI.getClosestAmisComponentByType(filterForm.context, "service");
5784
+ filterFormService.setData({showFieldsFilter: !!!filterFormService.props.data.showFieldsFilter});
5774
5785
  //触发amis crud 高度重算
5775
5786
  setTimeout(()=>{
5776
5787
  window.dispatchEvent(new Event("resize"))
5777
5788
  }, 100);
5778
5789
  // 移除搜索按钮上的红点
5779
- let crudService = scope.getComponentById("service_listview_" + event.data.objectName);
5790
+ // let crudService = scope.getComponentById("service_listview_" + event.data.objectName);
5791
+ let crudService = crud && SteedosUI.getClosestAmisComponentByType(crud.context, "service");
5780
5792
  crudService && crudService.setData({isFieldsFilterEmpty: true, showFieldsFilter: false});
5781
5793
  `;
5782
5794
  const dataProviderInited = `
@@ -6716,78 +6728,97 @@ function fields$1(){
6716
6728
 
6717
6729
  function fieldsExtend$4(){
6718
6730
  return {
6731
+ "group": "",
6719
6732
  "label": {
6720
6733
  "is_wide": true
6721
6734
  },
6722
6735
  "name": {
6736
+ "group": "",
6723
6737
  "amis": {
6724
6738
  "hidden": true,
6725
6739
  "required": false
6726
6740
  }
6727
6741
  },
6728
6742
  "object_name": {
6743
+ "group": "",
6729
6744
  "amis": {
6730
6745
  "hidden": true
6731
6746
  }
6732
6747
  },
6733
6748
  "filter_scope": {
6749
+ "group": "",
6734
6750
  "amis": {
6735
6751
  "hidden": true,
6736
6752
  "required": false
6737
6753
  }
6738
6754
  },
6739
6755
  "columns": {
6756
+ "group": "",
6740
6757
  "amis": {
6741
6758
  "hidden": true,
6742
6759
  "required": false
6743
6760
  }
6744
6761
  },
6745
6762
  "mobile_columns":{
6763
+ "group": "",
6746
6764
  "amis": {
6747
6765
  "hidden": true,
6748
6766
  "required": false
6749
6767
  }
6750
6768
  },
6751
6769
  "searchable_fields":{
6770
+ "group": "",
6752
6771
  "amis": {
6753
6772
  "hidden": true,
6754
6773
  "required": false
6755
6774
  }
6756
6775
  },
6757
6776
  "filter_fields": {
6777
+ "group": "",
6758
6778
  "amis": {
6759
6779
  "hidden": true,
6760
6780
  "required": false
6761
6781
  }
6762
6782
  },
6763
6783
  "scrolling_mode": {
6784
+ "group": "",
6764
6785
  "amis": {
6765
6786
  "hidden": true,
6766
6787
  "required": false
6767
6788
  }
6768
6789
  },
6769
6790
  "sort": {
6791
+ "group": "",
6770
6792
  "amis": {
6771
6793
  "hidden": true,
6772
6794
  "required": false
6773
6795
  }
6774
6796
  },
6775
6797
  "show_count": {
6798
+ "group": "",
6776
6799
  "amis": {
6777
6800
  "hidden": true,
6778
6801
  "required": false
6779
6802
  }
6780
6803
  },
6781
6804
  "type": {
6805
+ "group": "",
6782
6806
  "amis": {
6783
6807
  "hidden": true,
6784
6808
  "required": false
6785
6809
  }
6786
6810
  },
6787
6811
  "shared": {
6812
+ "group": "",
6788
6813
  "amis": {
6789
6814
  "visibleOn": "${global.user.is_space_admin}"
6790
6815
  }
6816
+ },
6817
+ "filters": {
6818
+ "group": "",
6819
+ "amis": {
6820
+ "hidden": true
6821
+ }
6791
6822
  }
6792
6823
  }
6793
6824
  }
@@ -6934,6 +6965,12 @@ function fieldsExtend$3(){
6934
6965
  "amis": {
6935
6966
  "visibleOn": "${global.user.is_space_admin}"
6936
6967
  }
6968
+ },
6969
+ "filters": {
6970
+ "group": "",
6971
+ "amis": {
6972
+ "hidden": true
6973
+ }
6937
6974
  }
6938
6975
  }
6939
6976
  }
@@ -7272,7 +7309,6 @@ function fieldsExtend$1(){
7272
7309
  }
7273
7310
  },
7274
7311
  "mobile_columns": {
7275
- "group": i18next.t('frontend_listview_control_columns_mobile_group'),
7276
7312
  "amis": {
7277
7313
  "type": "transfer",
7278
7314
  "sortable": true,
@@ -7642,7 +7678,8 @@ crudService && crudService.setData({showFieldsFilter: toShowFieldsFilter});
7642
7678
  // }
7643
7679
  `;
7644
7680
 
7645
- function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLookup = false, keywordsSearchBoxName = "__keywords", crudId } = {}){
7681
+ // function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLookup = false, keywordsSearchBoxName = "__keywords", crudId } = {}){
7682
+ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLookup = false, keywordsSearchBoxName = "__keywords" } = {}){
7646
7683
  const searchableFieldsLabel = [];
7647
7684
  _.each(mainObject.fields, function (field) {
7648
7685
  if (isFieldQuickSearchable(field, mainObject.NAME_FIELD_KEY)) {
@@ -7658,6 +7695,33 @@ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLooku
7658
7695
  crudKeywords = (localListViewProps && localListViewProps.__keywords) || "";
7659
7696
  }
7660
7697
 
7698
+ const onChangeScript = `
7699
+ const scope = event.context.scoped;
7700
+ let crud = SteedosUI.getClosestAmisComponentByType(scope, "crud");
7701
+ // let crudService = crud && SteedosUI.getClosestAmisComponentByType(crud.context, "service");
7702
+ let __changedSearchBoxValues = {};
7703
+ __changedSearchBoxValues["${keywordsSearchBoxName}"] = event.data["${keywordsSearchBoxName}"];
7704
+ // crudService && crudService.setData({__changedSearchBoxValues: __changedSearchBoxValues});
7705
+ // 这里不用crudService而用crud是因为lookup字段弹出的列表中的crudService中的变量无法传入crud的发送适配器中
7706
+ crud && crud.setData({__changedSearchBoxValues: __changedSearchBoxValues});
7707
+ `;
7708
+
7709
+ // onSearchScript中加上了onChangeScript中的脚本,是因为amis 3.2不能用change事件执行onChangeScript
7710
+ // 而点击回车按键又不会触发blur事件,所以只能每次回车事件中额外再执行一次onChangeScript
7711
+ // 等升级到amis 3.4+,blur事件换成change事件执行onChangeScript,就可以不用在onSearchScript中执行onChangeScript了
7712
+ const onSearchScript = `
7713
+ ${onChangeScript}
7714
+
7715
+ // 下面的脚本只为解决点击搜索表单取消按钮,再重新在其中输入过滤条件但是不点击搜索按钮或回车按键触发搜索,此时在快速搜索框输入过滤条件按回车按键会把搜索表单中的过滤条件清空的问题
7716
+ // const scope = event.context.scoped;
7717
+ // 如果点击过顶部搜索栏表单的取消按钮,会把此处event.data.__super.__super.__super中的搜索表单项的所有字段设置为null
7718
+ // 点击取消按钮后继续在表单项中输入过滤条件且最后没有点击回车按键或点击表单项搜索按钮的话,在快速搜索中点击回车按钮提交搜索会所顶部搜索表单中的字段值清空
7719
+ let filterForm = SteedosUI.getClosestAmisComponentByType(scope, "form");
7720
+ setTimeout(function(){
7721
+ filterForm.setValues(event.data.__changedFilterFormValues);
7722
+ }, 500);
7723
+ `;
7724
+
7661
7725
  return {
7662
7726
  "type": "tooltip-wrapper",
7663
7727
  "id": "steedos_crud_toolbar_quick_search",
@@ -7676,28 +7740,24 @@ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLooku
7676
7740
  "placeholder": "搜索此列表",
7677
7741
  "value": crudKeywords,
7678
7742
  "clearable": true,
7679
- "clearAndSubmit": true,
7743
+ // "clearAndSubmit": true,//因为清除并不会触发失去焦点事件,只有禁用,但是它会触发change事件,所以等升级到amis 3.4+后可以重新放开
7680
7744
  "searchImediately": false,
7681
7745
  "onEvent": {
7682
- "change": {
7746
+ "search": {
7683
7747
  "actions": [
7684
7748
  {
7685
7749
  "actionType": "custom",
7686
- "script": `
7687
- doAction(
7688
- {
7689
- "componentId": 'service_${crudId}',
7690
- "actionType": "setValue",
7691
- "args": {
7692
- "value": {
7693
- "__serachBoxValues": event.data
7694
- }
7695
- }
7696
- }
7697
- )
7698
- `
7750
+ "script": onSearchScript
7699
7751
  }
7700
7752
  ]
7753
+ },
7754
+ "blur": { //这里把change事件换成blur是因为amis 3.2change事件中setData会卡,升级到3.4+后就可以换回change事件
7755
+ "actions": [
7756
+ {
7757
+ "actionType": "custom",
7758
+ "script": onChangeScript
7759
+ },
7760
+ ]
7701
7761
  }
7702
7762
  }
7703
7763
  }
@@ -7706,7 +7766,7 @@ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLooku
7706
7766
  }
7707
7767
 
7708
7768
  function getObjectHeaderToolbar(mainObject, fields, formFactor, {
7709
- showDisplayAs = false, hiddenCount = false, headerToolbarItems, crudId,
7769
+ showDisplayAs = false, hiddenCount = false, headerToolbarItems,
7710
7770
  filterVisible = true, isLookup = false, keywordsSearchBoxName } = {}){
7711
7771
  // console.log(`getObjectHeaderToolbar====>`, filterVisible)
7712
7772
  // console.log(`getObjectHeaderToolbar`, mainObject)
@@ -7810,7 +7870,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
7810
7870
  };
7811
7871
  }
7812
7872
  let toolbarDisplayAsButton = getDisplayAsButton(mainObject?.name);
7813
- let toolbarDQuickSearchBox = getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLookup, keywordsSearchBoxName, crudId });
7873
+ let toolbarDQuickSearchBox = getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLookup, keywordsSearchBoxName });
7814
7874
 
7815
7875
  // toolbars返回的数组元素不可以是空对象{},比如hiddenCount ? {} : {"type": "tpl",...},因为空对象最终还是会生成一个空的.antd-Crud-toolbar-item dom
7816
7876
  // 当出现空的.antd-Crud-toolbar-item dom时会影响toolbar元素的maring-right css样式计算,如果有动态需要应该加到动态数组变量toolbars中
@@ -7958,6 +8018,20 @@ async function getObjectFilter(objectSchema, fields, options) {
7958
8018
  let crudService = crud && SteedosUI.getClosestAmisComponentByType(crud.context, "service");
7959
8019
  crudService && crudService.setData({isFieldsFilterEmpty});
7960
8020
  `;
8021
+ let onChangeScript = `
8022
+ const scope = event.context.scoped;
8023
+ // let filterFormValues = event.data;
8024
+ let filterForm = SteedosUI.getClosestAmisComponentByType(scope, "form");
8025
+ let filterFormService = SteedosUI.getClosestAmisComponentByType(filterForm.context, "service");
8026
+ // 使用event.data的话,并不能拿到本地存储中的过滤条件,所以需要从filterFormService中取。
8027
+ let filterFormValues = filterFormService.getData();
8028
+ let crud = SteedosUI.getClosestAmisComponentByType(scope, "crud");
8029
+ const changedFilterFormValues = _.pickBy(filterFormValues, function(n,k){return /^__searchable__/.test(k);});;
8030
+ // let crudService = crud && SteedosUI.getClosestAmisComponentByType(crud.context, "service");
8031
+ // crudService && crudService.setData({__changedFilterFormValues: changedFilterFormValues});
8032
+ // 这里不用crudService而用crud是因为lookup字段弹出的列表中的crudService中的变量无法传入crud的发送适配器中
8033
+ crud && crud.setData({__changedFilterFormValues: changedFilterFormValues});
8034
+ `;
7961
8035
  return {
7962
8036
  "title": "",
7963
8037
  "submitText": "",
@@ -7981,19 +8055,7 @@ async function getObjectFilter(objectSchema, fields, options) {
7981
8055
  "actions": [
7982
8056
  {
7983
8057
  "actionType": "custom",
7984
- "script": `
7985
- doAction(
7986
- {
7987
- "componentId": 'service_${options.crudId}',
7988
- "actionType": "setValue",
7989
- "args": {
7990
- "value": {
7991
- "__filterFormValues": event.data
7992
- }
7993
- }
7994
- }
7995
- )
7996
- `
8058
+ "script": onChangeScript
7997
8059
  }
7998
8060
  ]
7999
8061
  }
@@ -8068,7 +8130,6 @@ async function getObjectCRUD(objectSchema, fields, options){
8068
8130
  const bulkActions = getBulkActions(objectSchema);
8069
8131
  const defaults = options.defaults;
8070
8132
  const listSchema = (defaults && defaults.listSchema) || {};
8071
- const id = `listview_${objectSchema.name}`;
8072
8133
 
8073
8134
  const bodyProps = {
8074
8135
  // toolbar: getToolbar(),
@@ -8078,7 +8139,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8078
8139
  ...options,
8079
8140
  disableStatistics: options.queryCount === false
8080
8141
  }),
8081
- filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, Object.assign({}, options, {crudId: id})),
8142
+ filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, options),
8082
8143
  };
8083
8144
  if(options.formFactor !== 'SMALL' || ["split"].indexOf(options.displayAs) == -1){
8084
8145
  if(listSchema.mode !== "cards"){
@@ -8107,8 +8168,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8107
8168
  showDisplayAs,
8108
8169
  hiddenCount: options.queryCount === false,
8109
8170
  headerToolbarItems: options.headerToolbarItems,
8110
- filterVisible: options.filterVisible,
8111
- crudId: id
8171
+ filterVisible: options.filterVisible
8112
8172
  });
8113
8173
 
8114
8174
  options.amisData = createObject(options.amisData, {
@@ -8121,6 +8181,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8121
8181
 
8122
8182
 
8123
8183
  let body = null;
8184
+ const id = `listview_${objectSchema.name}`;
8124
8185
  if(options.formFactor === 'SMALL' && false){
8125
8186
  delete bodyProps.bulkActions;
8126
8187
  delete bodyProps.headerToolbar;
@@ -8199,7 +8260,12 @@ async function getObjectCRUD(objectSchema, fields, options){
8199
8260
  hiddenOn: options.tableHiddenOn,
8200
8261
  autoFillHeight,
8201
8262
  className: `flex-auto ${crudClassName || ""}`,
8202
- bodyClassName: "bg-white",
8263
+ // 这里不可以用动态className,因为它会把样式类加到.antd-Crud和.antd-Table.antd-Crud-body这两层div中,而子表列表中crudClassName中有hidden样式类会造成所有子表都不显示的bug
8264
+ // className: {
8265
+ // [`flex-auto ${crudClassName || ""}`]: "true",
8266
+ // "is-steedos-crud-data-empty": "${!items || COUNT(items) == 0}"
8267
+ // },
8268
+ bodyClassName: "bg-white",//上面className写成动态的class变量对象的话,bodyClassName不会生效,会被上面的className值覆盖
8203
8269
  crudClassName: crudClassName,
8204
8270
  quickSaveApi: {
8205
8271
  url: `\${context.rootUrl}/graphql`,
@@ -10090,8 +10156,6 @@ async function lookupToAmisTreeSelect(field, readonly, ctx) {
10090
10156
  return amisSchema;
10091
10157
  }
10092
10158
 
10093
- const keywordsSearchBoxName = `__keywords_lookup`;
10094
-
10095
10159
  const getReferenceToFieldSchema = (field, refObjectConfig)=>{
10096
10160
  let referenceTo = field.reference_to;
10097
10161
  if(!referenceTo){
@@ -10350,8 +10414,18 @@ async function lookupToAmisPicker(field, readonly, ctx){
10350
10414
 
10351
10415
  source.data.$term = "$term";
10352
10416
  source.data.$self = "$$";
10353
-
10417
+
10418
+ // field.name可能是带点的名称,比如审批王中子表字段'instances.instances_submitter',如果不替换掉点,会造成审批王表单中新建子表行时报错
10419
+ let keywordsSearchBoxName = `__keywords_lookup__${field.name.replace(/\./g, "_")}__to__${refObjectConfig.name}`;
10420
+
10354
10421
  source.requestAdaptor = `
10422
+ let __changedFilterFormValues = api.data.$self.__changedFilterFormValues || {};
10423
+ let __changedSearchBoxValues = api.data.$self.__changedSearchBoxValues || {};
10424
+ // 把表单搜索和快速搜索中的change事件中记录的过滤条件也拼到$self中,是为解决触发搜索请求时,两边输入的过滤条件都带上,即:
10425
+ // 有时在搜索表单中输入过滤条件事,忘记点击回车键或搜索按钮,而是进一步修改快速搜索框中的关键字点击其中回车键触发搜索
10426
+ // 这种情况下,触发的搜索请求中没有带上搜索表单中输入的过滤条件。
10427
+ // 反过来先在快速搜索框中输入过滤条件却不点击其中回车键触发搜索,而是到搜索表单中触发搜索请求也是一样的。
10428
+ Object.assign(api.data.$self, __changedSearchBoxValues, __changedFilterFormValues);
10355
10429
  const selfData = JSON.parse(JSON.stringify(api.data.$self));
10356
10430
  var filters = [];
10357
10431
  var pageSize = api.data.pageSize || 10;
@@ -10486,6 +10560,14 @@ async function lookupToAmisPicker(field, readonly, ctx){
10486
10560
  }
10487
10561
  });
10488
10562
  payload.data.rows = treeRecords;
10563
+ try{
10564
+ setTimeout(() => {
10565
+ $('.amis-dialog-widget.antd-Modal .antd-Table-content .antd-Table-table thead .antd-Table-expandBtn')[0]?.click();
10566
+ }, 600);
10567
+ }
10568
+ catch(ex){
10569
+ console.error("tree数据格式展开异常:", ex);
10570
+ }
10489
10571
  }
10490
10572
  return payload;
10491
10573
  `;
@@ -10658,6 +10740,7 @@ async function lookupToAmisPicker(field, readonly, ctx){
10658
10740
 
10659
10741
  async function lookupToAmisSelect(field, readonly, ctx){
10660
10742
  let referenceTo = await getReferenceTo(field);
10743
+ const isMobile = window.innerWidth <= 768;
10661
10744
  const valueFieldKey = referenceTo && referenceTo.valueField?.name || '_id' ;
10662
10745
  // const labelFieldKey = referenceTo && referenceTo.labelField?.name || 'name';
10663
10746
 
@@ -10838,7 +10921,11 @@ async function lookupToAmisSelect(field, readonly, ctx){
10838
10921
  </span>
10839
10922
  <span class='pl-1.5'>\${label}</span>
10840
10923
  </span>`;
10841
- data.menuTpl = "${icon ? `"+select_menuTpl+"` : label}";
10924
+ const menuTpl = "${icon ? `"+select_menuTpl+"` : label}";
10925
+ // TODO: 待amis修复了此bug, 就可以撤销添加menuTpl的判断。
10926
+ if(!(isMobile && field.multiple)){
10927
+ data.menuTpl = menuTpl;
10928
+ }
10842
10929
  if(field.multiple){
10843
10930
  data.multiple = true;
10844
10931
  data.extractValue = true;
@@ -11346,6 +11433,8 @@ function getSelectFieldOptions(field){
11346
11433
  }
11347
11434
 
11348
11435
  async function convertSFieldToAmisField(field, readonly, ctx) {
11436
+ // console.log('convertSFieldToAmisField====>', field, readonly, ctx)
11437
+ const isMobile = window.innerWidth <= 768;
11349
11438
  // 创建人和修改人、创建时间和修改时间不显示
11350
11439
  if(_$1.includes(OMIT_FIELDS, field.name) && ctx.showSystemFields != true){
11351
11440
  return;
@@ -11408,7 +11497,11 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
11408
11497
  </span>
11409
11498
  <span class='pl-1.5'>\${label}</span>
11410
11499
  </span>`;
11411
- convertData.menuTpl = "${icon ? `"+select_menuTpl+"` : label}";
11500
+ const menuTpl = "${icon ? `"+select_menuTpl+"` : label}";
11501
+ // TODO: 待amis修复了此bug, 就可以撤销添加menuTpl的判断。
11502
+ if(!(isMobile && field.multiple)){
11503
+ convertData.menuTpl = menuTpl;
11504
+ }
11412
11505
  if(field.multiple){
11413
11506
  convertData.multiple = true;
11414
11507
  convertData.extractValue = true;
@@ -11995,9 +12088,7 @@ async function getFieldSearchable(perField, permissionFields, ctx){
11995
12088
 
11996
12089
  const amisField = await convertSFieldToAmisField(_field, false, Object.assign({}, ctx, {fieldNamePrefix: fieldNamePrefix, required: false, showSystemFields: true, inFilterForm: true}));
11997
12090
  if(amisField){
11998
- return Object.assign({}, amisField,{
11999
- submitOnChange: false
12000
- });
12091
+ return amisField;
12001
12092
  }
12002
12093
  }
12003
12094
  }
@@ -12271,7 +12362,7 @@ async function getFormBody(permissionFields, formFields, ctx){
12271
12362
  * @Author: 殷亮辉 yinlianghui@hotoa.com
12272
12363
  * @Date: 2023-11-15 09:50:22
12273
12364
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
12274
- * @LastEditTime: 2023-11-29 17:48:02
12365
+ * @LastEditTime: 2023-12-04 17:36:50
12275
12366
  */
12276
12367
 
12277
12368
  /**
@@ -12390,12 +12481,16 @@ async function getForm(props, mode = "edit") {
12390
12481
  }
12391
12482
  else if (mode === "new") {
12392
12483
  let onNewItemSubmitScript = `
12393
- event.data["${props.name}"].push(JSON.parse(JSON.stringify(event.data)));
12484
+ let fieldValue = _.cloneDeep(event.data["${props.name}"]);
12485
+ if(!fieldValue){
12486
+ fieldValue = [];
12487
+ }
12488
+ fieldValue.push(JSON.parse(JSON.stringify(event.data)));
12394
12489
  doAction({
12395
12490
  "componentId": "${props.id}",
12396
12491
  "actionType": "setValue",
12397
12492
  "args": {
12398
- "value": event.data["${props.name}"]
12493
+ "value": fieldValue
12399
12494
  }
12400
12495
  });
12401
12496
  `;
@@ -12597,11 +12692,20 @@ const getAmisInputTableSchema = async (props, readonly) => {
12597
12692
  ],
12598
12693
  "className": props.className
12599
12694
  };
12695
+ let footerToolbar = clone(props.footerToolbar || []); //这里不clone的话,会造成死循环,应该是因为props属性变更会让组件重新渲染
12600
12696
  if (props.addable) {
12601
- let buttonNewSchema = getButtonNew(props);
12602
- schema.body.push(buttonNewSchema);
12697
+ let buttonNewSchema = await getButtonNew(props);
12698
+ footerToolbar.unshift(buttonNewSchema);
12699
+ }
12700
+ if (footerToolbar.length) {
12701
+ schema.body.push({
12702
+ "type": "wrapper",
12703
+ "size": "none",
12704
+ "body": footerToolbar
12705
+ });
12603
12706
  }
12604
12707
  if (props.amis) {
12708
+ delete props.amis.id;
12605
12709
  Object.assign(schema.body[0], props.amis);
12606
12710
  }
12607
12711
  return schema;