@steedos-widgets/amis-lib 1.3.4-beta.8 → 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
  }
@@ -5978,10 +6064,13 @@ async function lookupToAmisPicker(field, readonly, ctx){
5978
6064
  const op = api.data.$self.op;
5979
6065
  if(!_.isEmpty(op)){
5980
6066
  // op不为空,表示处于字段初始编辑状态,不是点击后出现弹窗状态。
6067
+ // 这里不可以用_.pick函数让payload只返回labelField和valueField,因为字段上配置的amis autoFill功能可能依赖了其他字段
6068
+ /*
5981
6069
  const rows = _.map(payload.data.rows, (item)=>{
5982
6070
  return _.pick(item, ["${referenceTo.labelField.name}", "${referenceTo.valueField.name}"]);
5983
6071
  })
5984
6072
  payload.data.rows = rows;
6073
+ */
5985
6074
  return payload;
5986
6075
  }
5987
6076
  if(enable_tree){
@@ -6062,13 +6151,15 @@ async function lookupToAmisPicker(field, readonly, ctx){
6062
6151
  pickerSchema.headerToolbar = getObjectHeaderToolbar(refObjectConfig, fieldsArr, ctx.formFactor, { headerToolbarItems, isLookup: true, keywordsSearchBoxName });
6063
6152
  const isAllowCreate = refObjectConfig.permissions.allowCreate;
6064
6153
  const isCreate = ___namespace.isBoolean(field.create) ? field.create : true;
6065
- if (isAllowCreate && isCreate) {
6154
+ // lookup字段配置过滤条件就强制不显示新建按钮
6155
+ let isHasFilters = (field.filters || field._filtersFunction) ? true : false;
6156
+ if (isAllowCreate && isCreate && !isHasFilters) {
6066
6157
  const new_button = await getSchema$5(refObjectConfig, { appId: ctx.appId, objectName: refObjectConfig.name, formFactor: ctx.formFactor });
6067
6158
  new_button.align = "right";
6068
6159
  // 保持快速搜索放在最左侧,新建按钮往里插,而不是push到最后
6069
6160
  pickerSchema.headerToolbar.splice(pickerSchema.headerToolbar.length - 1, 0, new_button);
6070
6161
  }
6071
- pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar();
6162
+ pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar(refObjectConfig,ctx.formFactor,{isLookup: true});
6072
6163
  if (ctx.filterVisible !== false) {
6073
6164
  pickerSchema.filter = await getObjectFilter(refObjectConfig, fields, {
6074
6165
  ...ctx,
@@ -6196,10 +6287,10 @@ async function lookupToAmisSelect(field, readonly, ctx){
6196
6287
  // const labelFieldKey = referenceTo && referenceTo.labelField?.name || 'name';
6197
6288
 
6198
6289
  let apiInfo;
6199
-
6290
+ let defaultValueOptionsQueryData;
6200
6291
  if(referenceTo){
6201
6292
  // 字段值单独走一个请求合并到source的同一个GraphQL接口中
6202
- const defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6293
+ defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6203
6294
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6204
6295
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6205
6296
  ], {
@@ -6212,7 +6303,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6212
6303
  }, null, [
6213
6304
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6214
6305
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6215
- ], {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}"`});
6216
6307
 
6217
6308
  apiInfo.adaptor = `
6218
6309
  const data = payload.data;
@@ -6306,11 +6397,16 @@ async function lookupToAmisSelect(field, readonly, ctx){
6306
6397
  var optionsFiltersOp = "${field.multiple ? "in" : "="}";
6307
6398
  var optionsFilters = [["${valueFieldKey}", optionsFiltersOp, []]];
6308
6399
  if (defaultValue && !api.data.$term) {
6400
+ const defaultValueOptionsQueryData = ${JSON.stringify(defaultValueOptionsQueryData)};
6401
+ const defaultValueOptionsQuery = defaultValueOptionsQueryData?.query?.replace(/^{/,"").replace(/}$/,"");
6309
6402
  // 字段值单独请求,没值的时候在请求中返回空
6310
6403
  optionsFilters = [["${valueFieldKey}", optionsFiltersOp, defaultValue]];
6311
6404
  if(filters.length > 0){
6312
6405
  optionsFilters = [filters, optionsFilters];
6313
6406
  }
6407
+ if(defaultValueOptionsQuery){
6408
+ api.data.query = "{"+api.data.query.replace(/^{/,"").replace(/}$/,"")+","+defaultValueOptionsQuery+"}";
6409
+ }
6314
6410
  }
6315
6411
  api.data.query = api.data.query.replace(/{__options_filters}/g, JSON.stringify(optionsFilters));
6316
6412
  return api;
@@ -6352,7 +6448,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6352
6448
  disabledOn: `${readonly} || ( (this._master && (this._master.relatedKey ==='${field.name}')) || ((this.relatedKey ==='${field.name}') && (${field.multiple} != true)) )`,
6353
6449
  // labelField: labelField,
6354
6450
  // valueField: valueField,
6355
- source: apiInfo,
6451
+ // source: apiInfo,
6356
6452
  autoComplete: apiInfo,
6357
6453
  searchable: true,
6358
6454
  };
@@ -6431,10 +6527,10 @@ async function lookupToAmis(field, readonly, ctx){
6431
6527
 
6432
6528
  const refObject = await getUISchema(referenceTo.objectName);
6433
6529
 
6434
- // 此处不参考 steedos 的 enable_enhanced_lookup 规则. 如果默认是开启弹出选择,用户选择过程操作太繁琐, 所以默认是关闭弹出选择.
6435
- // 由于amis picker 目前不支持联动, 配置了depend_on时, 使用使用select ,以支持联动
6436
- // TODO: 确认 amis picker 支持联动时, 清理field.depend_on判断
6437
- 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){
6438
6534
  return await lookupToAmisPicker(field, readonly, ctx);
6439
6535
  }else if(refObject.enable_tree) {
6440
6536
  return await lookupToAmisTreeSelect(field, readonly, Object.assign({}, ctx, {
@@ -6751,8 +6847,8 @@ function getAmisStaticFieldType(type, readonly, options){
6751
6847
  /*
6752
6848
  * @Author: baozhoutao@steedos.com
6753
6849
  * @Date: 2022-10-28 14:15:09
6754
- * @LastEditors: baozhoutao@steedos.com
6755
- * @LastEditTime: 2022-11-02 18:06:16
6850
+ * @LastEditors: liaodaxue
6851
+ * @LastEditTime: 2023-10-30 17:51:54
6756
6852
  * @Description:
6757
6853
  */
6758
6854
 
@@ -6803,11 +6899,26 @@ const getAmisFileEditSchema = (steedosField)=>{
6803
6899
  useChunk: false, // 关闭分块上传
6804
6900
  receiver: {
6805
6901
  method: "post",
6902
+ dataType: "form-data",
6806
6903
  url: `\${context.rootUrl}/s3/${tableName}`,
6807
- data: {
6808
- $: "$$",
6809
- context: `\${context}`,
6810
- },
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
+ `,
6811
6922
  adaptor: `
6812
6923
  const { context } = api.body;
6813
6924
  var rootUrl = context.rootUrl + "/api/files/${tableName}/";
@@ -6993,8 +7104,6 @@ function getSelectFieldOptions(field){
6993
7104
  }
6994
7105
 
6995
7106
  async function convertSFieldToAmisField(field, readonly, ctx) {
6996
- // console.log('convertSFieldToAmisField====>', field, readonly, ctx)
6997
- const isMobile = window.innerWidth <= 768;
6998
7107
  // 创建人和修改人、创建时间和修改时间不显示
6999
7108
  if(___namespace.includes(OMIT_FIELDS, field.name) && ctx.showSystemFields != true){
7000
7109
  return;
@@ -7083,26 +7192,33 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7083
7192
  };
7084
7193
  break;
7085
7194
  case 'date':
7086
- convertData = isMobile && !readonly ? {
7087
- type: "native-date",
7088
- pipeIn: (value, data) => {
7089
- if (value) {
7090
- value = moment(value).utc().format('YYYY-MM-DD');
7091
- return value;
7092
- } else {
7093
- return "";
7094
- }
7095
-
7096
- },
7097
- pipeOut: (value, oldValue, data) => {
7098
- if (value) {
7099
- value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7100
- return value;
7101
- } else {
7102
- return "";
7103
- }
7104
- }
7105
- } : {
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 = {
7106
7222
  type: getAmisStaticFieldType('date', readonly),
7107
7223
  inputFormat: "YYYY-MM-DD",
7108
7224
  format:'YYYY-MM-DDT00:00:00.000[Z]',
@@ -7121,43 +7237,51 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7121
7237
  };
7122
7238
  break;
7123
7239
  case 'datetime':
7124
- convertData = isMobile && !readonly ? {
7125
- type: "combo",
7126
- pipeIn: (value, data) => {
7127
- let revalue = {};
7128
- if (value && value != "Invalid date") {
7129
- value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7130
- revalue[field.name + "-native-date"] = value.split(' ')[0];
7131
- revalue[field.name + "-native-time"] = value.split(' ')[1];
7132
- } else {
7133
- revalue[field.name + "-native-date"] = "";
7134
- revalue[field.name + "-native-time"] = "";
7135
- }
7136
- return revalue;
7137
- },
7138
- pipeOut: (value, oldValue, data) => {
7139
- let revalue = "";
7140
- if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7141
- revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7142
- revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7143
- }
7144
- return revalue;
7145
- },
7146
- items: [
7147
- {
7148
- type: "native-date",
7149
- name: field.name + "-native-date",
7150
- className: "steedos-native-date",
7151
- value: ""
7152
- },
7153
- {
7154
- type: "native-time",
7155
- name: field.name + "-native-time",
7156
- className: "steedos-native-time",
7157
- value: ""
7158
- }
7159
- ]
7160
- } : {
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 = {
7161
7285
  type: getAmisStaticFieldType('datetime', readonly),
7162
7286
  inputFormat: 'YYYY-MM-DD HH:mm',
7163
7287
  format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
@@ -7177,26 +7301,34 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7177
7301
  };
7178
7302
  break;
7179
7303
  case 'time':
7180
- convertData = isMobile && !readonly ? {
7181
- type: "native-time",
7182
- pipeIn: (value, data) => {
7183
- if (value) {
7184
- value = moment(value).utc().format('HH:mm');
7185
- return value;
7186
- } else {
7187
- return "";
7188
- }
7189
-
7190
- },
7191
- pipeOut: (value, oldValue, data) => {
7192
- if (value) {
7193
- value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7194
- return value;
7195
- } else {
7196
- return "";
7197
- }
7198
- }
7199
- } : {
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 = {
7200
7332
  type: getAmisStaticFieldType('time', readonly),
7201
7333
  inputFormat: 'HH:mm',
7202
7334
  timeFormat:'HH:mm',
@@ -7246,7 +7378,20 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7246
7378
  type: getAmisStaticFieldType('number', readonly),
7247
7379
  min: field.min,
7248
7380
  max: field.max,
7249
- 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
+ },
7250
7395
  };
7251
7396
  }
7252
7397
  break;
@@ -7658,8 +7803,41 @@ var config = {
7658
7803
  };
7659
7804
 
7660
7805
  async function getQuickEditSchema(field, options){
7661
- 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传值
7662
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
+
7663
7841
  if (field.disabled) {
7664
7842
  quickEditSchema = false;
7665
7843
  } else {
@@ -7676,7 +7854,7 @@ async function getQuickEditSchema(field, options){
7676
7854
  {
7677
7855
  "actionType": "custom",
7678
7856
  "script": `
7679
- var _display = event.data._display;
7857
+ var _display = _.cloneDeep(event.data._display);
7680
7858
  ${displayField}
7681
7859
  doAction({actionType: 'setValue', "args": {"value": {_display}},componentId: "${quickEditId}"});
7682
7860
  `
@@ -7698,7 +7876,7 @@ async function getQuickEditSchema(field, options){
7698
7876
  第二种是增加选项时,按照value的值,找到对应选项,并按照_display的规则为其赋值
7699
7877
  */
7700
7878
  TempDisplayField = `
7701
- const preData = event.data.__super.${field.name};
7879
+ const preData = _.cloneDeep(event.data.__super.${field.name});
7702
7880
  if(preData && event.data.${field.name}.length < preData.length){
7703
7881
  let deletedIndex;
7704
7882
  preData.forEach(function(item,index){
@@ -7742,7 +7920,7 @@ async function getQuickEditSchema(field, options){
7742
7920
  break;
7743
7921
  case "percent":
7744
7922
  TempDisplayField = `
7745
- _display["${field.name}"] = (event.data.value * 100).toFixed(${field.scale}) + '%';
7923
+ _display["${field.name}"] = event.data.value.toFixed(${field.scale}) + '%';
7746
7924
  `;
7747
7925
  quickEditSchema.body[0].onEvent["change"] = quickEditOnEvent(TempDisplayField);
7748
7926
  break;
@@ -7893,6 +8071,131 @@ async function getQuickEditSchema(field, options){
7893
8071
  }
7894
8072
 
7895
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
+ }
7896
8199
  } else {
7897
8200
  quickEditSchema = false;
7898
8201
  }
@@ -7927,6 +8230,8 @@ async function getTableColumns(fields, options){
7927
8230
  const columns = [];
7928
8231
  if(!options.isLookup){
7929
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"});
7930
8235
  }
7931
8236
  const allowEdit = options.permissions?.allowEdit && !options.isLookup && options.enable_inline_edit != false;
7932
8237
 
@@ -7958,7 +8263,7 @@ async function getTableColumns(fields, options){
7958
8263
  {
7959
8264
  "args": {
7960
8265
  "api": {
7961
- "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'}",
7962
8267
  "method": "get",
7963
8268
  "headers": {
7964
8269
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
@@ -8005,7 +8310,7 @@ async function getTableColumns(fields, options){
8005
8310
  else if(field.type === 'select'){
8006
8311
  const map = getSelectMap(field.options);
8007
8312
  columnItem = Object.assign({}, {
8008
- type: "mapping",
8313
+ type: "static-mapping",
8009
8314
  name: field.name,
8010
8315
  label: field.label,
8011
8316
  map: map,
@@ -8020,7 +8325,7 @@ async function getTableColumns(fields, options){
8020
8325
  const tpl = await getFieldTpl(field, options);
8021
8326
  let type = 'text';
8022
8327
  if(tpl){
8023
- type = 'tpl';
8328
+ type = 'static';
8024
8329
  }else if(field.type === 'html'){
8025
8330
  type = 'markdown';
8026
8331
  }else if(field.type === 'url'){
@@ -8061,6 +8366,7 @@ async function getTableColumns(fields, options){
8061
8366
  columnItem.quickEdit = quickEditSchema;
8062
8367
  columnItem.quickEditEnabledOn = "${is_system !== true}";
8063
8368
  }
8369
+ columnItem.id = `${options.objectName}_${field.name}_\${_index}`;
8064
8370
  columns.push(columnItem);
8065
8371
  }
8066
8372
  }
@@ -8339,7 +8645,7 @@ async function getTableOperation(ctx){
8339
8645
  }
8340
8646
  return {
8341
8647
  type: 'operation',
8342
- label: i18next__default["default"].t('frontend_operation'),
8648
+ label: "",
8343
8649
  fixed: 'right',
8344
8650
  labelClassName: 'text-center',
8345
8651
  className: 'text-center steedos-listview-operation w-10',
@@ -8373,23 +8679,87 @@ async function getTableOperation(ctx){
8373
8679
  }
8374
8680
  }
8375
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
+
8376
8716
  async function getTableSchema$1(fields, options){
8377
8717
  if(!options){
8378
8718
  options = {};
8379
8719
  }
8380
8720
  let { isLookup, hiddenColumnOperation } = options;
8721
+ const defaults = options.defaults;
8722
+ const listSchema = (defaults && defaults.listSchema) || {};
8723
+
8381
8724
  let columns = [];
8382
8725
  let useMobileColumns = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8383
8726
  if(isLookup){
8384
8727
  // 在lookup手机端列表模式调式好之前不使用getMobileTableColumns
8385
8728
  useMobileColumns = false;
8386
8729
  }
8730
+ if(listSchema.mode && listSchema.mode !== "table"){
8731
+ // 如果指定的mode,则不走我们内置的手机端列表效果,使用steedos组件内部开发的默认card/list效果,或者由用户自己实现card/list模式的crud列表
8732
+ useMobileColumns = false;
8733
+ }
8387
8734
  if(useMobileColumns){
8388
8735
  columns = await getMobileTableColumns(fields, options);
8389
8736
  }
8390
8737
  else {
8391
8738
  columns = await getTableColumns(fields, options);
8392
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
+
8393
8763
  if(!isLookup && !hiddenColumnOperation){
8394
8764
  columns.push(await getTableOperation(options));
8395
8765
  }
@@ -8397,6 +8767,7 @@ async function getTableSchema$1(fields, options){
8397
8767
 
8398
8768
  return {
8399
8769
  mode: "table",
8770
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8400
8771
  name: "thelist",
8401
8772
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8402
8773
  className: "",
@@ -8867,18 +9238,30 @@ function getReadonlyFormAdaptor(object, fields, options){
8867
9238
  payload.status = 2;
8868
9239
  payload.msg = payload.errors[0].message;
8869
9240
  }
9241
+ ${options && options.initApiAdaptor || ''}
8870
9242
  return payload;
8871
9243
  `
8872
9244
  }
8873
9245
 
8874
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
+ }
8875
9255
  return {
8876
9256
  method: "post",
8877
9257
  url: getApi$2() + '&objectName=${objectName}' + "&recordId=${recordId}",
8878
9258
  cache: API_CACHE,
8879
- // requestAdaptor: "console.log('getReadonlyFormInitApi requestAdaptor', api);return api;",
9259
+ requestAdaptor: `
9260
+ ${options && options.initApiRequestAdaptor || ''}
9261
+ return api;
9262
+ `,
8880
9263
  adaptor: getReadonlyFormAdaptor(object, fields, options),
8881
- data: await getFindOneQuery$1(object, recordId, fields, options),
9264
+ data: await getFindOneQuery$1(object, recordId, fields, findOneOptions),
8882
9265
  headers: {
8883
9266
  Authorization: "Bearer ${context.tenantId},${context.authToken}"
8884
9267
  }
@@ -9019,7 +9402,7 @@ async function getEditFormInitApi(object, recordId, fields, options){
9019
9402
  ${getScriptForRewriteValueForFileFields(fields)}
9020
9403
 
9021
9404
  _.each(dataKeys, function(key){
9022
- if(fieldKeys.indexOf(key)<0){
9405
+ if(fieldKeys.indexOf(key)<0 && key !== "_display"){
9023
9406
  delete data[key];
9024
9407
  }
9025
9408
  })
@@ -9194,6 +9577,8 @@ async function getCalendarApi(mainObject, fields, options) {
9194
9577
 
9195
9578
  if(api.data.$self.additionalFilters){
9196
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)
9197
9582
  }
9198
9583
 
9199
9584
  var pageSize = api.data.pageSize || 10;
@@ -9519,6 +9904,7 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9519
9904
  businessHours.endTime = `${calendarOptions.endDayHour}:00`;
9520
9905
  }
9521
9906
 
9907
+ // api.trackExpression="\\\${additionalFilters}";
9522
9908
  const onEvent = {
9523
9909
  "getEvents": {
9524
9910
  "weight": 0,
@@ -9530,6 +9916,22 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9530
9916
  "actionType": "custom",
9531
9917
  "script": onGetEventsScript
9532
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
+ // }
9533
9935
  ]
9534
9936
  },
9535
9937
  "select": {
@@ -9853,7 +10255,7 @@ function deleteVariable(data, key) {
9853
10255
  * @Author: baozhoutao@steedos.com
9854
10256
  * @Date: 2022-05-26 16:02:08
9855
10257
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
9856
- * @LastEditTime: 2023-09-15 15:36:17
10258
+ * @LastEditTime: 2023-10-12 18:25:05
9857
10259
  * @Description:
9858
10260
  */
9859
10261
 
@@ -9873,8 +10275,9 @@ const getFieldSchemaArray = (formFields, ctx) => {
9873
10275
  }
9874
10276
 
9875
10277
  let forceHidden = false;
9876
- if(!recordId && field.readonly){
10278
+ if(!recordId && field.readonly && !ctx.isEditor){
9877
10279
  // 新建记录时,只读字段先隐藏,后续支持显示后,即任务:https://github.com/steedos/steedos-platform/issues/3164 完成后再放开
10280
+ // 表单只读时所有字段都是readonly,设计器中如果forceHidden会造成整个表单在只读的时候显示为空白了,所以要排除掉
9878
10281
  forceHidden = true;
9879
10282
  }
9880
10283
 
@@ -10116,6 +10519,9 @@ async function getObjectCRUD(objectSchema, fields, options){
10116
10519
  const nonpaged = objectSchema.paging && objectSchema.paging.enabled === false;
10117
10520
  const isTreeObject = objectSchema.enable_tree;
10118
10521
  const bulkActions = getBulkActions(objectSchema);
10522
+ const defaults = options.defaults;
10523
+ const listSchema = (defaults && defaults.listSchema) || {};
10524
+
10119
10525
  const bodyProps = {
10120
10526
  // toolbar: getToolbar(),
10121
10527
  // headerToolbar: getObjectHeaderToolbar(objectSchema, options.formFactor, {showDisplayAs}),
@@ -10127,9 +10533,12 @@ async function getObjectCRUD(objectSchema, fields, options){
10127
10533
  filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, options),
10128
10534
  };
10129
10535
  if(options.formFactor !== 'SMALL' || ["split"].indexOf(options.displayAs) == -1){
10130
- Object.assign(bodyProps, {
10131
- bulkActions: options.bulkActions != false ? bulkActions : false
10132
- });
10536
+ if(listSchema.mode !== "cards"){
10537
+ // card模式时默认不显示勾选框
10538
+ Object.assign(bodyProps, {
10539
+ bulkActions: options.bulkActions != false ? bulkActions : false
10540
+ });
10541
+ }
10133
10542
  }
10134
10543
  // yml里配置的 不分页和enable_tree:true 优先级最高,组件中输入的top次之。
10135
10544
  options.queryCount = true;
@@ -10188,17 +10597,19 @@ async function getObjectCRUD(objectSchema, fields, options){
10188
10597
  }
10189
10598
  let tableOptions = Object.assign({
10190
10599
  idFieldName: objectSchema.idFieldName, labelFieldName: labelFieldName,
10191
- 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
10192
10602
  }, options);
10193
10603
  tableOptions.amisData = createObject(options.amisData || {}, {});
10194
10604
  const table = await getTableSchema$1(fields, tableOptions);
10195
- delete table.mode;
10605
+ // delete table.mode;
10196
10606
  //image与avatar需要在提交修改时特别处理
10197
10607
  const imageNames = ___default["default"].compact(___default["default"].map(___default["default"].filter(fields, (field) => ["image","avatar"].includes(field.type)), 'name'));
10198
10608
  const quickSaveApiRequestAdaptor = `
10199
10609
  var graphqlOrder = "";
10200
10610
  var imageNames = ${JSON.stringify(imageNames)};
10201
- api.data.rowsDiff.forEach(function (item, index) {
10611
+ const rowsDiff = _.cloneDeep(api.data.rowsDiff);
10612
+ rowsDiff.forEach(function (item, index) {
10202
10613
  for(key in item){
10203
10614
  if(_.includes(imageNames, key)){
10204
10615
  if(typeof item[key] == "string"){
@@ -10212,6 +10623,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10212
10623
  }
10213
10624
  }
10214
10625
  }
10626
+ item = _.omit(item, '_display');
10215
10627
  const itemOrder = 'update' + index + ':' + api.data.objectName + '__update(id:"' + item._id + '", doc:' + JSON.stringify(JSON.stringify(_.omit(item, '_id'))) + ') {_id}';
10216
10628
  graphqlOrder += itemOrder;
10217
10629
  })
@@ -10262,12 +10674,14 @@ async function getObjectCRUD(objectSchema, fields, options){
10262
10674
 
10263
10675
  }
10264
10676
 
10265
- const defaults = options.defaults;
10266
-
10267
- const listSchema = (defaults && defaults.listSchema) || {};
10268
10677
  body = defaultsDeep({}, listSchema, body);
10269
10678
  body = await getCrudSchemaWithDataFilter(body, { crudDataFilter, onCrudDataFilter, amisData, env });
10270
10679
 
10680
+ let crudModeClassName = "";
10681
+ if(body.mode){
10682
+ crudModeClassName = `steedos-crud-mode-${body.mode}`;
10683
+ }
10684
+
10271
10685
  if (defaults) {
10272
10686
  const headerSchema = defaults.headerSchema;
10273
10687
  const footerSchema = defaults.footerSchema;
@@ -10296,7 +10710,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10296
10710
  // TODO: data应该只留loaded,其他属性都改为从上层传递下来
10297
10711
  return {
10298
10712
  type: 'service',
10299
- className: '',
10713
+ className: crudModeClassName,
10300
10714
  //目前crud的service层id不认用户自定义id,只支持默认规则id,许多地方的格式都写死了service_listview_${objectname}
10301
10715
  id: `service_${id}`,
10302
10716
  name: `page`,
@@ -10350,8 +10764,29 @@ const getFormFields = (objectSchema, formProps)=>{
10350
10764
  return lodash.sortBy(___default["default"].values(fields), "sort_no");
10351
10765
  };
10352
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
+
10353
10787
  async function getObjectForm(objectSchema, ctx){
10354
- 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;
10355
10790
  const fields = ___default["default"].values(objectSchema.fields);
10356
10791
  const formFields = getFormFields(objectSchema, ctx);
10357
10792
  const formSchema = defaults && defaults.formSchema || {};
@@ -10368,7 +10803,8 @@ async function getObjectForm(objectSchema, ctx){
10368
10803
  name: `page_edit_${recordId}`,
10369
10804
  api: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
10370
10805
  data:{
10371
- editFormInited: false
10806
+ editFormInited: false,
10807
+ ...amisData
10372
10808
  },
10373
10809
  // data: {global: getGlobalData('edit'), recordId: recordId, objectName: objectSchema.name, context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10374
10810
  initApi: null,
@@ -10421,9 +10857,10 @@ async function getObjectForm(objectSchema, ctx){
10421
10857
  },
10422
10858
  "expression": `\${_master.objectName != '${objectSchema.name}' && _master.objectName}`
10423
10859
  },
10860
+ ...submitSuccActions,
10424
10861
  // {
10425
10862
  // "actionType": "custom",
10426
- // "script": "debugger;"
10863
+ // "script": `setTimeout(function(){doAction({'actionType': 'setValue','componentId': '${formSchema.id}','args': {'value': {'sort_no': 879}}})}, 300)`
10427
10864
  // },
10428
10865
  // {
10429
10866
  // "args": {},
@@ -10434,20 +10871,22 @@ async function getObjectForm(objectSchema, ctx){
10434
10871
  }
10435
10872
  })]
10436
10873
  };
10874
+ amisSchema.body[0] = await getFormSchemaWithDataFilter(amisSchema.body[0], { formDataFilter, onFormDataFilter, amisData, env });
10437
10875
  return amisSchema;
10438
10876
  }
10439
10877
 
10440
10878
  async function getObjectDetail(objectSchema, recordId, ctx){
10441
- 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;
10442
10881
  const fields = ___default["default"].values(objectSchema.fields);
10443
10882
  const formFields = getFormFields(objectSchema, ctx);
10444
10883
  const serviceId = `service_detail_page`;
10445
- return {
10884
+ const amisSchema = {
10446
10885
  type: 'service',
10447
10886
  name: `page_readonly_${recordId}`,
10448
10887
  id: serviceId,
10449
10888
  data: {global: getGlobalData('read'), context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10450
- api: await getReadonlyFormInitApi(objectSchema, recordId, fields, formInitProps),
10889
+ api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
10451
10890
  body: [
10452
10891
  {
10453
10892
  "type": "wrapper", //form 的 hiddenOn 会导致 form onEvent 异常, 使用wrapper包裹一次form,并在wrapper上控制显隐
@@ -10466,7 +10905,11 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10466
10905
  "formData": "$$"
10467
10906
  },
10468
10907
  wrapWithPanel: false,
10469
- 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
+ ),
10470
10913
  className: 'steedos-amis-form bg-white',
10471
10914
  actions: [], // 不显示表单默认的提交按钮
10472
10915
  onEvent: {
@@ -10520,7 +10963,10 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10520
10963
  ]
10521
10964
  }
10522
10965
  }
10523
- }
10966
+ };
10967
+
10968
+ amisSchema.body[0].body = await getFormSchemaWithDataFilter(amisSchema.body[0].body, { formDataFilter, onFormDataFilter, amisData, env });
10969
+ return amisSchema;
10524
10970
  }
10525
10971
 
10526
10972
  /*
@@ -10600,7 +11046,7 @@ const getRecordPermissions = async (objectName, recordId)=>{
10600
11046
  * @Author: baozhoutao@steedos.com
10601
11047
  * @Date: 2022-07-05 15:55:39
10602
11048
  * @LastEditors: liaodaxue
10603
- * @LastEditTime: 2023-09-25 17:18:08
11049
+ * @LastEditTime: 2023-10-23 15:55:46
10604
11050
  * @Description:
10605
11051
  */
10606
11052
 
@@ -10891,11 +11337,15 @@ async function getRelatedListSchema(
10891
11337
  ctx
10892
11338
  ) {
10893
11339
  const uiSchema = await getUISchema(objectName);
11340
+ if(!uiSchema){
11341
+ return {}
11342
+ }
11343
+ const listViewNames = _$1.map(uiSchema.list_views, 'name');
10894
11344
  const listView = _$1.find(
10895
11345
  uiSchema.list_views,
10896
11346
  (listView, name) => {
10897
- // 传入listViewName空值则取第一个
10898
- if(!listViewName){
11347
+ // 传入listViewName空值 或者 不存在 则取第一个
11348
+ if(!listViewName || listViewNames.indexOf(listViewName)<0){
10899
11349
  listViewName = name;
10900
11350
  }
10901
11351
  return name === listViewName || listView._id === listViewName;
@@ -10975,8 +11425,8 @@ async function getRelatedListSchema(
10975
11425
  /*
10976
11426
  * @Author: baozhoutao@steedos.com
10977
11427
  * @Date: 2022-07-05 15:55:39
10978
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
10979
- * @LastEditTime: 2023-09-21 17:35:06
11428
+ * @LastEditors: liaodaxue
11429
+ * @LastEditTime: 2023-10-20 11:38:25
10980
11430
  * @Description:
10981
11431
  */
10982
11432
 
@@ -11305,8 +11755,8 @@ async function getListSchema(
11305
11755
  "filtersFunction": listview_filters,
11306
11756
  "sort": sort,
11307
11757
  "ctx": ctx,
11308
- "requestAdaptor": listView.requestAdaptor,
11309
- "adaptor": listView.adaptor,
11758
+ "requestAdaptor": listView.requestAdaptor || ctx.requestAdaptor,
11759
+ "adaptor": listView.adaptor || ctx.adaptor,
11310
11760
  "headerToolbarItems": ctx.headerToolbarItems,
11311
11761
  "filterVisible": ctx.filterVisible,
11312
11762
  "rowClassNameExpr": ctx.rowClassNameExpr,
@@ -13951,10 +14401,18 @@ const getOpinionFieldStepsName = (field, top_keywords) => {
13951
14401
  * @Author: baozhoutao@steedos.com
13952
14402
  * @Date: 2022-09-09 17:47:37
13953
14403
  * @LastEditors: baozhoutao@steedos.com
13954
- * @LastEditTime: 2023-03-18 15:32:34
14404
+ * @LastEditTime: 2023-10-10 13:57:02
13955
14405
  * @Description:
13956
14406
  */
13957
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
+
13958
14416
  const getTrace = ({ instance, traceId }) => {
13959
14417
  return _$1.find(instance.traces, (trace) => {
13960
14418
  return trace._id === traceId;
@@ -14174,6 +14632,8 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14174
14632
  method: "get",
14175
14633
  });
14176
14634
 
14635
+ const moment = getMoment();
14636
+
14177
14637
  return {
14178
14638
  box: box,
14179
14639
  _id: instanceId,
@@ -14184,7 +14644,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14184
14644
  applicant_name: instance.applicant_name,
14185
14645
  submitter: instance.submitter,
14186
14646
  submit_date: instance.submit_date
14187
- ? amisRequire("moment")(instance.submit_date).format("YYYY-MM-DD")
14647
+ ? (moment && moment(instance.submit_date).format("YYYY-MM-DD"))
14188
14648
  : "",
14189
14649
  state: instance.state,
14190
14650
  approveValues: values,
@@ -14224,8 +14684,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14224
14684
  finishDate = approve.is_read ? "已读" : "未处理";
14225
14685
  judge = null;
14226
14686
  } else {
14227
- finishDate =
14228
- amisRequire("moment")(finishDate).format("YYYY-MM-DD HH:mm");
14687
+ finishDate = moment && moment(finishDate).format("YYYY-MM-DD HH:mm");
14229
14688
  }
14230
14689
 
14231
14690
  switch (judge) {
@@ -14315,6 +14774,7 @@ exports.getFileSrc = getFileSrc;
14315
14774
  exports.getFlowFormSchema = getFlowFormSchema;
14316
14775
  exports.getFormPageInitSchema = getFormPageInitSchema;
14317
14776
  exports.getFormSchema = getFormSchema;
14777
+ exports.getGlobalNowData = getGlobalNowData;
14318
14778
  exports.getIdsPickerSchema = getIdsPickerSchema;
14319
14779
  exports.getImageSrc = getImageSrc;
14320
14780
  exports.getInstanceInfo = getInstanceInfo;