@steedos-widgets/amis-lib 1.3.4-beta.9 → 1.3.5

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.cjs.js CHANGED
@@ -470,8 +470,8 @@ function getLookupListView(refObjectConfig) {
470
470
  /*
471
471
  * @Author: baozhoutao@steedos.com
472
472
  * @Date: 2022-05-23 09:53:08
473
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
474
- * @LastEditTime: 2023-09-19 14:38:39
473
+ * @LastEditors: liaodaxue
474
+ * @LastEditTime: 2023-10-11 17:32:17
475
475
  * @Description:
476
476
  */
477
477
 
@@ -532,7 +532,7 @@ function getSelectMap(selectOptions){
532
532
  if(optionColor){
533
533
  const background = optionColor.charAt(0) === '#' ? optionColor : '#'+optionColor;
534
534
  const color = getContrastColor(background);
535
- const optionColorStyle = 'background:'+background+';color:'+color;
535
+ const optionColorStyle = 'background:'+background+';color:'+color+';line-height:1.5rem';
536
536
  map[optionValue] = `<span class="rounded-xl px-2 py-1" style='${optionColorStyle}'>${option.label}</span>`;
537
537
  }else {
538
538
  map[optionValue] = option.label;
@@ -989,17 +989,17 @@ async function getFindQuery(object, recordId, fields, options){
989
989
  }
990
990
 
991
991
  const countQuery = options.count === false ? "" : `,count:${object.name}__count(filters:{__filters})`;
992
- const moreQuerie = options.moreQueries?.length ? ("," + options.moreQueries.map(function(item){
993
- // 把最外层的{}去除
994
- return item.replace(/^{/,"").replace(/}$/,"");
995
- }).join(",")) : "";
992
+ // const moreQuerie = options.moreQueries?.length ? ("," + options.moreQueries.map(function(item){
993
+ // // 把最外层的{}去除
994
+ // return item.replace(/^{/,"").replace(/}$/,"");
995
+ // }).join(",")) : "";
996
996
 
997
997
  return {
998
998
  orderBy: "${orderBy}",
999
999
  orderDir: "${orderDir}",
1000
1000
  pageNo: "${page}",
1001
1001
  pageSize: "${perPage}",
1002
- query: `{${alias}:${object.name}${queryOptions}{${await getFieldsTemplate(fields, options.expand)}${treeFields}${cfsFields}}${countQuery}${moreQuerie}}`
1002
+ query: `{${alias}:${object.name}${queryOptions}{${await getFieldsTemplate(fields, options.expand)}${treeFields}${cfsFields}}${countQuery}}`
1003
1003
  }
1004
1004
  }
1005
1005
 
@@ -1791,6 +1791,13 @@ async function getSelectUserSchema(field, readonly, ctx) {
1791
1791
  return amisSchema;
1792
1792
  }
1793
1793
 
1794
+ /*
1795
+ * @Author: 殷亮辉 yinlianghui@hotoa.com
1796
+ * @Date: 2023-03-22 09:31:21
1797
+ * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
1798
+ * @LastEditTime: 2023-11-05 16:31:38
1799
+ */
1800
+
1794
1801
  const globalTag = '__G_L_O_B_A_L__';
1795
1802
 
1796
1803
  const getParentPath = function (path) {
@@ -1830,7 +1837,43 @@ const isExpression = function (func) {
1830
1837
  return false;
1831
1838
  };
1832
1839
 
1840
+ const getMoment$1 = () => {
1841
+ if (window.amisRequire) {
1842
+ return window.amisRequire("moment");
1843
+ } else if (window.moment) {
1844
+ return window.moment;
1845
+ }
1846
+ };
1847
+
1848
+ const getGlobalNowData = () => {
1849
+ let now = new Date();
1850
+ let moment = getMoment$1();
1851
+ let today = moment().utc();
1852
+ today.set("hours", 0);
1853
+ today.set("minutes", 0);
1854
+ today.set("seconds", 0);
1855
+ today.set("milliseconds", 0);
1856
+ today = today.toDate();
1857
+ let timeNow = moment();
1858
+ timeNow.set("year", 1970);
1859
+ timeNow.set("month", 0);
1860
+ timeNow.set("date", 1);
1861
+ timeNow.set("hours", timeNow.hours() + timeNow.utcOffset() / 60);
1862
+ timeNow.set("seconds", 0);
1863
+ timeNow.set("milliseconds", 0);
1864
+ timeNow = timeNow.toDate();
1865
+ return {
1866
+ now,
1867
+ today,
1868
+ timeNow
1869
+ };
1870
+ };
1871
+
1833
1872
  const parseSingleExpression = function (func, formData, dataPath, global, userSession = {}) {
1873
+ if (global) {
1874
+ Object.assign(global, getGlobalNowData());
1875
+ }
1876
+
1834
1877
  var error, funcBody, parent, parentPath, str;
1835
1878
 
1836
1879
  if (formData === void 0) {
@@ -2597,20 +2640,29 @@ function getButtonVisibleOn$1(button){
2597
2640
  // return 'false';
2598
2641
  // }
2599
2642
  if(visible.trim().startsWith('function')){
2600
- return `${visible}.apply({
2643
+ visible = `${visible}.apply({
2601
2644
  object: uiSchema
2602
- }, [objectName, typeof _id === 'undefined' ? null: _id, typeof record === 'undefined' ? (typeof recordPermissions === 'undefined' ? {} : recordPermissions) : record.recordPermissions, data])`
2645
+ }, [objectName, typeof _id === 'undefined' ? null: _id, typeof record === 'undefined' ? (typeof recordPermissions === 'undefined' ? {} : recordPermissions) : record.recordPermissions, data])`;
2603
2646
  }
2604
- return visible;
2605
2647
  }
2606
2648
 
2607
2649
  if(button.type === 'amis_button'){
2608
- const amisSchema = button.amis_schema;
2650
+ let amisSchema = button.amis_schema;
2651
+ if(___namespace.isString(amisSchema)){
2652
+ amisSchema = JSON.parse(amisSchema);
2653
+ }
2609
2654
  if(amisSchema && amisSchema.body && amisSchema.body.length > 0){
2610
2655
  const btn1 = amisSchema.body[0];
2611
- return btn1.visibleOn
2656
+ if(___namespace.hasIn(btn1, 'visibleOn')){
2657
+ /* 当含有“更多”按钮或者“下拉”箭头按钮时,单个按钮的visibleOn需要合并到 “更多”按钮或者“下拉”箭头按钮的 visibleOn 中,用||隔开。
2658
+ visibleOn的格式需要保持一致; 不能是 js 和 ${xxx} 混合的表达式;
2659
+ visibleOn的值需要是js格式,因为默认的编辑、删除等系统按钮的visibleOn的格式就是js格式(function(){});
2660
+ */
2661
+ return btn1.visibleOn
2662
+ }
2612
2663
  }
2613
2664
  }
2665
+ return visible;
2614
2666
  }
2615
2667
 
2616
2668
  const getButtonVisible = (button, ctx) => {
@@ -2936,9 +2988,30 @@ const getObjectDetailHeaderButtons = (objectSchema, recordId)=>{
2936
2988
  const getObjectDetailButtonsSchemas = (objectSchema, recordId, ctx)=>{
2937
2989
  const { buttons, moreButtons, moreButtonsVisibleOn } = getObjectDetailHeaderButtons(objectSchema, recordId);
2938
2990
  if(ctx.formFactor === 'SMALL'){
2991
+ const dropdownButtons = [
2992
+ ...___namespace.map(buttons, (button) => {
2993
+ button.className += ' w-full';
2994
+ return button;
2995
+ }),
2996
+ ...___namespace.map(moreButtons, (button) => {
2997
+ button.className += ' w-full';
2998
+ return button;
2999
+ })
3000
+ ];
3001
+
3002
+ let phoneMoreButtonsVisibleOn = '';
3003
+ ___namespace.forEach(dropdownButtons, (button, index) => {
3004
+ if(index === 0){
3005
+ phoneMoreButtonsVisibleOn = button.visibleOn;
3006
+ }else {
3007
+ phoneMoreButtonsVisibleOn = phoneMoreButtonsVisibleOn + ' || ' + button.visibleOn;
3008
+ }
3009
+ });
3010
+
2939
3011
  return {
2940
3012
  "type": "button",
2941
3013
  "icon": "fa fa-angle-down",
3014
+ "visibleOn": phoneMoreButtonsVisibleOn,
2942
3015
  "onEvent": {
2943
3016
  "click": {
2944
3017
  "actions": [
@@ -2954,16 +3027,7 @@ const getObjectDetailButtonsSchemas = (objectSchema, recordId, ctx)=>{
2954
3027
  "id": "u:fd837823be5b",
2955
3028
  "vertical": true,
2956
3029
  "tiled": true,
2957
- "buttons": [
2958
- ...___namespace.map(buttons, (button)=>{
2959
- button.className += ' w-full';
2960
- return button;
2961
- }),
2962
- ...___namespace.map(moreButtons, (button)=>{
2963
- button.className += ' w-full';
2964
- return button;
2965
- })
2966
- ],
3030
+ "buttons": dropdownButtons,
2967
3031
  "btnLevel": "enhance",
2968
3032
  "className": "w-full",
2969
3033
  "btnClassName": "w-full",
@@ -3334,7 +3398,8 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
3334
3398
  if(isLookup){
3335
3399
  searchableFieldsStoreKey += "/lookup/" + objectName;
3336
3400
  }
3337
- let defaultSearchableFields = sessionStorage.getItem(searchableFieldsStoreKey);
3401
+ searchableFieldsStoreKey = searchableFieldsStoreKey + "/" + (data.context && data.context.userId);
3402
+ let defaultSearchableFields = localStorage.getItem(searchableFieldsStoreKey);
3338
3403
  if(defaultSearchableFields){
3339
3404
  defaultSearchableFields = defaultSearchableFields.split(",");
3340
3405
  }
@@ -3403,7 +3468,8 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
3403
3468
  if(isLookup){
3404
3469
  searchableFieldsStoreKey += "/lookup/" + objectName;
3405
3470
  }
3406
- sessionStorage.setItem(searchableFieldsStoreKey, value);
3471
+ searchableFieldsStoreKey = searchableFieldsStoreKey + "/" + (data.context && data.context.userId);
3472
+ localStorage.setItem(searchableFieldsStoreKey, value);
3407
3473
 
3408
3474
  // ===START===:当变更可搜索字段时,如果被移除的可搜索字段在本地存储中已经存入过滤条件中则应该清除本地存储中相关字段的过滤条件。
3409
3475
  const searchableFields = data.fields;
@@ -4369,7 +4435,8 @@ const getCopyListviewButtonSchema = ()=>{
4369
4435
  "&": "${list_view}",
4370
4436
  "name":"",
4371
4437
  "label": i18next__default["default"].t('frontend_listview_control_clone_defaultData_label_start') + " ${list_view.label} " + i18next__default["default"].t('frontend_listview_control_clone_defaultData_label_end'),
4372
- "shared":false
4438
+ "shared":false,
4439
+ "object_name": "${targetObjectName}",
4373
4440
  },
4374
4441
  "fieldsExtend": fieldsExtend$3(),
4375
4442
  "fields": fields(),
@@ -5157,7 +5224,7 @@ let resizeWindow = function(){
5157
5224
  //触发amis crud 高度重算
5158
5225
  setTimeout(()=>{
5159
5226
  window.dispatchEvent(new Event("resize"))
5160
- }, 500);
5227
+ }, 1000);
5161
5228
  }
5162
5229
  resizeWindow();
5163
5230
  // 手机端在显示搜索栏时隐藏crud上的刷新按钮,因为点击后crud高度显示有问题
@@ -5394,6 +5461,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
5394
5461
  }
5395
5462
 
5396
5463
  function getObjectFooterToolbar(mainObject, formFactor, options) {
5464
+ // crud card模式与table模式两种情况下showPageInput默认值不一样,所以需要显式设置为false
5397
5465
  if (formFactor === 'SMALL') {
5398
5466
  // return [
5399
5467
  // "load-more",
@@ -5403,14 +5471,17 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5403
5471
  "switch-per-page",
5404
5472
  {
5405
5473
  "type": "pagination",
5406
- "maxButtons": 5
5474
+ "maxButtons": 5,
5475
+ "showPageInput": false
5407
5476
  }
5408
5477
  ]
5409
5478
  }else {
5410
5479
  return [
5480
+ // "statistics",
5411
5481
  {
5412
5482
  "type": "pagination",
5413
- "maxButtons": 5
5483
+ "maxButtons": 5,
5484
+ "showPageInput": false
5414
5485
  }
5415
5486
  ]
5416
5487
  }
@@ -5419,16 +5490,31 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5419
5490
  if(options && options.isRelated){
5420
5491
  return [
5421
5492
  "statistics",
5422
- "pagination"
5493
+ {
5494
+ "type": "pagination",
5495
+ "maxButtons": 10,
5496
+ "showPageInput": false
5497
+ }
5423
5498
  ]
5424
5499
 
5425
5500
  }
5426
5501
  else {
5427
- return [
5428
- "switch-per-page",
5502
+ const no_pagination = mainObject.paging && (mainObject.paging.enabled === false);
5503
+ const is_lookup = options.isLookup;
5504
+ const commonConfig = [
5429
5505
  "statistics",
5430
- "pagination"
5431
- ]
5506
+ {
5507
+ "type": "pagination",
5508
+ "maxButtons": 10,
5509
+ "showPageInput": false
5510
+ }
5511
+ ];
5512
+
5513
+ if (no_pagination && is_lookup) {
5514
+ return commonConfig;
5515
+ } else {
5516
+ return ["switch-per-page", ...commonConfig];
5517
+ }
5432
5518
  }
5433
5519
  }
5434
5520
  }
@@ -6065,13 +6151,15 @@ async function lookupToAmisPicker(field, readonly, ctx){
6065
6151
  pickerSchema.headerToolbar = getObjectHeaderToolbar(refObjectConfig, fieldsArr, ctx.formFactor, { headerToolbarItems, isLookup: true, keywordsSearchBoxName });
6066
6152
  const isAllowCreate = refObjectConfig.permissions.allowCreate;
6067
6153
  const isCreate = ___namespace.isBoolean(field.create) ? field.create : true;
6068
- if (isAllowCreate && isCreate) {
6154
+ // lookup字段配置过滤条件就强制不显示新建按钮
6155
+ let isHasFilters = (field.filters || field._filtersFunction) ? true : false;
6156
+ if (isAllowCreate && isCreate && !isHasFilters) {
6069
6157
  const new_button = await getSchema$5(refObjectConfig, { appId: ctx.appId, objectName: refObjectConfig.name, formFactor: ctx.formFactor });
6070
6158
  new_button.align = "right";
6071
6159
  // 保持快速搜索放在最左侧,新建按钮往里插,而不是push到最后
6072
6160
  pickerSchema.headerToolbar.splice(pickerSchema.headerToolbar.length - 1, 0, new_button);
6073
6161
  }
6074
- pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar();
6162
+ pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar(refObjectConfig,ctx.formFactor,{isLookup: true});
6075
6163
  if (ctx.filterVisible !== false) {
6076
6164
  pickerSchema.filter = await getObjectFilter(refObjectConfig, fields, {
6077
6165
  ...ctx,
@@ -6199,10 +6287,10 @@ async function lookupToAmisSelect(field, readonly, ctx){
6199
6287
  // const labelFieldKey = referenceTo && referenceTo.labelField?.name || 'name';
6200
6288
 
6201
6289
  let apiInfo;
6202
-
6290
+ let defaultValueOptionsQueryData;
6203
6291
  if(referenceTo){
6204
6292
  // 字段值单独走一个请求合并到source的同一个GraphQL接口中
6205
- const defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6293
+ defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6206
6294
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6207
6295
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6208
6296
  ], {
@@ -6215,7 +6303,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6215
6303
  }, null, [
6216
6304
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6217
6305
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6218
- ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`, moreQueries: [defaultValueOptionsQueryData.query]});
6306
+ ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`});
6219
6307
 
6220
6308
  apiInfo.adaptor = `
6221
6309
  const data = payload.data;
@@ -6309,11 +6397,16 @@ async function lookupToAmisSelect(field, readonly, ctx){
6309
6397
  var optionsFiltersOp = "${field.multiple ? "in" : "="}";
6310
6398
  var optionsFilters = [["${valueFieldKey}", optionsFiltersOp, []]];
6311
6399
  if (defaultValue && !api.data.$term) {
6400
+ const defaultValueOptionsQueryData = ${JSON.stringify(defaultValueOptionsQueryData)};
6401
+ const defaultValueOptionsQuery = defaultValueOptionsQueryData?.query?.replace(/^{/,"").replace(/}$/,"");
6312
6402
  // 字段值单独请求,没值的时候在请求中返回空
6313
6403
  optionsFilters = [["${valueFieldKey}", optionsFiltersOp, defaultValue]];
6314
6404
  if(filters.length > 0){
6315
6405
  optionsFilters = [filters, optionsFilters];
6316
6406
  }
6407
+ if(defaultValueOptionsQuery){
6408
+ api.data.query = "{"+api.data.query.replace(/^{/,"").replace(/}$/,"")+","+defaultValueOptionsQuery+"}";
6409
+ }
6317
6410
  }
6318
6411
  api.data.query = api.data.query.replace(/{__options_filters}/g, JSON.stringify(optionsFilters));
6319
6412
  return api;
@@ -6355,7 +6448,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6355
6448
  disabledOn: `${readonly} || ( (this._master && (this._master.relatedKey ==='${field.name}')) || ((this.relatedKey ==='${field.name}') && (${field.multiple} != true)) )`,
6356
6449
  // labelField: labelField,
6357
6450
  // valueField: valueField,
6358
- source: apiInfo,
6451
+ // source: apiInfo,
6359
6452
  autoComplete: apiInfo,
6360
6453
  searchable: true,
6361
6454
  };
@@ -6434,10 +6527,10 @@ async function lookupToAmis(field, readonly, ctx){
6434
6527
 
6435
6528
  const refObject = await getUISchema(referenceTo.objectName);
6436
6529
 
6437
- // 此处不参考 steedos 的 enable_enhanced_lookup 规则. 如果默认是开启弹出选择,用户选择过程操作太繁琐, 所以默认是关闭弹出选择.
6438
- // 由于amis picker 目前不支持联动, 配置了depend_on时, 使用使用select ,以支持联动
6439
- // TODO: 确认 amis picker 支持联动时, 清理field.depend_on判断
6440
- if(refObject.enable_enhanced_lookup == true && ___namespace.isEmpty(field.depend_on)){
6530
+ // 优先取字段中配置的enable_enhanced_lookup,字段上没配置时,才从对象上取enable_enhanced_lookup属性
6531
+ let enableEnhancedLookup = ___namespace.isBoolean(field.enable_enhanced_lookup) ? field.enable_enhanced_lookup : refObject.enable_enhanced_lookup;
6532
+ // 默认使用下拉框模式显示lookup选项,只能配置了enable_enhanced_lookup才使用弹出增强模式
6533
+ if(enableEnhancedLookup == true){
6441
6534
  return await lookupToAmisPicker(field, readonly, ctx);
6442
6535
  }else if(refObject.enable_tree) {
6443
6536
  return await lookupToAmisTreeSelect(field, readonly, Object.assign({}, ctx, {
@@ -6754,8 +6847,8 @@ function getAmisStaticFieldType(type, readonly, options){
6754
6847
  /*
6755
6848
  * @Author: baozhoutao@steedos.com
6756
6849
  * @Date: 2022-10-28 14:15:09
6757
- * @LastEditors: baozhoutao@steedos.com
6758
- * @LastEditTime: 2022-11-02 18:06:16
6850
+ * @LastEditors: liaodaxue
6851
+ * @LastEditTime: 2023-10-30 17:51:54
6759
6852
  * @Description:
6760
6853
  */
6761
6854
 
@@ -6806,11 +6899,26 @@ const getAmisFileEditSchema = (steedosField)=>{
6806
6899
  useChunk: false, // 关闭分块上传
6807
6900
  receiver: {
6808
6901
  method: "post",
6902
+ dataType: "form-data",
6809
6903
  url: `\${context.rootUrl}/s3/${tableName}`,
6810
- data: {
6811
- $: "$$",
6812
- context: `\${context}`,
6813
- },
6904
+ requestAdaptor: `
6905
+ const { _master, global,context } = api.body;
6906
+ // const { recordId, objectName } = _master;
6907
+ const { spaceId, userId, user } = global;
6908
+ /*
6909
+ record_id: recordId,
6910
+ parent: recordId,
6911
+ object_name: objectName,
6912
+ owner_name: user.name,
6913
+ space: spaceId,
6914
+ owner: userId
6915
+ */
6916
+ // 参考platform 2.2版本,附件字段保存时cfs.files.filerecord、cfs.images.filerecord表中的metadata下只保存space、owner两个属性值。
6917
+ api.data.append('space', spaceId);
6918
+ api.data.append('owner', userId);
6919
+
6920
+ return api;
6921
+ `,
6814
6922
  adaptor: `
6815
6923
  const { context } = api.body;
6816
6924
  var rootUrl = context.rootUrl + "/api/files/${tableName}/";
@@ -6996,8 +7104,6 @@ function getSelectFieldOptions(field){
6996
7104
  }
6997
7105
 
6998
7106
  async function convertSFieldToAmisField(field, readonly, ctx) {
6999
- // console.log('convertSFieldToAmisField====>', field, readonly, ctx)
7000
- const isMobile = window.innerWidth <= 768;
7001
7107
  // 创建人和修改人、创建时间和修改时间不显示
7002
7108
  if(___namespace.includes(OMIT_FIELDS, field.name) && ctx.showSystemFields != true){
7003
7109
  return;
@@ -7086,26 +7192,33 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7086
7192
  };
7087
7193
  break;
7088
7194
  case 'date':
7089
- convertData = isMobile && !readonly ? {
7090
- type: "native-date",
7091
- pipeIn: (value, data) => {
7092
- if (value) {
7093
- value = moment(value).utc().format('YYYY-MM-DD');
7094
- return value;
7095
- } else {
7096
- return "";
7097
- }
7098
-
7099
- },
7100
- pipeOut: (value, oldValue, data) => {
7101
- if (value) {
7102
- value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7103
- return value;
7104
- } else {
7105
- return "";
7106
- }
7107
- }
7108
- } : {
7195
+ // convertData = isMobile && !readonly ? {
7196
+ // type: "native-date",
7197
+ // pipeIn: (value, data) => {
7198
+ // if (value) {
7199
+ // value = moment(value).utc().format('YYYY-MM-DD');
7200
+ // return value;
7201
+ // } else {
7202
+ // return "";
7203
+ // }
7204
+
7205
+ // },
7206
+ // pipeOut: (value, oldValue, data) => {
7207
+ // if (value) {
7208
+ // value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7209
+ // return value;
7210
+ // } else {
7211
+ // return "";
7212
+ // }
7213
+ // }
7214
+ // } : {
7215
+ // type: getAmisStaticFieldType('date', readonly),
7216
+ // inputFormat: "YYYY-MM-DD",
7217
+ // format:'YYYY-MM-DDT00:00:00.000[Z]',
7218
+ // tpl: readonly ? Tpl.getDateTpl(field) : null,
7219
+ // // utc: true
7220
+ // }
7221
+ convertData = {
7109
7222
  type: getAmisStaticFieldType('date', readonly),
7110
7223
  inputFormat: "YYYY-MM-DD",
7111
7224
  format:'YYYY-MM-DDT00:00:00.000[Z]',
@@ -7124,43 +7237,51 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7124
7237
  };
7125
7238
  break;
7126
7239
  case 'datetime':
7127
- convertData = isMobile && !readonly ? {
7128
- type: "combo",
7129
- pipeIn: (value, data) => {
7130
- let revalue = {};
7131
- if (value && value != "Invalid date") {
7132
- value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7133
- revalue[field.name + "-native-date"] = value.split(' ')[0];
7134
- revalue[field.name + "-native-time"] = value.split(' ')[1];
7135
- } else {
7136
- revalue[field.name + "-native-date"] = "";
7137
- revalue[field.name + "-native-time"] = "";
7138
- }
7139
- return revalue;
7140
- },
7141
- pipeOut: (value, oldValue, data) => {
7142
- let revalue = "";
7143
- if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7144
- revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7145
- revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7146
- }
7147
- return revalue;
7148
- },
7149
- items: [
7150
- {
7151
- type: "native-date",
7152
- name: field.name + "-native-date",
7153
- className: "steedos-native-date",
7154
- value: ""
7155
- },
7156
- {
7157
- type: "native-time",
7158
- name: field.name + "-native-time",
7159
- className: "steedos-native-time",
7160
- value: ""
7161
- }
7162
- ]
7163
- } : {
7240
+ // convertData = isMobile && !readonly ? {
7241
+ // type: "combo",
7242
+ // pipeIn: (value, data) => {
7243
+ // let revalue = {};
7244
+ // if (value && value != "Invalid date") {
7245
+ // value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7246
+ // revalue[field.name + "-native-date"] = value.split(' ')[0];
7247
+ // revalue[field.name + "-native-time"] = value.split(' ')[1];
7248
+ // } else {
7249
+ // revalue[field.name + "-native-date"] = "";
7250
+ // revalue[field.name + "-native-time"] = "";
7251
+ // }
7252
+ // return revalue;
7253
+ // },
7254
+ // pipeOut: (value, oldValue, data) => {
7255
+ // let revalue = "";
7256
+ // if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7257
+ // revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7258
+ // revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7259
+ // }
7260
+ // return revalue;
7261
+ // },
7262
+ // items: [
7263
+ // {
7264
+ // type: "native-date",
7265
+ // name: field.name + "-native-date",
7266
+ // className: "steedos-native-date",
7267
+ // value: ""
7268
+ // },
7269
+ // {
7270
+ // type: "native-time",
7271
+ // name: field.name + "-native-time",
7272
+ // className: "steedos-native-time",
7273
+ // value: ""
7274
+ // }
7275
+ // ]
7276
+ // } : {
7277
+ // type: getAmisStaticFieldType('datetime', readonly),
7278
+ // inputFormat: 'YYYY-MM-DD HH:mm',
7279
+ // format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
7280
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7281
+ // utc: true,
7282
+ // }
7283
+
7284
+ convertData = {
7164
7285
  type: getAmisStaticFieldType('datetime', readonly),
7165
7286
  inputFormat: 'YYYY-MM-DD HH:mm',
7166
7287
  format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
@@ -7180,26 +7301,34 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7180
7301
  };
7181
7302
  break;
7182
7303
  case 'time':
7183
- convertData = isMobile && !readonly ? {
7184
- type: "native-time",
7185
- pipeIn: (value, data) => {
7186
- if (value) {
7187
- value = moment(value).utc().format('HH:mm');
7188
- return value;
7189
- } else {
7190
- return "";
7191
- }
7192
-
7193
- },
7194
- pipeOut: (value, oldValue, data) => {
7195
- if (value) {
7196
- value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7197
- return value;
7198
- } else {
7199
- return "";
7200
- }
7201
- }
7202
- } : {
7304
+ // convertData = isMobile && !readonly ? {
7305
+ // type: "native-time",
7306
+ // pipeIn: (value, data) => {
7307
+ // if (value) {
7308
+ // value = moment(value).utc().format('HH:mm');
7309
+ // return value;
7310
+ // } else {
7311
+ // return "";
7312
+ // }
7313
+
7314
+ // },
7315
+ // pipeOut: (value, oldValue, data) => {
7316
+ // if (value) {
7317
+ // value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7318
+ // return value;
7319
+ // } else {
7320
+ // return "";
7321
+ // }
7322
+ // }
7323
+ // } : {
7324
+ // type: getAmisStaticFieldType('time', readonly),
7325
+ // inputFormat: 'HH:mm',
7326
+ // timeFormat:'HH:mm',
7327
+ // format:'1970-01-01THH:mm:00.000[Z]',
7328
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7329
+ // // utc: true
7330
+ // }
7331
+ convertData = {
7203
7332
  type: getAmisStaticFieldType('time', readonly),
7204
7333
  inputFormat: 'HH:mm',
7205
7334
  timeFormat:'HH:mm',
@@ -7249,7 +7378,20 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7249
7378
  type: getAmisStaticFieldType('number', readonly),
7250
7379
  min: field.min,
7251
7380
  max: field.max,
7252
- precision: field.scale
7381
+ precision: field.scale,
7382
+ suffix: "%",
7383
+ pipeIn: (value, data) => {
7384
+ if(value){
7385
+ return value*100;
7386
+ }
7387
+ return value;
7388
+ },
7389
+ pipeOut: (value, oldValue, data) => {
7390
+ if(value){
7391
+ return value/100;
7392
+ }
7393
+ return value;
7394
+ },
7253
7395
  };
7254
7396
  }
7255
7397
  break;
@@ -7661,8 +7803,41 @@ var config = {
7661
7803
  };
7662
7804
 
7663
7805
  async function getQuickEditSchema(field, options){
7664
- const quickEditId = options.objectName + "_" + field.name + "QuickEdit";//定义快速编辑的表单id,用于setvalue传值
7806
+ //判断在amis3.2以上环境下,放开批量编辑
7807
+ const isAmisVersionforBatchEdit = amisRequire('amis').version[0] >= 3 && amisRequire('amis').version[2] >= 2;
7808
+ const quickEditId = options.objectName + "_" + field.name + "_quickEdit";//定义快速编辑的表单id,用于setvalue传值
7665
7809
  var quickEditSchema = { body: [], id: quickEditId };
7810
+ //select,avatar,image,file等组件无法行记录字段赋值,暂不支持批量编辑;
7811
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
7812
+ const submitEvent = {
7813
+ submit: {
7814
+ actions: [
7815
+ {
7816
+ actionType: "custom",
7817
+ script: `
7818
+ let items = _.cloneDeep(event.data.items);
7819
+ let selectedItems = _.cloneDeep(event.data.selectedItems);
7820
+ if(event.data.isBatchEdit){
7821
+ selectedItems.forEach(function(selectedItem){
7822
+ selectedItem._display.${field.name} = event.data._display.${field.name};
7823
+ doAction({actionType: 'setValue', "args": {"value": selectedItem._display},componentId: "_display_" + selectedItem._index});
7824
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + selectedItem._index});
7825
+ })
7826
+ }else{
7827
+ doAction({actionType: 'setValue', "args": {"value": event.data._display},componentId: "_display_" + event.data._index});
7828
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + event.data._index});
7829
+ }
7830
+ `
7831
+ },
7832
+ {
7833
+ "actionType": "closeDialog"
7834
+ }
7835
+ ]
7836
+ }
7837
+ };
7838
+ quickEditSchema.onEvent = submitEvent;
7839
+ }
7840
+
7666
7841
  if (field.disabled) {
7667
7842
  quickEditSchema = false;
7668
7843
  } else {
@@ -7679,7 +7854,7 @@ async function getQuickEditSchema(field, options){
7679
7854
  {
7680
7855
  "actionType": "custom",
7681
7856
  "script": `
7682
- var _display = event.data._display;
7857
+ var _display = _.cloneDeep(event.data._display);
7683
7858
  ${displayField}
7684
7859
  doAction({actionType: 'setValue', "args": {"value": {_display}},componentId: "${quickEditId}"});
7685
7860
  `
@@ -7701,7 +7876,7 @@ async function getQuickEditSchema(field, options){
7701
7876
  第二种是增加选项时,按照value的值,找到对应选项,并按照_display的规则为其赋值
7702
7877
  */
7703
7878
  TempDisplayField = `
7704
- const preData = event.data.__super.${field.name};
7879
+ const preData = _.cloneDeep(event.data.__super.${field.name});
7705
7880
  if(preData && event.data.${field.name}.length < preData.length){
7706
7881
  let deletedIndex;
7707
7882
  preData.forEach(function(item,index){
@@ -7745,7 +7920,7 @@ async function getQuickEditSchema(field, options){
7745
7920
  break;
7746
7921
  case "percent":
7747
7922
  TempDisplayField = `
7748
- _display["${field.name}"] = (event.data.value * 100).toFixed(${field.scale}) + '%';
7923
+ _display["${field.name}"] = event.data.value.toFixed(${field.scale}) + '%';
7749
7924
  `;
7750
7925
  quickEditSchema.body[0].onEvent["change"] = quickEditOnEvent(TempDisplayField);
7751
7926
  break;
@@ -7896,6 +8071,131 @@ async function getQuickEditSchema(field, options){
7896
8071
  }
7897
8072
 
7898
8073
  });
8074
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
8075
+ quickEditSchema.body.push({
8076
+ "name": "isBatchEdit",
8077
+ "type": "checkbox",
8078
+ "option": [
8079
+ {
8080
+ "type": "tpl",
8081
+ "tpl": "更新${COUNT(selectedItems)}个选定记录"
8082
+ },
8083
+ {
8084
+ "type": "spinner",
8085
+ "showOn": "${batchPermissionLoading}",
8086
+ "size": "sm",
8087
+ "className": "mr-4"
8088
+ }
8089
+ ],
8090
+ "visibleOn": "${ARRAYSOME(selectedItems, item => item._id === _id) && COUNT(selectedItems)>1 && quickedit_record_permissions.allowEdit && quickedit_record_permissions_loading == false}",
8091
+ "disabledOn": "${batchPermissionLoading}",
8092
+ "onEvent":{
8093
+ "change":{
8094
+ "actions":[
8095
+ {
8096
+ "actionType": "setValue",
8097
+ "componentId": quickEditId,
8098
+ "args": {
8099
+ "value":{
8100
+ "batchPermissionLoading": true
8101
+ }
8102
+ },
8103
+ "expression":"${event.data.value}"
8104
+ },
8105
+ {
8106
+ "actionType": "ajax",
8107
+ "args": {
8108
+ "api": {
8109
+ "url": "${context.rootUrl}/graphql",
8110
+ "method": "post",
8111
+ "headers": {
8112
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
8113
+ },
8114
+ "data": {
8115
+ "query": "{rows:${objectName}(filters:[\"_id\",\"in\",${selectedItems | pick:_id | split | json}]){_id,_permissions{allowEdit}}}"
8116
+ },
8117
+ "adaptor": `
8118
+ const noPermission = [];
8119
+ payload.data.rows.forEach(function (row) {
8120
+ if(!row._permissions.allowEdit){
8121
+ noPermission.push(row._id);
8122
+ }
8123
+ })
8124
+ payload.data.noPermission = noPermission;
8125
+ return payload;
8126
+ `
8127
+ }
8128
+ },
8129
+ "expression":"${event.data.value}"
8130
+ },
8131
+ {
8132
+ "actionType": "setValue",
8133
+ "componentId": quickEditId,
8134
+ "args": {
8135
+ "value":{
8136
+ "batchPermissionLoading": false
8137
+ }
8138
+ },
8139
+ "expression":"${event.data.value}"
8140
+ },
8141
+ {
8142
+ "actionType": "dialog",
8143
+ "dialog":{
8144
+ "title": "记录权限",
8145
+ "showCloseButton": false,
8146
+ "body":[
8147
+ {
8148
+ "type": "tpl",
8149
+ "tpl": "当前选中记录中,有${COUNT(noPermission)}条记录无编辑权限,是否需要批量编辑其他记录?"
8150
+ }
8151
+ ],
8152
+ "onEvent":{
8153
+ "confirm":{
8154
+ "actions":[
8155
+ {
8156
+ "actionType": "custom",
8157
+ "script": `
8158
+ const noPermission = event.data.noPermission;
8159
+ const crudComponent = event.context.scoped.getComponentById("${options.crudId}");
8160
+ const selectedItems = crudComponent && crudComponent.props.store.selectedItems.concat();
8161
+ noPermission.forEach(function (item) {
8162
+ crudComponent && crudComponent.unSelectItem(_.find(selectedItems,{_id:item}));
8163
+ })
8164
+ `
8165
+ },
8166
+ {
8167
+ "actionType": "setValue",
8168
+ "componentId": quickEditId,
8169
+ "args": {
8170
+ "value":{
8171
+ "isBatchEdit": true
8172
+ }
8173
+ },
8174
+ }
8175
+ ]
8176
+ },
8177
+ "cancel":{
8178
+ "actions":[
8179
+ {
8180
+ "actionType": "setValue",
8181
+ "componentId": quickEditId,
8182
+ "args": {
8183
+ "value":{
8184
+ "isBatchEdit": false
8185
+ }
8186
+ },
8187
+ }
8188
+ ]
8189
+ }
8190
+ }
8191
+ },
8192
+ "expression":"${COUNT(event.data.noPermission)>0}"
8193
+ }
8194
+ ]
8195
+ }
8196
+ }
8197
+ });
8198
+ }
7899
8199
  } else {
7900
8200
  quickEditSchema = false;
7901
8201
  }
@@ -7930,6 +8230,8 @@ async function getTableColumns(fields, options){
7930
8230
  const columns = [];
7931
8231
  if(!options.isLookup){
7932
8232
  columns.push({name: '_index',type: 'text', width: 32, placeholder: ""});
8233
+ //将_display放入crud的columns中,可以通过setvalue修改行内数据域的_display,而不影响上层items的_display,用于批量编辑
8234
+ columns.push({name: '_display',type: 'static', width: 32, placeholder: "",id: "_display_${_index}", className: "hidden"});
7933
8235
  }
7934
8236
  const allowEdit = options.permissions?.allowEdit && !options.isLookup && options.enable_inline_edit != false;
7935
8237
 
@@ -7961,7 +8263,7 @@ async function getTableColumns(fields, options){
7961
8263
  {
7962
8264
  "args": {
7963
8265
  "api": {
7964
- "url": "${context.rootUrl}/api/files/files/${versions[0]}?download=true",
8266
+ "url": "${(versions[0] && versions[0].url) ? versions[0].url+'?download=true' : context.rootUrl+'/api/files/files/'+versions[0]+'?download=true'}",
7965
8267
  "method": "get",
7966
8268
  "headers": {
7967
8269
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
@@ -8008,7 +8310,7 @@ async function getTableColumns(fields, options){
8008
8310
  else if(field.type === 'select'){
8009
8311
  const map = getSelectMap(field.options);
8010
8312
  columnItem = Object.assign({}, {
8011
- type: "mapping",
8313
+ type: "static-mapping",
8012
8314
  name: field.name,
8013
8315
  label: field.label,
8014
8316
  map: map,
@@ -8023,7 +8325,7 @@ async function getTableColumns(fields, options){
8023
8325
  const tpl = await getFieldTpl(field, options);
8024
8326
  let type = 'text';
8025
8327
  if(tpl){
8026
- type = 'tpl';
8328
+ type = 'static';
8027
8329
  }else if(field.type === 'html'){
8028
8330
  type = 'markdown';
8029
8331
  }else if(field.type === 'url'){
@@ -8064,6 +8366,7 @@ async function getTableColumns(fields, options){
8064
8366
  columnItem.quickEdit = quickEditSchema;
8065
8367
  columnItem.quickEditEnabledOn = "${is_system !== true}";
8066
8368
  }
8369
+ columnItem.id = `${options.objectName}_${field.name}_\${_index}`;
8067
8370
  columns.push(columnItem);
8068
8371
  }
8069
8372
  }
@@ -8342,7 +8645,7 @@ async function getTableOperation(ctx){
8342
8645
  }
8343
8646
  return {
8344
8647
  type: 'operation',
8345
- label: i18next__default["default"].t('frontend_operation'),
8648
+ label: "",
8346
8649
  fixed: 'right',
8347
8650
  labelClassName: 'text-center',
8348
8651
  className: 'text-center steedos-listview-operation w-10',
@@ -8376,23 +8679,87 @@ async function getTableOperation(ctx){
8376
8679
  }
8377
8680
  }
8378
8681
 
8682
+ async function getDefaultCrudCard(columns, options) {
8683
+ let labelFieldName = options?.labelFieldName || "name";
8684
+ let titleColumn, bodyColumns = [];
8685
+ columns.forEach(function (item) {
8686
+ delete item.quickEdit;
8687
+ delete item.width;
8688
+ if (item.name === labelFieldName) {
8689
+ titleColumn = item;
8690
+ }
8691
+ else {
8692
+ if (item.name !== "_index") {
8693
+ bodyColumns.push(item);
8694
+ }
8695
+ }
8696
+ });
8697
+ let card = {
8698
+ "header": {
8699
+ "title": titleColumn.tpl
8700
+ },
8701
+ body: bodyColumns,
8702
+ // useCardLabel: false,
8703
+ toolbar: []
8704
+ };
8705
+ let hideToolbarOperation = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8706
+ if(!hideToolbarOperation){
8707
+ let toolbarOperation = await getTableOperation(options);
8708
+ if (toolbarOperation) {
8709
+ toolbarOperation.className += " inline-block w-auto";
8710
+ }
8711
+ card.toolbar.push(toolbarOperation);
8712
+ }
8713
+ return card;
8714
+ }
8715
+
8379
8716
  async function getTableSchema$1(fields, options){
8380
8717
  if(!options){
8381
8718
  options = {};
8382
8719
  }
8383
8720
  let { isLookup, hiddenColumnOperation } = options;
8721
+ const defaults = options.defaults;
8722
+ const listSchema = (defaults && defaults.listSchema) || {};
8723
+
8384
8724
  let columns = [];
8385
8725
  let useMobileColumns = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8386
8726
  if(isLookup){
8387
8727
  // 在lookup手机端列表模式调式好之前不使用getMobileTableColumns
8388
8728
  useMobileColumns = false;
8389
8729
  }
8730
+ if(listSchema.mode && listSchema.mode !== "table"){
8731
+ // 如果指定的mode,则不走我们内置的手机端列表效果,使用steedos组件内部开发的默认card/list效果,或者由用户自己实现card/list模式的crud列表
8732
+ useMobileColumns = false;
8733
+ }
8390
8734
  if(useMobileColumns){
8391
8735
  columns = await getMobileTableColumns(fields, options);
8392
8736
  }
8393
8737
  else {
8394
8738
  columns = await getTableColumns(fields, options);
8395
8739
 
8740
+ if(listSchema.mode === "cards"){
8741
+ let card = listSchema.card;
8742
+ if(!card){
8743
+ card = await getDefaultCrudCard(columns, options);
8744
+ }
8745
+ return {
8746
+ mode: "cards",
8747
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8748
+ name: "thelist",
8749
+ headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8750
+ className: "",
8751
+ draggable: false,
8752
+ defaultParams: getDefaultParams(options),
8753
+ card: card,
8754
+ syncLocation: false,
8755
+ keepItemSelectionOnPageChange: true,
8756
+ checkOnItemClick: isLookup ? true : false,
8757
+ labelTpl: `\${${options.labelFieldName}}`,
8758
+ autoFillHeight: false, // 自动高度效果不理想,先关闭
8759
+ columnsTogglable: false
8760
+ }
8761
+ }
8762
+
8396
8763
  if(!isLookup && !hiddenColumnOperation){
8397
8764
  columns.push(await getTableOperation(options));
8398
8765
  }
@@ -8400,6 +8767,7 @@ async function getTableSchema$1(fields, options){
8400
8767
 
8401
8768
  return {
8402
8769
  mode: "table",
8770
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8403
8771
  name: "thelist",
8404
8772
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8405
8773
  className: "",
@@ -8870,18 +9238,30 @@ function getReadonlyFormAdaptor(object, fields, options){
8870
9238
  payload.status = 2;
8871
9239
  payload.msg = payload.errors[0].message;
8872
9240
  }
9241
+ ${options && options.initApiAdaptor || ''}
8873
9242
  return payload;
8874
9243
  `
8875
9244
  }
8876
9245
 
8877
9246
  async function getReadonlyFormInitApi(object, recordId, fields, options){
9247
+ let findOneOptions;
9248
+ if (!recordId && options && options.isEditor) {
9249
+ // 设计器中只读表单返回第一条记录
9250
+ findOneOptions = {
9251
+ filters: [],
9252
+ queryOptions: "top: 1"
9253
+ };
9254
+ }
8878
9255
  return {
8879
9256
  method: "post",
8880
9257
  url: getApi$2() + '&objectName=${objectName}' + "&recordId=${recordId}",
8881
9258
  cache: API_CACHE,
8882
- // requestAdaptor: "console.log('getReadonlyFormInitApi requestAdaptor', api);return api;",
9259
+ requestAdaptor: `
9260
+ ${options && options.initApiRequestAdaptor || ''}
9261
+ return api;
9262
+ `,
8883
9263
  adaptor: getReadonlyFormAdaptor(object, fields, options),
8884
- data: await getFindOneQuery$1(object, recordId, fields, options),
9264
+ data: await getFindOneQuery$1(object, recordId, fields, findOneOptions),
8885
9265
  headers: {
8886
9266
  Authorization: "Bearer ${context.tenantId},${context.authToken}"
8887
9267
  }
@@ -9022,7 +9402,7 @@ async function getEditFormInitApi(object, recordId, fields, options){
9022
9402
  ${getScriptForRewriteValueForFileFields(fields)}
9023
9403
 
9024
9404
  _.each(dataKeys, function(key){
9025
- if(fieldKeys.indexOf(key)<0){
9405
+ if(fieldKeys.indexOf(key)<0 && key !== "_display"){
9026
9406
  delete data[key];
9027
9407
  }
9028
9408
  })
@@ -9197,6 +9577,8 @@ async function getCalendarApi(mainObject, fields, options) {
9197
9577
 
9198
9578
  if(api.data.$self.additionalFilters){
9199
9579
  filters.push(api.data.$self.additionalFilters)
9580
+ }else if(api.data.$self.event.data.additionalFilters){
9581
+ filters.push(api.data.$self.event.data.additionalFilters)
9200
9582
  }
9201
9583
 
9202
9584
  var pageSize = api.data.pageSize || 10;
@@ -9522,6 +9904,7 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9522
9904
  businessHours.endTime = `${calendarOptions.endDayHour}:00`;
9523
9905
  }
9524
9906
 
9907
+ // api.trackExpression="\\\${additionalFilters}";
9525
9908
  const onEvent = {
9526
9909
  "getEvents": {
9527
9910
  "weight": 0,
@@ -9533,6 +9916,22 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9533
9916
  "actionType": "custom",
9534
9917
  "script": onGetEventsScript
9535
9918
  }
9919
+ // {
9920
+ // "actionType": "ajax",
9921
+ // "outputVar": "responseResult",
9922
+ // "args": {
9923
+ // "options": {
9924
+ // },
9925
+ // "api": api
9926
+ // // {
9927
+ // // "url": "111",
9928
+ // // "method": "post",
9929
+ // // "data": {
9930
+ // // "calendarOptions": JSON.stringify(calendarOptions);
9931
+ // // }
9932
+ // // }
9933
+ // }
9934
+ // }
9536
9935
  ]
9537
9936
  },
9538
9937
  "select": {
@@ -9856,7 +10255,7 @@ function deleteVariable(data, key) {
9856
10255
  * @Author: baozhoutao@steedos.com
9857
10256
  * @Date: 2022-05-26 16:02:08
9858
10257
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
9859
- * @LastEditTime: 2023-09-15 15:36:17
10258
+ * @LastEditTime: 2023-10-12 18:25:05
9860
10259
  * @Description:
9861
10260
  */
9862
10261
 
@@ -9876,8 +10275,9 @@ const getFieldSchemaArray = (formFields, ctx) => {
9876
10275
  }
9877
10276
 
9878
10277
  let forceHidden = false;
9879
- if(!recordId && field.readonly){
10278
+ if(!recordId && field.readonly && !ctx.isEditor){
9880
10279
  // 新建记录时,只读字段先隐藏,后续支持显示后,即任务:https://github.com/steedos/steedos-platform/issues/3164 完成后再放开
10280
+ // 表单只读时所有字段都是readonly,设计器中如果forceHidden会造成整个表单在只读的时候显示为空白了,所以要排除掉
9881
10281
  forceHidden = true;
9882
10282
  }
9883
10283
 
@@ -10119,6 +10519,9 @@ async function getObjectCRUD(objectSchema, fields, options){
10119
10519
  const nonpaged = objectSchema.paging && objectSchema.paging.enabled === false;
10120
10520
  const isTreeObject = objectSchema.enable_tree;
10121
10521
  const bulkActions = getBulkActions(objectSchema);
10522
+ const defaults = options.defaults;
10523
+ const listSchema = (defaults && defaults.listSchema) || {};
10524
+
10122
10525
  const bodyProps = {
10123
10526
  // toolbar: getToolbar(),
10124
10527
  // headerToolbar: getObjectHeaderToolbar(objectSchema, options.formFactor, {showDisplayAs}),
@@ -10130,9 +10533,12 @@ async function getObjectCRUD(objectSchema, fields, options){
10130
10533
  filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, options),
10131
10534
  };
10132
10535
  if(options.formFactor !== 'SMALL' || ["split"].indexOf(options.displayAs) == -1){
10133
- Object.assign(bodyProps, {
10134
- bulkActions: options.bulkActions != false ? bulkActions : false
10135
- });
10536
+ if(listSchema.mode !== "cards"){
10537
+ // card模式时默认不显示勾选框
10538
+ Object.assign(bodyProps, {
10539
+ bulkActions: options.bulkActions != false ? bulkActions : false
10540
+ });
10541
+ }
10136
10542
  }
10137
10543
  // yml里配置的 不分页和enable_tree:true 优先级最高,组件中输入的top次之。
10138
10544
  options.queryCount = true;
@@ -10191,17 +10597,19 @@ async function getObjectCRUD(objectSchema, fields, options){
10191
10597
  }
10192
10598
  let tableOptions = Object.assign({
10193
10599
  idFieldName: objectSchema.idFieldName, labelFieldName: labelFieldName,
10194
- permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit
10600
+ permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit,
10601
+ crudId: listSchema.id || id
10195
10602
  }, options);
10196
10603
  tableOptions.amisData = createObject(options.amisData || {}, {});
10197
10604
  const table = await getTableSchema$1(fields, tableOptions);
10198
- delete table.mode;
10605
+ // delete table.mode;
10199
10606
  //image与avatar需要在提交修改时特别处理
10200
10607
  const imageNames = ___default["default"].compact(___default["default"].map(___default["default"].filter(fields, (field) => ["image","avatar"].includes(field.type)), 'name'));
10201
10608
  const quickSaveApiRequestAdaptor = `
10202
10609
  var graphqlOrder = "";
10203
10610
  var imageNames = ${JSON.stringify(imageNames)};
10204
- api.data.rowsDiff.forEach(function (item, index) {
10611
+ const rowsDiff = _.cloneDeep(api.data.rowsDiff);
10612
+ rowsDiff.forEach(function (item, index) {
10205
10613
  for(key in item){
10206
10614
  if(_.includes(imageNames, key)){
10207
10615
  if(typeof item[key] == "string"){
@@ -10215,6 +10623,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10215
10623
  }
10216
10624
  }
10217
10625
  }
10626
+ item = _.omit(item, '_display');
10218
10627
  const itemOrder = 'update' + index + ':' + api.data.objectName + '__update(id:"' + item._id + '", doc:' + JSON.stringify(JSON.stringify(_.omit(item, '_id'))) + ') {_id}';
10219
10628
  graphqlOrder += itemOrder;
10220
10629
  })
@@ -10265,12 +10674,14 @@ async function getObjectCRUD(objectSchema, fields, options){
10265
10674
 
10266
10675
  }
10267
10676
 
10268
- const defaults = options.defaults;
10269
-
10270
- const listSchema = (defaults && defaults.listSchema) || {};
10271
10677
  body = defaultsDeep({}, listSchema, body);
10272
10678
  body = await getCrudSchemaWithDataFilter(body, { crudDataFilter, onCrudDataFilter, amisData, env });
10273
10679
 
10680
+ let crudModeClassName = "";
10681
+ if(body.mode){
10682
+ crudModeClassName = `steedos-crud-mode-${body.mode}`;
10683
+ }
10684
+
10274
10685
  if (defaults) {
10275
10686
  const headerSchema = defaults.headerSchema;
10276
10687
  const footerSchema = defaults.footerSchema;
@@ -10299,7 +10710,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10299
10710
  // TODO: data应该只留loaded,其他属性都改为从上层传递下来
10300
10711
  return {
10301
10712
  type: 'service',
10302
- className: '',
10713
+ className: crudModeClassName,
10303
10714
  //目前crud的service层id不认用户自定义id,只支持默认规则id,许多地方的格式都写死了service_listview_${objectname}
10304
10715
  id: `service_${id}`,
10305
10716
  name: `page`,
@@ -10353,8 +10764,29 @@ const getFormFields = (objectSchema, formProps)=>{
10353
10764
  return lodash.sortBy(___default["default"].values(fields), "sort_no");
10354
10765
  };
10355
10766
 
10767
+ async function getFormSchemaWithDataFilter(form, options = {}){
10768
+ const { formDataFilter, amisData, env } = options;
10769
+ let onFormDataFilter = options.onFormDataFilter;
10770
+ if (!onFormDataFilter && typeof formDataFilter === 'string') {
10771
+ onFormDataFilter = new Function(
10772
+ 'form',
10773
+ 'env',
10774
+ 'data',
10775
+ formDataFilter
10776
+ );
10777
+ }
10778
+
10779
+ try {
10780
+ onFormDataFilter && (form = await onFormDataFilter(form, env, amisData) || form);
10781
+ } catch (e) {
10782
+ console.warn(e);
10783
+ }
10784
+ return form;
10785
+ }
10786
+
10356
10787
  async function getObjectForm(objectSchema, ctx){
10357
- const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults } = ctx;
10788
+ const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults, submitSuccActions = [],
10789
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10358
10790
  const fields = ___default["default"].values(objectSchema.fields);
10359
10791
  const formFields = getFormFields(objectSchema, ctx);
10360
10792
  const formSchema = defaults && defaults.formSchema || {};
@@ -10371,7 +10803,8 @@ async function getObjectForm(objectSchema, ctx){
10371
10803
  name: `page_edit_${recordId}`,
10372
10804
  api: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
10373
10805
  data:{
10374
- editFormInited: false
10806
+ editFormInited: false,
10807
+ ...amisData
10375
10808
  },
10376
10809
  // data: {global: getGlobalData('edit'), recordId: recordId, objectName: objectSchema.name, context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10377
10810
  initApi: null,
@@ -10424,9 +10857,10 @@ async function getObjectForm(objectSchema, ctx){
10424
10857
  },
10425
10858
  "expression": `\${_master.objectName != '${objectSchema.name}' && _master.objectName}`
10426
10859
  },
10860
+ ...submitSuccActions,
10427
10861
  // {
10428
10862
  // "actionType": "custom",
10429
- // "script": "debugger;"
10863
+ // "script": `setTimeout(function(){doAction({'actionType': 'setValue','componentId': '${formSchema.id}','args': {'value': {'sort_no': 879}}})}, 300)`
10430
10864
  // },
10431
10865
  // {
10432
10866
  // "args": {},
@@ -10437,20 +10871,22 @@ async function getObjectForm(objectSchema, ctx){
10437
10871
  }
10438
10872
  })]
10439
10873
  };
10874
+ amisSchema.body[0] = await getFormSchemaWithDataFilter(amisSchema.body[0], { formDataFilter, onFormDataFilter, amisData, env });
10440
10875
  return amisSchema;
10441
10876
  }
10442
10877
 
10443
10878
  async function getObjectDetail(objectSchema, recordId, ctx){
10444
- const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, formInitProps } = ctx;
10879
+ const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign,
10880
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10445
10881
  const fields = ___default["default"].values(objectSchema.fields);
10446
10882
  const formFields = getFormFields(objectSchema, ctx);
10447
10883
  const serviceId = `service_detail_page`;
10448
- return {
10884
+ const amisSchema = {
10449
10885
  type: 'service',
10450
10886
  name: `page_readonly_${recordId}`,
10451
10887
  id: serviceId,
10452
10888
  data: {global: getGlobalData('read'), context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10453
- api: await getReadonlyFormInitApi(objectSchema, recordId, fields, formInitProps),
10889
+ api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
10454
10890
  body: [
10455
10891
  {
10456
10892
  "type": "wrapper", //form 的 hiddenOn 会导致 form onEvent 异常, 使用wrapper包裹一次form,并在wrapper上控制显隐
@@ -10469,7 +10905,11 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10469
10905
  "formData": "$$"
10470
10906
  },
10471
10907
  wrapWithPanel: false,
10472
- body: await getFormBody(_$1.map(fields, (field)=>{field.readonly = true; return field;}), _$1.map(formFields, (field)=>{field.readonly = true; return field;}), Object.assign({}, ctx, {showSystemFields: true,fieldGroups: objectSchema.field_groups})),
10908
+ body: await getFormBody(
10909
+ _$1.map(fields, (field) => { field.readonly = true; return field; }),
10910
+ _$1.map(formFields, (field) => { field.readonly = true; return field; }),
10911
+ Object.assign({}, ctx, { showSystemFields: true, fieldGroups: objectSchema.field_groups })
10912
+ ),
10473
10913
  className: 'steedos-amis-form bg-white',
10474
10914
  actions: [], // 不显示表单默认的提交按钮
10475
10915
  onEvent: {
@@ -10523,7 +10963,10 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10523
10963
  ]
10524
10964
  }
10525
10965
  }
10526
- }
10966
+ };
10967
+
10968
+ amisSchema.body[0].body = await getFormSchemaWithDataFilter(amisSchema.body[0].body, { formDataFilter, onFormDataFilter, amisData, env });
10969
+ return amisSchema;
10527
10970
  }
10528
10971
 
10529
10972
  /*
@@ -10603,7 +11046,7 @@ const getRecordPermissions = async (objectName, recordId)=>{
10603
11046
  * @Author: baozhoutao@steedos.com
10604
11047
  * @Date: 2022-07-05 15:55:39
10605
11048
  * @LastEditors: liaodaxue
10606
- * @LastEditTime: 2023-09-25 17:18:08
11049
+ * @LastEditTime: 2023-10-23 15:55:46
10607
11050
  * @Description:
10608
11051
  */
10609
11052
 
@@ -10894,11 +11337,15 @@ async function getRelatedListSchema(
10894
11337
  ctx
10895
11338
  ) {
10896
11339
  const uiSchema = await getUISchema(objectName);
11340
+ if(!uiSchema){
11341
+ return {}
11342
+ }
11343
+ const listViewNames = _$1.map(uiSchema.list_views, 'name');
10897
11344
  const listView = _$1.find(
10898
11345
  uiSchema.list_views,
10899
11346
  (listView, name) => {
10900
- // 传入listViewName空值则取第一个
10901
- if(!listViewName){
11347
+ // 传入listViewName空值 或者 不存在 则取第一个
11348
+ if(!listViewName || listViewNames.indexOf(listViewName)<0){
10902
11349
  listViewName = name;
10903
11350
  }
10904
11351
  return name === listViewName || listView._id === listViewName;
@@ -10978,8 +11425,8 @@ async function getRelatedListSchema(
10978
11425
  /*
10979
11426
  * @Author: baozhoutao@steedos.com
10980
11427
  * @Date: 2022-07-05 15:55:39
10981
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
10982
- * @LastEditTime: 2023-09-21 17:35:06
11428
+ * @LastEditors: liaodaxue
11429
+ * @LastEditTime: 2023-10-20 11:38:25
10983
11430
  * @Description:
10984
11431
  */
10985
11432
 
@@ -11308,8 +11755,8 @@ async function getListSchema(
11308
11755
  "filtersFunction": listview_filters,
11309
11756
  "sort": sort,
11310
11757
  "ctx": ctx,
11311
- "requestAdaptor": listView.requestAdaptor,
11312
- "adaptor": listView.adaptor,
11758
+ "requestAdaptor": listView.requestAdaptor || ctx.requestAdaptor,
11759
+ "adaptor": listView.adaptor || ctx.adaptor,
11313
11760
  "headerToolbarItems": ctx.headerToolbarItems,
11314
11761
  "filterVisible": ctx.filterVisible,
11315
11762
  "rowClassNameExpr": ctx.rowClassNameExpr,
@@ -13954,10 +14401,18 @@ const getOpinionFieldStepsName = (field, top_keywords) => {
13954
14401
  * @Author: baozhoutao@steedos.com
13955
14402
  * @Date: 2022-09-09 17:47:37
13956
14403
  * @LastEditors: baozhoutao@steedos.com
13957
- * @LastEditTime: 2023-03-18 15:32:34
14404
+ * @LastEditTime: 2023-10-10 13:57:02
13958
14405
  * @Description:
13959
14406
  */
13960
14407
 
14408
+ const getMoment = ()=>{
14409
+ if(window.amisRequire){
14410
+ return window.amisRequire("moment");
14411
+ }else if(window.moment){
14412
+ return window.moment;
14413
+ }
14414
+ };
14415
+
13961
14416
  const getTrace = ({ instance, traceId }) => {
13962
14417
  return _$1.find(instance.traces, (trace) => {
13963
14418
  return trace._id === traceId;
@@ -14177,6 +14632,8 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14177
14632
  method: "get",
14178
14633
  });
14179
14634
 
14635
+ const moment = getMoment();
14636
+
14180
14637
  return {
14181
14638
  box: box,
14182
14639
  _id: instanceId,
@@ -14187,7 +14644,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14187
14644
  applicant_name: instance.applicant_name,
14188
14645
  submitter: instance.submitter,
14189
14646
  submit_date: instance.submit_date
14190
- ? amisRequire("moment")(instance.submit_date).format("YYYY-MM-DD")
14647
+ ? (moment && moment(instance.submit_date).format("YYYY-MM-DD"))
14191
14648
  : "",
14192
14649
  state: instance.state,
14193
14650
  approveValues: values,
@@ -14227,8 +14684,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14227
14684
  finishDate = approve.is_read ? "已读" : "未处理";
14228
14685
  judge = null;
14229
14686
  } else {
14230
- finishDate =
14231
- amisRequire("moment")(finishDate).format("YYYY-MM-DD HH:mm");
14687
+ finishDate = moment && moment(finishDate).format("YYYY-MM-DD HH:mm");
14232
14688
  }
14233
14689
 
14234
14690
  switch (judge) {
@@ -14318,6 +14774,7 @@ exports.getFileSrc = getFileSrc;
14318
14774
  exports.getFlowFormSchema = getFlowFormSchema;
14319
14775
  exports.getFormPageInitSchema = getFormPageInitSchema;
14320
14776
  exports.getFormSchema = getFormSchema;
14777
+ exports.getGlobalNowData = getGlobalNowData;
14321
14778
  exports.getIdsPickerSchema = getIdsPickerSchema;
14322
14779
  exports.getImageSrc = getImageSrc;
14323
14780
  exports.getInstanceInfo = getInstanceInfo;