@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.esm.js CHANGED
@@ -443,8 +443,8 @@ function getLookupListView(refObjectConfig) {
443
443
  /*
444
444
  * @Author: baozhoutao@steedos.com
445
445
  * @Date: 2022-05-23 09:53:08
446
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
447
- * @LastEditTime: 2023-09-19 14:38:39
446
+ * @LastEditors: liaodaxue
447
+ * @LastEditTime: 2023-10-11 17:32:17
448
448
  * @Description:
449
449
  */
450
450
 
@@ -505,7 +505,7 @@ function getSelectMap(selectOptions){
505
505
  if(optionColor){
506
506
  const background = optionColor.charAt(0) === '#' ? optionColor : '#'+optionColor;
507
507
  const color = getContrastColor(background);
508
- const optionColorStyle = 'background:'+background+';color:'+color;
508
+ const optionColorStyle = 'background:'+background+';color:'+color+';line-height:1.5rem';
509
509
  map[optionValue] = `<span class="rounded-xl px-2 py-1" style='${optionColorStyle}'>${option.label}</span>`;
510
510
  }else {
511
511
  map[optionValue] = option.label;
@@ -962,17 +962,17 @@ async function getFindQuery(object, recordId, fields, options){
962
962
  }
963
963
 
964
964
  const countQuery = options.count === false ? "" : `,count:${object.name}__count(filters:{__filters})`;
965
- const moreQuerie = options.moreQueries?.length ? ("," + options.moreQueries.map(function(item){
966
- // 把最外层的{}去除
967
- return item.replace(/^{/,"").replace(/}$/,"");
968
- }).join(",")) : "";
965
+ // const moreQuerie = options.moreQueries?.length ? ("," + options.moreQueries.map(function(item){
966
+ // // 把最外层的{}去除
967
+ // return item.replace(/^{/,"").replace(/}$/,"");
968
+ // }).join(",")) : "";
969
969
 
970
970
  return {
971
971
  orderBy: "${orderBy}",
972
972
  orderDir: "${orderDir}",
973
973
  pageNo: "${page}",
974
974
  pageSize: "${perPage}",
975
- query: `{${alias}:${object.name}${queryOptions}{${await getFieldsTemplate(fields, options.expand)}${treeFields}${cfsFields}}${countQuery}${moreQuerie}}`
975
+ query: `{${alias}:${object.name}${queryOptions}{${await getFieldsTemplate(fields, options.expand)}${treeFields}${cfsFields}}${countQuery}}`
976
976
  }
977
977
  }
978
978
 
@@ -1764,6 +1764,13 @@ async function getSelectUserSchema(field, readonly, ctx) {
1764
1764
  return amisSchema;
1765
1765
  }
1766
1766
 
1767
+ /*
1768
+ * @Author: 殷亮辉 yinlianghui@hotoa.com
1769
+ * @Date: 2023-03-22 09:31:21
1770
+ * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
1771
+ * @LastEditTime: 2023-11-05 16:31:38
1772
+ */
1773
+
1767
1774
  const globalTag = '__G_L_O_B_A_L__';
1768
1775
 
1769
1776
  const getParentPath = function (path) {
@@ -1803,7 +1810,43 @@ const isExpression = function (func) {
1803
1810
  return false;
1804
1811
  };
1805
1812
 
1813
+ const getMoment$1 = () => {
1814
+ if (window.amisRequire) {
1815
+ return window.amisRequire("moment");
1816
+ } else if (window.moment) {
1817
+ return window.moment;
1818
+ }
1819
+ };
1820
+
1821
+ const getGlobalNowData = () => {
1822
+ let now = new Date();
1823
+ let moment = getMoment$1();
1824
+ let today = moment().utc();
1825
+ today.set("hours", 0);
1826
+ today.set("minutes", 0);
1827
+ today.set("seconds", 0);
1828
+ today.set("milliseconds", 0);
1829
+ today = today.toDate();
1830
+ let timeNow = moment();
1831
+ timeNow.set("year", 1970);
1832
+ timeNow.set("month", 0);
1833
+ timeNow.set("date", 1);
1834
+ timeNow.set("hours", timeNow.hours() + timeNow.utcOffset() / 60);
1835
+ timeNow.set("seconds", 0);
1836
+ timeNow.set("milliseconds", 0);
1837
+ timeNow = timeNow.toDate();
1838
+ return {
1839
+ now,
1840
+ today,
1841
+ timeNow
1842
+ };
1843
+ };
1844
+
1806
1845
  const parseSingleExpression = function (func, formData, dataPath, global, userSession = {}) {
1846
+ if (global) {
1847
+ Object.assign(global, getGlobalNowData());
1848
+ }
1849
+
1807
1850
  var error, funcBody, parent, parentPath, str;
1808
1851
 
1809
1852
  if (formData === void 0) {
@@ -2570,20 +2613,29 @@ function getButtonVisibleOn$1(button){
2570
2613
  // return 'false';
2571
2614
  // }
2572
2615
  if(visible.trim().startsWith('function')){
2573
- return `${visible}.apply({
2616
+ visible = `${visible}.apply({
2574
2617
  object: uiSchema
2575
- }, [objectName, typeof _id === 'undefined' ? null: _id, typeof record === 'undefined' ? (typeof recordPermissions === 'undefined' ? {} : recordPermissions) : record.recordPermissions, data])`
2618
+ }, [objectName, typeof _id === 'undefined' ? null: _id, typeof record === 'undefined' ? (typeof recordPermissions === 'undefined' ? {} : recordPermissions) : record.recordPermissions, data])`;
2576
2619
  }
2577
- return visible;
2578
2620
  }
2579
2621
 
2580
2622
  if(button.type === 'amis_button'){
2581
- const amisSchema = button.amis_schema;
2623
+ let amisSchema = button.amis_schema;
2624
+ if(_$1.isString(amisSchema)){
2625
+ amisSchema = JSON.parse(amisSchema);
2626
+ }
2582
2627
  if(amisSchema && amisSchema.body && amisSchema.body.length > 0){
2583
2628
  const btn1 = amisSchema.body[0];
2584
- return btn1.visibleOn
2629
+ if(_$1.hasIn(btn1, 'visibleOn')){
2630
+ /* 当含有“更多”按钮或者“下拉”箭头按钮时,单个按钮的visibleOn需要合并到 “更多”按钮或者“下拉”箭头按钮的 visibleOn 中,用||隔开。
2631
+ visibleOn的格式需要保持一致; 不能是 js 和 ${xxx} 混合的表达式;
2632
+ visibleOn的值需要是js格式,因为默认的编辑、删除等系统按钮的visibleOn的格式就是js格式(function(){});
2633
+ */
2634
+ return btn1.visibleOn
2635
+ }
2585
2636
  }
2586
2637
  }
2638
+ return visible;
2587
2639
  }
2588
2640
 
2589
2641
  const getButtonVisible = (button, ctx) => {
@@ -2909,9 +2961,30 @@ const getObjectDetailHeaderButtons = (objectSchema, recordId)=>{
2909
2961
  const getObjectDetailButtonsSchemas = (objectSchema, recordId, ctx)=>{
2910
2962
  const { buttons, moreButtons, moreButtonsVisibleOn } = getObjectDetailHeaderButtons(objectSchema, recordId);
2911
2963
  if(ctx.formFactor === 'SMALL'){
2964
+ const dropdownButtons = [
2965
+ ..._$1.map(buttons, (button) => {
2966
+ button.className += ' w-full';
2967
+ return button;
2968
+ }),
2969
+ ..._$1.map(moreButtons, (button) => {
2970
+ button.className += ' w-full';
2971
+ return button;
2972
+ })
2973
+ ];
2974
+
2975
+ let phoneMoreButtonsVisibleOn = '';
2976
+ _$1.forEach(dropdownButtons, (button, index) => {
2977
+ if(index === 0){
2978
+ phoneMoreButtonsVisibleOn = button.visibleOn;
2979
+ }else {
2980
+ phoneMoreButtonsVisibleOn = phoneMoreButtonsVisibleOn + ' || ' + button.visibleOn;
2981
+ }
2982
+ });
2983
+
2912
2984
  return {
2913
2985
  "type": "button",
2914
2986
  "icon": "fa fa-angle-down",
2987
+ "visibleOn": phoneMoreButtonsVisibleOn,
2915
2988
  "onEvent": {
2916
2989
  "click": {
2917
2990
  "actions": [
@@ -2927,16 +3000,7 @@ const getObjectDetailButtonsSchemas = (objectSchema, recordId, ctx)=>{
2927
3000
  "id": "u:fd837823be5b",
2928
3001
  "vertical": true,
2929
3002
  "tiled": true,
2930
- "buttons": [
2931
- ..._$1.map(buttons, (button)=>{
2932
- button.className += ' w-full';
2933
- return button;
2934
- }),
2935
- ..._$1.map(moreButtons, (button)=>{
2936
- button.className += ' w-full';
2937
- return button;
2938
- })
2939
- ],
3003
+ "buttons": dropdownButtons,
2940
3004
  "btnLevel": "enhance",
2941
3005
  "className": "w-full",
2942
3006
  "btnClassName": "w-full",
@@ -3307,7 +3371,8 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
3307
3371
  if(isLookup){
3308
3372
  searchableFieldsStoreKey += "/lookup/" + objectName;
3309
3373
  }
3310
- let defaultSearchableFields = sessionStorage.getItem(searchableFieldsStoreKey);
3374
+ searchableFieldsStoreKey = searchableFieldsStoreKey + "/" + (data.context && data.context.userId);
3375
+ let defaultSearchableFields = localStorage.getItem(searchableFieldsStoreKey);
3311
3376
  if(defaultSearchableFields){
3312
3377
  defaultSearchableFields = defaultSearchableFields.split(",");
3313
3378
  }
@@ -3376,7 +3441,8 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
3376
3441
  if(isLookup){
3377
3442
  searchableFieldsStoreKey += "/lookup/" + objectName;
3378
3443
  }
3379
- sessionStorage.setItem(searchableFieldsStoreKey, value);
3444
+ searchableFieldsStoreKey = searchableFieldsStoreKey + "/" + (data.context && data.context.userId);
3445
+ localStorage.setItem(searchableFieldsStoreKey, value);
3380
3446
 
3381
3447
  // ===START===:当变更可搜索字段时,如果被移除的可搜索字段在本地存储中已经存入过滤条件中则应该清除本地存储中相关字段的过滤条件。
3382
3448
  const searchableFields = data.fields;
@@ -4342,7 +4408,8 @@ const getCopyListviewButtonSchema = ()=>{
4342
4408
  "&": "${list_view}",
4343
4409
  "name":"",
4344
4410
  "label": i18next.t('frontend_listview_control_clone_defaultData_label_start') + " ${list_view.label} " + i18next.t('frontend_listview_control_clone_defaultData_label_end'),
4345
- "shared":false
4411
+ "shared":false,
4412
+ "object_name": "${targetObjectName}",
4346
4413
  },
4347
4414
  "fieldsExtend": fieldsExtend$3(),
4348
4415
  "fields": fields(),
@@ -5130,7 +5197,7 @@ let resizeWindow = function(){
5130
5197
  //触发amis crud 高度重算
5131
5198
  setTimeout(()=>{
5132
5199
  window.dispatchEvent(new Event("resize"))
5133
- }, 500);
5200
+ }, 1000);
5134
5201
  }
5135
5202
  resizeWindow();
5136
5203
  // 手机端在显示搜索栏时隐藏crud上的刷新按钮,因为点击后crud高度显示有问题
@@ -5367,6 +5434,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
5367
5434
  }
5368
5435
 
5369
5436
  function getObjectFooterToolbar(mainObject, formFactor, options) {
5437
+ // crud card模式与table模式两种情况下showPageInput默认值不一样,所以需要显式设置为false
5370
5438
  if (formFactor === 'SMALL') {
5371
5439
  // return [
5372
5440
  // "load-more",
@@ -5376,14 +5444,17 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5376
5444
  "switch-per-page",
5377
5445
  {
5378
5446
  "type": "pagination",
5379
- "maxButtons": 5
5447
+ "maxButtons": 5,
5448
+ "showPageInput": false
5380
5449
  }
5381
5450
  ]
5382
5451
  }else {
5383
5452
  return [
5453
+ // "statistics",
5384
5454
  {
5385
5455
  "type": "pagination",
5386
- "maxButtons": 5
5456
+ "maxButtons": 5,
5457
+ "showPageInput": false
5387
5458
  }
5388
5459
  ]
5389
5460
  }
@@ -5392,16 +5463,31 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5392
5463
  if(options && options.isRelated){
5393
5464
  return [
5394
5465
  "statistics",
5395
- "pagination"
5466
+ {
5467
+ "type": "pagination",
5468
+ "maxButtons": 10,
5469
+ "showPageInput": false
5470
+ }
5396
5471
  ]
5397
5472
 
5398
5473
  }
5399
5474
  else {
5400
- return [
5401
- "switch-per-page",
5475
+ const no_pagination = mainObject.paging && (mainObject.paging.enabled === false);
5476
+ const is_lookup = options.isLookup;
5477
+ const commonConfig = [
5402
5478
  "statistics",
5403
- "pagination"
5404
- ]
5479
+ {
5480
+ "type": "pagination",
5481
+ "maxButtons": 10,
5482
+ "showPageInput": false
5483
+ }
5484
+ ];
5485
+
5486
+ if (no_pagination && is_lookup) {
5487
+ return commonConfig;
5488
+ } else {
5489
+ return ["switch-per-page", ...commonConfig];
5490
+ }
5405
5491
  }
5406
5492
  }
5407
5493
  }
@@ -5951,10 +6037,13 @@ async function lookupToAmisPicker(field, readonly, ctx){
5951
6037
  const op = api.data.$self.op;
5952
6038
  if(!_.isEmpty(op)){
5953
6039
  // op不为空,表示处于字段初始编辑状态,不是点击后出现弹窗状态。
6040
+ // 这里不可以用_.pick函数让payload只返回labelField和valueField,因为字段上配置的amis autoFill功能可能依赖了其他字段
6041
+ /*
5954
6042
  const rows = _.map(payload.data.rows, (item)=>{
5955
6043
  return _.pick(item, ["${referenceTo.labelField.name}", "${referenceTo.valueField.name}"]);
5956
6044
  })
5957
6045
  payload.data.rows = rows;
6046
+ */
5958
6047
  return payload;
5959
6048
  }
5960
6049
  if(enable_tree){
@@ -6035,13 +6124,15 @@ async function lookupToAmisPicker(field, readonly, ctx){
6035
6124
  pickerSchema.headerToolbar = getObjectHeaderToolbar(refObjectConfig, fieldsArr, ctx.formFactor, { headerToolbarItems, isLookup: true, keywordsSearchBoxName });
6036
6125
  const isAllowCreate = refObjectConfig.permissions.allowCreate;
6037
6126
  const isCreate = _$1.isBoolean(field.create) ? field.create : true;
6038
- if (isAllowCreate && isCreate) {
6127
+ // lookup字段配置过滤条件就强制不显示新建按钮
6128
+ let isHasFilters = (field.filters || field._filtersFunction) ? true : false;
6129
+ if (isAllowCreate && isCreate && !isHasFilters) {
6039
6130
  const new_button = await getSchema$5(refObjectConfig, { appId: ctx.appId, objectName: refObjectConfig.name, formFactor: ctx.formFactor });
6040
6131
  new_button.align = "right";
6041
6132
  // 保持快速搜索放在最左侧,新建按钮往里插,而不是push到最后
6042
6133
  pickerSchema.headerToolbar.splice(pickerSchema.headerToolbar.length - 1, 0, new_button);
6043
6134
  }
6044
- pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar();
6135
+ pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar(refObjectConfig,ctx.formFactor,{isLookup: true});
6045
6136
  if (ctx.filterVisible !== false) {
6046
6137
  pickerSchema.filter = await getObjectFilter(refObjectConfig, fields, {
6047
6138
  ...ctx,
@@ -6169,10 +6260,10 @@ async function lookupToAmisSelect(field, readonly, ctx){
6169
6260
  // const labelFieldKey = referenceTo && referenceTo.labelField?.name || 'name';
6170
6261
 
6171
6262
  let apiInfo;
6172
-
6263
+ let defaultValueOptionsQueryData;
6173
6264
  if(referenceTo){
6174
6265
  // 字段值单独走一个请求合并到source的同一个GraphQL接口中
6175
- const defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6266
+ defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6176
6267
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6177
6268
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6178
6269
  ], {
@@ -6185,7 +6276,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6185
6276
  }, null, [
6186
6277
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6187
6278
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6188
- ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`, moreQueries: [defaultValueOptionsQueryData.query]});
6279
+ ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`});
6189
6280
 
6190
6281
  apiInfo.adaptor = `
6191
6282
  const data = payload.data;
@@ -6279,11 +6370,16 @@ async function lookupToAmisSelect(field, readonly, ctx){
6279
6370
  var optionsFiltersOp = "${field.multiple ? "in" : "="}";
6280
6371
  var optionsFilters = [["${valueFieldKey}", optionsFiltersOp, []]];
6281
6372
  if (defaultValue && !api.data.$term) {
6373
+ const defaultValueOptionsQueryData = ${JSON.stringify(defaultValueOptionsQueryData)};
6374
+ const defaultValueOptionsQuery = defaultValueOptionsQueryData?.query?.replace(/^{/,"").replace(/}$/,"");
6282
6375
  // 字段值单独请求,没值的时候在请求中返回空
6283
6376
  optionsFilters = [["${valueFieldKey}", optionsFiltersOp, defaultValue]];
6284
6377
  if(filters.length > 0){
6285
6378
  optionsFilters = [filters, optionsFilters];
6286
6379
  }
6380
+ if(defaultValueOptionsQuery){
6381
+ api.data.query = "{"+api.data.query.replace(/^{/,"").replace(/}$/,"")+","+defaultValueOptionsQuery+"}";
6382
+ }
6287
6383
  }
6288
6384
  api.data.query = api.data.query.replace(/{__options_filters}/g, JSON.stringify(optionsFilters));
6289
6385
  return api;
@@ -6325,7 +6421,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6325
6421
  disabledOn: `${readonly} || ( (this._master && (this._master.relatedKey ==='${field.name}')) || ((this.relatedKey ==='${field.name}') && (${field.multiple} != true)) )`,
6326
6422
  // labelField: labelField,
6327
6423
  // valueField: valueField,
6328
- source: apiInfo,
6424
+ // source: apiInfo,
6329
6425
  autoComplete: apiInfo,
6330
6426
  searchable: true,
6331
6427
  };
@@ -6404,10 +6500,10 @@ async function lookupToAmis(field, readonly, ctx){
6404
6500
 
6405
6501
  const refObject = await getUISchema(referenceTo.objectName);
6406
6502
 
6407
- // 此处不参考 steedos 的 enable_enhanced_lookup 规则. 如果默认是开启弹出选择,用户选择过程操作太繁琐, 所以默认是关闭弹出选择.
6408
- // 由于amis picker 目前不支持联动, 配置了depend_on时, 使用使用select ,以支持联动
6409
- // TODO: 确认 amis picker 支持联动时, 清理field.depend_on判断
6410
- if(refObject.enable_enhanced_lookup == true && _$1.isEmpty(field.depend_on)){
6503
+ // 优先取字段中配置的enable_enhanced_lookup,字段上没配置时,才从对象上取enable_enhanced_lookup属性
6504
+ let enableEnhancedLookup = _$1.isBoolean(field.enable_enhanced_lookup) ? field.enable_enhanced_lookup : refObject.enable_enhanced_lookup;
6505
+ // 默认使用下拉框模式显示lookup选项,只能配置了enable_enhanced_lookup才使用弹出增强模式
6506
+ if(enableEnhancedLookup == true){
6411
6507
  return await lookupToAmisPicker(field, readonly, ctx);
6412
6508
  }else if(refObject.enable_tree) {
6413
6509
  return await lookupToAmisTreeSelect(field, readonly, Object.assign({}, ctx, {
@@ -6724,8 +6820,8 @@ function getAmisStaticFieldType(type, readonly, options){
6724
6820
  /*
6725
6821
  * @Author: baozhoutao@steedos.com
6726
6822
  * @Date: 2022-10-28 14:15:09
6727
- * @LastEditors: baozhoutao@steedos.com
6728
- * @LastEditTime: 2022-11-02 18:06:16
6823
+ * @LastEditors: liaodaxue
6824
+ * @LastEditTime: 2023-10-30 17:51:54
6729
6825
  * @Description:
6730
6826
  */
6731
6827
 
@@ -6776,11 +6872,26 @@ const getAmisFileEditSchema = (steedosField)=>{
6776
6872
  useChunk: false, // 关闭分块上传
6777
6873
  receiver: {
6778
6874
  method: "post",
6875
+ dataType: "form-data",
6779
6876
  url: `\${context.rootUrl}/s3/${tableName}`,
6780
- data: {
6781
- $: "$$",
6782
- context: `\${context}`,
6783
- },
6877
+ requestAdaptor: `
6878
+ const { _master, global,context } = api.body;
6879
+ // const { recordId, objectName } = _master;
6880
+ const { spaceId, userId, user } = global;
6881
+ /*
6882
+ record_id: recordId,
6883
+ parent: recordId,
6884
+ object_name: objectName,
6885
+ owner_name: user.name,
6886
+ space: spaceId,
6887
+ owner: userId
6888
+ */
6889
+ // 参考platform 2.2版本,附件字段保存时cfs.files.filerecord、cfs.images.filerecord表中的metadata下只保存space、owner两个属性值。
6890
+ api.data.append('space', spaceId);
6891
+ api.data.append('owner', userId);
6892
+
6893
+ return api;
6894
+ `,
6784
6895
  adaptor: `
6785
6896
  const { context } = api.body;
6786
6897
  var rootUrl = context.rootUrl + "/api/files/${tableName}/";
@@ -6966,8 +7077,6 @@ function getSelectFieldOptions(field){
6966
7077
  }
6967
7078
 
6968
7079
  async function convertSFieldToAmisField(field, readonly, ctx) {
6969
- // console.log('convertSFieldToAmisField====>', field, readonly, ctx)
6970
- const isMobile = window.innerWidth <= 768;
6971
7080
  // 创建人和修改人、创建时间和修改时间不显示
6972
7081
  if(_$1.includes(OMIT_FIELDS, field.name) && ctx.showSystemFields != true){
6973
7082
  return;
@@ -7056,26 +7165,33 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7056
7165
  };
7057
7166
  break;
7058
7167
  case 'date':
7059
- convertData = isMobile && !readonly ? {
7060
- type: "native-date",
7061
- pipeIn: (value, data) => {
7062
- if (value) {
7063
- value = moment(value).utc().format('YYYY-MM-DD');
7064
- return value;
7065
- } else {
7066
- return "";
7067
- }
7068
-
7069
- },
7070
- pipeOut: (value, oldValue, data) => {
7071
- if (value) {
7072
- value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7073
- return value;
7074
- } else {
7075
- return "";
7076
- }
7077
- }
7078
- } : {
7168
+ // convertData = isMobile && !readonly ? {
7169
+ // type: "native-date",
7170
+ // pipeIn: (value, data) => {
7171
+ // if (value) {
7172
+ // value = moment(value).utc().format('YYYY-MM-DD');
7173
+ // return value;
7174
+ // } else {
7175
+ // return "";
7176
+ // }
7177
+
7178
+ // },
7179
+ // pipeOut: (value, oldValue, data) => {
7180
+ // if (value) {
7181
+ // value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7182
+ // return value;
7183
+ // } else {
7184
+ // return "";
7185
+ // }
7186
+ // }
7187
+ // } : {
7188
+ // type: getAmisStaticFieldType('date', readonly),
7189
+ // inputFormat: "YYYY-MM-DD",
7190
+ // format:'YYYY-MM-DDT00:00:00.000[Z]',
7191
+ // tpl: readonly ? Tpl.getDateTpl(field) : null,
7192
+ // // utc: true
7193
+ // }
7194
+ convertData = {
7079
7195
  type: getAmisStaticFieldType('date', readonly),
7080
7196
  inputFormat: "YYYY-MM-DD",
7081
7197
  format:'YYYY-MM-DDT00:00:00.000[Z]',
@@ -7094,43 +7210,51 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7094
7210
  };
7095
7211
  break;
7096
7212
  case 'datetime':
7097
- convertData = isMobile && !readonly ? {
7098
- type: "combo",
7099
- pipeIn: (value, data) => {
7100
- let revalue = {};
7101
- if (value && value != "Invalid date") {
7102
- value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7103
- revalue[field.name + "-native-date"] = value.split(' ')[0];
7104
- revalue[field.name + "-native-time"] = value.split(' ')[1];
7105
- } else {
7106
- revalue[field.name + "-native-date"] = "";
7107
- revalue[field.name + "-native-time"] = "";
7108
- }
7109
- return revalue;
7110
- },
7111
- pipeOut: (value, oldValue, data) => {
7112
- let revalue = "";
7113
- if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7114
- revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7115
- revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7116
- }
7117
- return revalue;
7118
- },
7119
- items: [
7120
- {
7121
- type: "native-date",
7122
- name: field.name + "-native-date",
7123
- className: "steedos-native-date",
7124
- value: ""
7125
- },
7126
- {
7127
- type: "native-time",
7128
- name: field.name + "-native-time",
7129
- className: "steedos-native-time",
7130
- value: ""
7131
- }
7132
- ]
7133
- } : {
7213
+ // convertData = isMobile && !readonly ? {
7214
+ // type: "combo",
7215
+ // pipeIn: (value, data) => {
7216
+ // let revalue = {};
7217
+ // if (value && value != "Invalid date") {
7218
+ // value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7219
+ // revalue[field.name + "-native-date"] = value.split(' ')[0];
7220
+ // revalue[field.name + "-native-time"] = value.split(' ')[1];
7221
+ // } else {
7222
+ // revalue[field.name + "-native-date"] = "";
7223
+ // revalue[field.name + "-native-time"] = "";
7224
+ // }
7225
+ // return revalue;
7226
+ // },
7227
+ // pipeOut: (value, oldValue, data) => {
7228
+ // let revalue = "";
7229
+ // if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7230
+ // revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7231
+ // revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7232
+ // }
7233
+ // return revalue;
7234
+ // },
7235
+ // items: [
7236
+ // {
7237
+ // type: "native-date",
7238
+ // name: field.name + "-native-date",
7239
+ // className: "steedos-native-date",
7240
+ // value: ""
7241
+ // },
7242
+ // {
7243
+ // type: "native-time",
7244
+ // name: field.name + "-native-time",
7245
+ // className: "steedos-native-time",
7246
+ // value: ""
7247
+ // }
7248
+ // ]
7249
+ // } : {
7250
+ // type: getAmisStaticFieldType('datetime', readonly),
7251
+ // inputFormat: 'YYYY-MM-DD HH:mm',
7252
+ // format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
7253
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7254
+ // utc: true,
7255
+ // }
7256
+
7257
+ convertData = {
7134
7258
  type: getAmisStaticFieldType('datetime', readonly),
7135
7259
  inputFormat: 'YYYY-MM-DD HH:mm',
7136
7260
  format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
@@ -7150,26 +7274,34 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7150
7274
  };
7151
7275
  break;
7152
7276
  case 'time':
7153
- convertData = isMobile && !readonly ? {
7154
- type: "native-time",
7155
- pipeIn: (value, data) => {
7156
- if (value) {
7157
- value = moment(value).utc().format('HH:mm');
7158
- return value;
7159
- } else {
7160
- return "";
7161
- }
7162
-
7163
- },
7164
- pipeOut: (value, oldValue, data) => {
7165
- if (value) {
7166
- value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7167
- return value;
7168
- } else {
7169
- return "";
7170
- }
7171
- }
7172
- } : {
7277
+ // convertData = isMobile && !readonly ? {
7278
+ // type: "native-time",
7279
+ // pipeIn: (value, data) => {
7280
+ // if (value) {
7281
+ // value = moment(value).utc().format('HH:mm');
7282
+ // return value;
7283
+ // } else {
7284
+ // return "";
7285
+ // }
7286
+
7287
+ // },
7288
+ // pipeOut: (value, oldValue, data) => {
7289
+ // if (value) {
7290
+ // value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7291
+ // return value;
7292
+ // } else {
7293
+ // return "";
7294
+ // }
7295
+ // }
7296
+ // } : {
7297
+ // type: getAmisStaticFieldType('time', readonly),
7298
+ // inputFormat: 'HH:mm',
7299
+ // timeFormat:'HH:mm',
7300
+ // format:'1970-01-01THH:mm:00.000[Z]',
7301
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7302
+ // // utc: true
7303
+ // }
7304
+ convertData = {
7173
7305
  type: getAmisStaticFieldType('time', readonly),
7174
7306
  inputFormat: 'HH:mm',
7175
7307
  timeFormat:'HH:mm',
@@ -7219,7 +7351,20 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7219
7351
  type: getAmisStaticFieldType('number', readonly),
7220
7352
  min: field.min,
7221
7353
  max: field.max,
7222
- precision: field.scale
7354
+ precision: field.scale,
7355
+ suffix: "%",
7356
+ pipeIn: (value, data) => {
7357
+ if(value){
7358
+ return value*100;
7359
+ }
7360
+ return value;
7361
+ },
7362
+ pipeOut: (value, oldValue, data) => {
7363
+ if(value){
7364
+ return value/100;
7365
+ }
7366
+ return value;
7367
+ },
7223
7368
  };
7224
7369
  }
7225
7370
  break;
@@ -7631,8 +7776,41 @@ var config = {
7631
7776
  };
7632
7777
 
7633
7778
  async function getQuickEditSchema(field, options){
7634
- const quickEditId = options.objectName + "_" + field.name + "QuickEdit";//定义快速编辑的表单id,用于setvalue传值
7779
+ //判断在amis3.2以上环境下,放开批量编辑
7780
+ const isAmisVersionforBatchEdit = amisRequire('amis').version[0] >= 3 && amisRequire('amis').version[2] >= 2;
7781
+ const quickEditId = options.objectName + "_" + field.name + "_quickEdit";//定义快速编辑的表单id,用于setvalue传值
7635
7782
  var quickEditSchema = { body: [], id: quickEditId };
7783
+ //select,avatar,image,file等组件无法行记录字段赋值,暂不支持批量编辑;
7784
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
7785
+ const submitEvent = {
7786
+ submit: {
7787
+ actions: [
7788
+ {
7789
+ actionType: "custom",
7790
+ script: `
7791
+ let items = _.cloneDeep(event.data.items);
7792
+ let selectedItems = _.cloneDeep(event.data.selectedItems);
7793
+ if(event.data.isBatchEdit){
7794
+ selectedItems.forEach(function(selectedItem){
7795
+ selectedItem._display.${field.name} = event.data._display.${field.name};
7796
+ doAction({actionType: 'setValue', "args": {"value": selectedItem._display},componentId: "_display_" + selectedItem._index});
7797
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + selectedItem._index});
7798
+ })
7799
+ }else{
7800
+ doAction({actionType: 'setValue', "args": {"value": event.data._display},componentId: "_display_" + event.data._index});
7801
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + event.data._index});
7802
+ }
7803
+ `
7804
+ },
7805
+ {
7806
+ "actionType": "closeDialog"
7807
+ }
7808
+ ]
7809
+ }
7810
+ };
7811
+ quickEditSchema.onEvent = submitEvent;
7812
+ }
7813
+
7636
7814
  if (field.disabled) {
7637
7815
  quickEditSchema = false;
7638
7816
  } else {
@@ -7649,7 +7827,7 @@ async function getQuickEditSchema(field, options){
7649
7827
  {
7650
7828
  "actionType": "custom",
7651
7829
  "script": `
7652
- var _display = event.data._display;
7830
+ var _display = _.cloneDeep(event.data._display);
7653
7831
  ${displayField}
7654
7832
  doAction({actionType: 'setValue', "args": {"value": {_display}},componentId: "${quickEditId}"});
7655
7833
  `
@@ -7671,7 +7849,7 @@ async function getQuickEditSchema(field, options){
7671
7849
  第二种是增加选项时,按照value的值,找到对应选项,并按照_display的规则为其赋值
7672
7850
  */
7673
7851
  TempDisplayField = `
7674
- const preData = event.data.__super.${field.name};
7852
+ const preData = _.cloneDeep(event.data.__super.${field.name});
7675
7853
  if(preData && event.data.${field.name}.length < preData.length){
7676
7854
  let deletedIndex;
7677
7855
  preData.forEach(function(item,index){
@@ -7715,7 +7893,7 @@ async function getQuickEditSchema(field, options){
7715
7893
  break;
7716
7894
  case "percent":
7717
7895
  TempDisplayField = `
7718
- _display["${field.name}"] = (event.data.value * 100).toFixed(${field.scale}) + '%';
7896
+ _display["${field.name}"] = event.data.value.toFixed(${field.scale}) + '%';
7719
7897
  `;
7720
7898
  quickEditSchema.body[0].onEvent["change"] = quickEditOnEvent(TempDisplayField);
7721
7899
  break;
@@ -7866,6 +8044,131 @@ async function getQuickEditSchema(field, options){
7866
8044
  }
7867
8045
 
7868
8046
  });
8047
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
8048
+ quickEditSchema.body.push({
8049
+ "name": "isBatchEdit",
8050
+ "type": "checkbox",
8051
+ "option": [
8052
+ {
8053
+ "type": "tpl",
8054
+ "tpl": "更新${COUNT(selectedItems)}个选定记录"
8055
+ },
8056
+ {
8057
+ "type": "spinner",
8058
+ "showOn": "${batchPermissionLoading}",
8059
+ "size": "sm",
8060
+ "className": "mr-4"
8061
+ }
8062
+ ],
8063
+ "visibleOn": "${ARRAYSOME(selectedItems, item => item._id === _id) && COUNT(selectedItems)>1 && quickedit_record_permissions.allowEdit && quickedit_record_permissions_loading == false}",
8064
+ "disabledOn": "${batchPermissionLoading}",
8065
+ "onEvent":{
8066
+ "change":{
8067
+ "actions":[
8068
+ {
8069
+ "actionType": "setValue",
8070
+ "componentId": quickEditId,
8071
+ "args": {
8072
+ "value":{
8073
+ "batchPermissionLoading": true
8074
+ }
8075
+ },
8076
+ "expression":"${event.data.value}"
8077
+ },
8078
+ {
8079
+ "actionType": "ajax",
8080
+ "args": {
8081
+ "api": {
8082
+ "url": "${context.rootUrl}/graphql",
8083
+ "method": "post",
8084
+ "headers": {
8085
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
8086
+ },
8087
+ "data": {
8088
+ "query": "{rows:${objectName}(filters:[\"_id\",\"in\",${selectedItems | pick:_id | split | json}]){_id,_permissions{allowEdit}}}"
8089
+ },
8090
+ "adaptor": `
8091
+ const noPermission = [];
8092
+ payload.data.rows.forEach(function (row) {
8093
+ if(!row._permissions.allowEdit){
8094
+ noPermission.push(row._id);
8095
+ }
8096
+ })
8097
+ payload.data.noPermission = noPermission;
8098
+ return payload;
8099
+ `
8100
+ }
8101
+ },
8102
+ "expression":"${event.data.value}"
8103
+ },
8104
+ {
8105
+ "actionType": "setValue",
8106
+ "componentId": quickEditId,
8107
+ "args": {
8108
+ "value":{
8109
+ "batchPermissionLoading": false
8110
+ }
8111
+ },
8112
+ "expression":"${event.data.value}"
8113
+ },
8114
+ {
8115
+ "actionType": "dialog",
8116
+ "dialog":{
8117
+ "title": "记录权限",
8118
+ "showCloseButton": false,
8119
+ "body":[
8120
+ {
8121
+ "type": "tpl",
8122
+ "tpl": "当前选中记录中,有${COUNT(noPermission)}条记录无编辑权限,是否需要批量编辑其他记录?"
8123
+ }
8124
+ ],
8125
+ "onEvent":{
8126
+ "confirm":{
8127
+ "actions":[
8128
+ {
8129
+ "actionType": "custom",
8130
+ "script": `
8131
+ const noPermission = event.data.noPermission;
8132
+ const crudComponent = event.context.scoped.getComponentById("${options.crudId}");
8133
+ const selectedItems = crudComponent && crudComponent.props.store.selectedItems.concat();
8134
+ noPermission.forEach(function (item) {
8135
+ crudComponent && crudComponent.unSelectItem(_.find(selectedItems,{_id:item}));
8136
+ })
8137
+ `
8138
+ },
8139
+ {
8140
+ "actionType": "setValue",
8141
+ "componentId": quickEditId,
8142
+ "args": {
8143
+ "value":{
8144
+ "isBatchEdit": true
8145
+ }
8146
+ },
8147
+ }
8148
+ ]
8149
+ },
8150
+ "cancel":{
8151
+ "actions":[
8152
+ {
8153
+ "actionType": "setValue",
8154
+ "componentId": quickEditId,
8155
+ "args": {
8156
+ "value":{
8157
+ "isBatchEdit": false
8158
+ }
8159
+ },
8160
+ }
8161
+ ]
8162
+ }
8163
+ }
8164
+ },
8165
+ "expression":"${COUNT(event.data.noPermission)>0}"
8166
+ }
8167
+ ]
8168
+ }
8169
+ }
8170
+ });
8171
+ }
7869
8172
  } else {
7870
8173
  quickEditSchema = false;
7871
8174
  }
@@ -7900,6 +8203,8 @@ async function getTableColumns(fields, options){
7900
8203
  const columns = [];
7901
8204
  if(!options.isLookup){
7902
8205
  columns.push({name: '_index',type: 'text', width: 32, placeholder: ""});
8206
+ //将_display放入crud的columns中,可以通过setvalue修改行内数据域的_display,而不影响上层items的_display,用于批量编辑
8207
+ columns.push({name: '_display',type: 'static', width: 32, placeholder: "",id: "_display_${_index}", className: "hidden"});
7903
8208
  }
7904
8209
  const allowEdit = options.permissions?.allowEdit && !options.isLookup && options.enable_inline_edit != false;
7905
8210
 
@@ -7931,7 +8236,7 @@ async function getTableColumns(fields, options){
7931
8236
  {
7932
8237
  "args": {
7933
8238
  "api": {
7934
- "url": "${context.rootUrl}/api/files/files/${versions[0]}?download=true",
8239
+ "url": "${(versions[0] && versions[0].url) ? versions[0].url+'?download=true' : context.rootUrl+'/api/files/files/'+versions[0]+'?download=true'}",
7935
8240
  "method": "get",
7936
8241
  "headers": {
7937
8242
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
@@ -7978,7 +8283,7 @@ async function getTableColumns(fields, options){
7978
8283
  else if(field.type === 'select'){
7979
8284
  const map = getSelectMap(field.options);
7980
8285
  columnItem = Object.assign({}, {
7981
- type: "mapping",
8286
+ type: "static-mapping",
7982
8287
  name: field.name,
7983
8288
  label: field.label,
7984
8289
  map: map,
@@ -7993,7 +8298,7 @@ async function getTableColumns(fields, options){
7993
8298
  const tpl = await getFieldTpl(field, options);
7994
8299
  let type = 'text';
7995
8300
  if(tpl){
7996
- type = 'tpl';
8301
+ type = 'static';
7997
8302
  }else if(field.type === 'html'){
7998
8303
  type = 'markdown';
7999
8304
  }else if(field.type === 'url'){
@@ -8034,6 +8339,7 @@ async function getTableColumns(fields, options){
8034
8339
  columnItem.quickEdit = quickEditSchema;
8035
8340
  columnItem.quickEditEnabledOn = "${is_system !== true}";
8036
8341
  }
8342
+ columnItem.id = `${options.objectName}_${field.name}_\${_index}`;
8037
8343
  columns.push(columnItem);
8038
8344
  }
8039
8345
  }
@@ -8312,7 +8618,7 @@ async function getTableOperation(ctx){
8312
8618
  }
8313
8619
  return {
8314
8620
  type: 'operation',
8315
- label: i18next.t('frontend_operation'),
8621
+ label: "",
8316
8622
  fixed: 'right',
8317
8623
  labelClassName: 'text-center',
8318
8624
  className: 'text-center steedos-listview-operation w-10',
@@ -8346,23 +8652,87 @@ async function getTableOperation(ctx){
8346
8652
  }
8347
8653
  }
8348
8654
 
8655
+ async function getDefaultCrudCard(columns, options) {
8656
+ let labelFieldName = options?.labelFieldName || "name";
8657
+ let titleColumn, bodyColumns = [];
8658
+ columns.forEach(function (item) {
8659
+ delete item.quickEdit;
8660
+ delete item.width;
8661
+ if (item.name === labelFieldName) {
8662
+ titleColumn = item;
8663
+ }
8664
+ else {
8665
+ if (item.name !== "_index") {
8666
+ bodyColumns.push(item);
8667
+ }
8668
+ }
8669
+ });
8670
+ let card = {
8671
+ "header": {
8672
+ "title": titleColumn.tpl
8673
+ },
8674
+ body: bodyColumns,
8675
+ // useCardLabel: false,
8676
+ toolbar: []
8677
+ };
8678
+ let hideToolbarOperation = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8679
+ if(!hideToolbarOperation){
8680
+ let toolbarOperation = await getTableOperation(options);
8681
+ if (toolbarOperation) {
8682
+ toolbarOperation.className += " inline-block w-auto";
8683
+ }
8684
+ card.toolbar.push(toolbarOperation);
8685
+ }
8686
+ return card;
8687
+ }
8688
+
8349
8689
  async function getTableSchema$1(fields, options){
8350
8690
  if(!options){
8351
8691
  options = {};
8352
8692
  }
8353
8693
  let { isLookup, hiddenColumnOperation } = options;
8694
+ const defaults = options.defaults;
8695
+ const listSchema = (defaults && defaults.listSchema) || {};
8696
+
8354
8697
  let columns = [];
8355
8698
  let useMobileColumns = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8356
8699
  if(isLookup){
8357
8700
  // 在lookup手机端列表模式调式好之前不使用getMobileTableColumns
8358
8701
  useMobileColumns = false;
8359
8702
  }
8703
+ if(listSchema.mode && listSchema.mode !== "table"){
8704
+ // 如果指定的mode,则不走我们内置的手机端列表效果,使用steedos组件内部开发的默认card/list效果,或者由用户自己实现card/list模式的crud列表
8705
+ useMobileColumns = false;
8706
+ }
8360
8707
  if(useMobileColumns){
8361
8708
  columns = await getMobileTableColumns(fields, options);
8362
8709
  }
8363
8710
  else {
8364
8711
  columns = await getTableColumns(fields, options);
8365
8712
 
8713
+ if(listSchema.mode === "cards"){
8714
+ let card = listSchema.card;
8715
+ if(!card){
8716
+ card = await getDefaultCrudCard(columns, options);
8717
+ }
8718
+ return {
8719
+ mode: "cards",
8720
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8721
+ name: "thelist",
8722
+ headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8723
+ className: "",
8724
+ draggable: false,
8725
+ defaultParams: getDefaultParams(options),
8726
+ card: card,
8727
+ syncLocation: false,
8728
+ keepItemSelectionOnPageChange: true,
8729
+ checkOnItemClick: isLookup ? true : false,
8730
+ labelTpl: `\${${options.labelFieldName}}`,
8731
+ autoFillHeight: false, // 自动高度效果不理想,先关闭
8732
+ columnsTogglable: false
8733
+ }
8734
+ }
8735
+
8366
8736
  if(!isLookup && !hiddenColumnOperation){
8367
8737
  columns.push(await getTableOperation(options));
8368
8738
  }
@@ -8370,6 +8740,7 @@ async function getTableSchema$1(fields, options){
8370
8740
 
8371
8741
  return {
8372
8742
  mode: "table",
8743
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8373
8744
  name: "thelist",
8374
8745
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8375
8746
  className: "",
@@ -8840,18 +9211,30 @@ function getReadonlyFormAdaptor(object, fields, options){
8840
9211
  payload.status = 2;
8841
9212
  payload.msg = payload.errors[0].message;
8842
9213
  }
9214
+ ${options && options.initApiAdaptor || ''}
8843
9215
  return payload;
8844
9216
  `
8845
9217
  }
8846
9218
 
8847
9219
  async function getReadonlyFormInitApi(object, recordId, fields, options){
9220
+ let findOneOptions;
9221
+ if (!recordId && options && options.isEditor) {
9222
+ // 设计器中只读表单返回第一条记录
9223
+ findOneOptions = {
9224
+ filters: [],
9225
+ queryOptions: "top: 1"
9226
+ };
9227
+ }
8848
9228
  return {
8849
9229
  method: "post",
8850
9230
  url: getApi$2() + '&objectName=${objectName}' + "&recordId=${recordId}",
8851
9231
  cache: API_CACHE,
8852
- // requestAdaptor: "console.log('getReadonlyFormInitApi requestAdaptor', api);return api;",
9232
+ requestAdaptor: `
9233
+ ${options && options.initApiRequestAdaptor || ''}
9234
+ return api;
9235
+ `,
8853
9236
  adaptor: getReadonlyFormAdaptor(object, fields, options),
8854
- data: await getFindOneQuery$1(object, recordId, fields, options),
9237
+ data: await getFindOneQuery$1(object, recordId, fields, findOneOptions),
8855
9238
  headers: {
8856
9239
  Authorization: "Bearer ${context.tenantId},${context.authToken}"
8857
9240
  }
@@ -8992,7 +9375,7 @@ async function getEditFormInitApi(object, recordId, fields, options){
8992
9375
  ${getScriptForRewriteValueForFileFields(fields)}
8993
9376
 
8994
9377
  _.each(dataKeys, function(key){
8995
- if(fieldKeys.indexOf(key)<0){
9378
+ if(fieldKeys.indexOf(key)<0 && key !== "_display"){
8996
9379
  delete data[key];
8997
9380
  }
8998
9381
  })
@@ -9167,6 +9550,8 @@ async function getCalendarApi(mainObject, fields, options) {
9167
9550
 
9168
9551
  if(api.data.$self.additionalFilters){
9169
9552
  filters.push(api.data.$self.additionalFilters)
9553
+ }else if(api.data.$self.event.data.additionalFilters){
9554
+ filters.push(api.data.$self.event.data.additionalFilters)
9170
9555
  }
9171
9556
 
9172
9557
  var pageSize = api.data.pageSize || 10;
@@ -9492,6 +9877,7 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9492
9877
  businessHours.endTime = `${calendarOptions.endDayHour}:00`;
9493
9878
  }
9494
9879
 
9880
+ // api.trackExpression="\\\${additionalFilters}";
9495
9881
  const onEvent = {
9496
9882
  "getEvents": {
9497
9883
  "weight": 0,
@@ -9503,6 +9889,22 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9503
9889
  "actionType": "custom",
9504
9890
  "script": onGetEventsScript
9505
9891
  }
9892
+ // {
9893
+ // "actionType": "ajax",
9894
+ // "outputVar": "responseResult",
9895
+ // "args": {
9896
+ // "options": {
9897
+ // },
9898
+ // "api": api
9899
+ // // {
9900
+ // // "url": "111",
9901
+ // // "method": "post",
9902
+ // // "data": {
9903
+ // // "calendarOptions": JSON.stringify(calendarOptions);
9904
+ // // }
9905
+ // // }
9906
+ // }
9907
+ // }
9506
9908
  ]
9507
9909
  },
9508
9910
  "select": {
@@ -9826,7 +10228,7 @@ function deleteVariable(data, key) {
9826
10228
  * @Author: baozhoutao@steedos.com
9827
10229
  * @Date: 2022-05-26 16:02:08
9828
10230
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
9829
- * @LastEditTime: 2023-09-15 15:36:17
10231
+ * @LastEditTime: 2023-10-12 18:25:05
9830
10232
  * @Description:
9831
10233
  */
9832
10234
 
@@ -9846,8 +10248,9 @@ const getFieldSchemaArray = (formFields, ctx) => {
9846
10248
  }
9847
10249
 
9848
10250
  let forceHidden = false;
9849
- if(!recordId && field.readonly){
10251
+ if(!recordId && field.readonly && !ctx.isEditor){
9850
10252
  // 新建记录时,只读字段先隐藏,后续支持显示后,即任务:https://github.com/steedos/steedos-platform/issues/3164 完成后再放开
10253
+ // 表单只读时所有字段都是readonly,设计器中如果forceHidden会造成整个表单在只读的时候显示为空白了,所以要排除掉
9851
10254
  forceHidden = true;
9852
10255
  }
9853
10256
 
@@ -10089,6 +10492,9 @@ async function getObjectCRUD(objectSchema, fields, options){
10089
10492
  const nonpaged = objectSchema.paging && objectSchema.paging.enabled === false;
10090
10493
  const isTreeObject = objectSchema.enable_tree;
10091
10494
  const bulkActions = getBulkActions(objectSchema);
10495
+ const defaults = options.defaults;
10496
+ const listSchema = (defaults && defaults.listSchema) || {};
10497
+
10092
10498
  const bodyProps = {
10093
10499
  // toolbar: getToolbar(),
10094
10500
  // headerToolbar: getObjectHeaderToolbar(objectSchema, options.formFactor, {showDisplayAs}),
@@ -10100,9 +10506,12 @@ async function getObjectCRUD(objectSchema, fields, options){
10100
10506
  filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, options),
10101
10507
  };
10102
10508
  if(options.formFactor !== 'SMALL' || ["split"].indexOf(options.displayAs) == -1){
10103
- Object.assign(bodyProps, {
10104
- bulkActions: options.bulkActions != false ? bulkActions : false
10105
- });
10509
+ if(listSchema.mode !== "cards"){
10510
+ // card模式时默认不显示勾选框
10511
+ Object.assign(bodyProps, {
10512
+ bulkActions: options.bulkActions != false ? bulkActions : false
10513
+ });
10514
+ }
10106
10515
  }
10107
10516
  // yml里配置的 不分页和enable_tree:true 优先级最高,组件中输入的top次之。
10108
10517
  options.queryCount = true;
@@ -10161,17 +10570,19 @@ async function getObjectCRUD(objectSchema, fields, options){
10161
10570
  }
10162
10571
  let tableOptions = Object.assign({
10163
10572
  idFieldName: objectSchema.idFieldName, labelFieldName: labelFieldName,
10164
- permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit
10573
+ permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit,
10574
+ crudId: listSchema.id || id
10165
10575
  }, options);
10166
10576
  tableOptions.amisData = createObject(options.amisData || {}, {});
10167
10577
  const table = await getTableSchema$1(fields, tableOptions);
10168
- delete table.mode;
10578
+ // delete table.mode;
10169
10579
  //image与avatar需要在提交修改时特别处理
10170
10580
  const imageNames = ___default.compact(___default.map(___default.filter(fields, (field) => ["image","avatar"].includes(field.type)), 'name'));
10171
10581
  const quickSaveApiRequestAdaptor = `
10172
10582
  var graphqlOrder = "";
10173
10583
  var imageNames = ${JSON.stringify(imageNames)};
10174
- api.data.rowsDiff.forEach(function (item, index) {
10584
+ const rowsDiff = _.cloneDeep(api.data.rowsDiff);
10585
+ rowsDiff.forEach(function (item, index) {
10175
10586
  for(key in item){
10176
10587
  if(_.includes(imageNames, key)){
10177
10588
  if(typeof item[key] == "string"){
@@ -10185,6 +10596,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10185
10596
  }
10186
10597
  }
10187
10598
  }
10599
+ item = _.omit(item, '_display');
10188
10600
  const itemOrder = 'update' + index + ':' + api.data.objectName + '__update(id:"' + item._id + '", doc:' + JSON.stringify(JSON.stringify(_.omit(item, '_id'))) + ') {_id}';
10189
10601
  graphqlOrder += itemOrder;
10190
10602
  })
@@ -10235,12 +10647,14 @@ async function getObjectCRUD(objectSchema, fields, options){
10235
10647
 
10236
10648
  }
10237
10649
 
10238
- const defaults = options.defaults;
10239
-
10240
- const listSchema = (defaults && defaults.listSchema) || {};
10241
10650
  body = defaultsDeep({}, listSchema, body);
10242
10651
  body = await getCrudSchemaWithDataFilter(body, { crudDataFilter, onCrudDataFilter, amisData, env });
10243
10652
 
10653
+ let crudModeClassName = "";
10654
+ if(body.mode){
10655
+ crudModeClassName = `steedos-crud-mode-${body.mode}`;
10656
+ }
10657
+
10244
10658
  if (defaults) {
10245
10659
  const headerSchema = defaults.headerSchema;
10246
10660
  const footerSchema = defaults.footerSchema;
@@ -10269,7 +10683,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10269
10683
  // TODO: data应该只留loaded,其他属性都改为从上层传递下来
10270
10684
  return {
10271
10685
  type: 'service',
10272
- className: '',
10686
+ className: crudModeClassName,
10273
10687
  //目前crud的service层id不认用户自定义id,只支持默认规则id,许多地方的格式都写死了service_listview_${objectname}
10274
10688
  id: `service_${id}`,
10275
10689
  name: `page`,
@@ -10323,8 +10737,29 @@ const getFormFields = (objectSchema, formProps)=>{
10323
10737
  return lodash.sortBy(___default.values(fields), "sort_no");
10324
10738
  };
10325
10739
 
10740
+ async function getFormSchemaWithDataFilter(form, options = {}){
10741
+ const { formDataFilter, amisData, env } = options;
10742
+ let onFormDataFilter = options.onFormDataFilter;
10743
+ if (!onFormDataFilter && typeof formDataFilter === 'string') {
10744
+ onFormDataFilter = new Function(
10745
+ 'form',
10746
+ 'env',
10747
+ 'data',
10748
+ formDataFilter
10749
+ );
10750
+ }
10751
+
10752
+ try {
10753
+ onFormDataFilter && (form = await onFormDataFilter(form, env, amisData) || form);
10754
+ } catch (e) {
10755
+ console.warn(e);
10756
+ }
10757
+ return form;
10758
+ }
10759
+
10326
10760
  async function getObjectForm(objectSchema, ctx){
10327
- const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults } = ctx;
10761
+ const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults, submitSuccActions = [],
10762
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10328
10763
  const fields = ___default.values(objectSchema.fields);
10329
10764
  const formFields = getFormFields(objectSchema, ctx);
10330
10765
  const formSchema = defaults && defaults.formSchema || {};
@@ -10341,7 +10776,8 @@ async function getObjectForm(objectSchema, ctx){
10341
10776
  name: `page_edit_${recordId}`,
10342
10777
  api: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
10343
10778
  data:{
10344
- editFormInited: false
10779
+ editFormInited: false,
10780
+ ...amisData
10345
10781
  },
10346
10782
  // data: {global: getGlobalData('edit'), recordId: recordId, objectName: objectSchema.name, context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10347
10783
  initApi: null,
@@ -10394,9 +10830,10 @@ async function getObjectForm(objectSchema, ctx){
10394
10830
  },
10395
10831
  "expression": `\${_master.objectName != '${objectSchema.name}' && _master.objectName}`
10396
10832
  },
10833
+ ...submitSuccActions,
10397
10834
  // {
10398
10835
  // "actionType": "custom",
10399
- // "script": "debugger;"
10836
+ // "script": `setTimeout(function(){doAction({'actionType': 'setValue','componentId': '${formSchema.id}','args': {'value': {'sort_no': 879}}})}, 300)`
10400
10837
  // },
10401
10838
  // {
10402
10839
  // "args": {},
@@ -10407,20 +10844,22 @@ async function getObjectForm(objectSchema, ctx){
10407
10844
  }
10408
10845
  })]
10409
10846
  };
10847
+ amisSchema.body[0] = await getFormSchemaWithDataFilter(amisSchema.body[0], { formDataFilter, onFormDataFilter, amisData, env });
10410
10848
  return amisSchema;
10411
10849
  }
10412
10850
 
10413
10851
  async function getObjectDetail(objectSchema, recordId, ctx){
10414
- const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, formInitProps } = ctx;
10852
+ const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign,
10853
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10415
10854
  const fields = ___default.values(objectSchema.fields);
10416
10855
  const formFields = getFormFields(objectSchema, ctx);
10417
10856
  const serviceId = `service_detail_page`;
10418
- return {
10857
+ const amisSchema = {
10419
10858
  type: 'service',
10420
10859
  name: `page_readonly_${recordId}`,
10421
10860
  id: serviceId,
10422
10861
  data: {global: getGlobalData('read'), context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10423
- api: await getReadonlyFormInitApi(objectSchema, recordId, fields, formInitProps),
10862
+ api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
10424
10863
  body: [
10425
10864
  {
10426
10865
  "type": "wrapper", //form 的 hiddenOn 会导致 form onEvent 异常, 使用wrapper包裹一次form,并在wrapper上控制显隐
@@ -10439,7 +10878,11 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10439
10878
  "formData": "$$"
10440
10879
  },
10441
10880
  wrapWithPanel: false,
10442
- body: await getFormBody(map(fields, (field)=>{field.readonly = true; return field;}), map(formFields, (field)=>{field.readonly = true; return field;}), Object.assign({}, ctx, {showSystemFields: true,fieldGroups: objectSchema.field_groups})),
10881
+ body: await getFormBody(
10882
+ map(fields, (field) => { field.readonly = true; return field; }),
10883
+ map(formFields, (field) => { field.readonly = true; return field; }),
10884
+ Object.assign({}, ctx, { showSystemFields: true, fieldGroups: objectSchema.field_groups })
10885
+ ),
10443
10886
  className: 'steedos-amis-form bg-white',
10444
10887
  actions: [], // 不显示表单默认的提交按钮
10445
10888
  onEvent: {
@@ -10493,7 +10936,10 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10493
10936
  ]
10494
10937
  }
10495
10938
  }
10496
- }
10939
+ };
10940
+
10941
+ amisSchema.body[0].body = await getFormSchemaWithDataFilter(amisSchema.body[0].body, { formDataFilter, onFormDataFilter, amisData, env });
10942
+ return amisSchema;
10497
10943
  }
10498
10944
 
10499
10945
  /*
@@ -10573,7 +11019,7 @@ const getRecordPermissions = async (objectName, recordId)=>{
10573
11019
  * @Author: baozhoutao@steedos.com
10574
11020
  * @Date: 2022-07-05 15:55:39
10575
11021
  * @LastEditors: liaodaxue
10576
- * @LastEditTime: 2023-09-25 17:18:08
11022
+ * @LastEditTime: 2023-10-23 15:55:46
10577
11023
  * @Description:
10578
11024
  */
10579
11025
 
@@ -10864,11 +11310,15 @@ async function getRelatedListSchema(
10864
11310
  ctx
10865
11311
  ) {
10866
11312
  const uiSchema = await getUISchema(objectName);
11313
+ if(!uiSchema){
11314
+ return {}
11315
+ }
11316
+ const listViewNames = map(uiSchema.list_views, 'name');
10867
11317
  const listView = find(
10868
11318
  uiSchema.list_views,
10869
11319
  (listView, name) => {
10870
- // 传入listViewName空值则取第一个
10871
- if(!listViewName){
11320
+ // 传入listViewName空值 或者 不存在 则取第一个
11321
+ if(!listViewName || listViewNames.indexOf(listViewName)<0){
10872
11322
  listViewName = name;
10873
11323
  }
10874
11324
  return name === listViewName || listView._id === listViewName;
@@ -10948,8 +11398,8 @@ async function getRelatedListSchema(
10948
11398
  /*
10949
11399
  * @Author: baozhoutao@steedos.com
10950
11400
  * @Date: 2022-07-05 15:55:39
10951
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
10952
- * @LastEditTime: 2023-09-21 17:35:06
11401
+ * @LastEditors: liaodaxue
11402
+ * @LastEditTime: 2023-10-20 11:38:25
10953
11403
  * @Description:
10954
11404
  */
10955
11405
 
@@ -11278,8 +11728,8 @@ async function getListSchema(
11278
11728
  "filtersFunction": listview_filters,
11279
11729
  "sort": sort,
11280
11730
  "ctx": ctx,
11281
- "requestAdaptor": listView.requestAdaptor,
11282
- "adaptor": listView.adaptor,
11731
+ "requestAdaptor": listView.requestAdaptor || ctx.requestAdaptor,
11732
+ "adaptor": listView.adaptor || ctx.adaptor,
11283
11733
  "headerToolbarItems": ctx.headerToolbarItems,
11284
11734
  "filterVisible": ctx.filterVisible,
11285
11735
  "rowClassNameExpr": ctx.rowClassNameExpr,
@@ -13924,10 +14374,18 @@ const getOpinionFieldStepsName = (field, top_keywords) => {
13924
14374
  * @Author: baozhoutao@steedos.com
13925
14375
  * @Date: 2022-09-09 17:47:37
13926
14376
  * @LastEditors: baozhoutao@steedos.com
13927
- * @LastEditTime: 2023-03-18 15:32:34
14377
+ * @LastEditTime: 2023-10-10 13:57:02
13928
14378
  * @Description:
13929
14379
  */
13930
14380
 
14381
+ const getMoment = ()=>{
14382
+ if(window.amisRequire){
14383
+ return window.amisRequire("moment");
14384
+ }else if(window.moment){
14385
+ return window.moment;
14386
+ }
14387
+ };
14388
+
13931
14389
  const getTrace = ({ instance, traceId }) => {
13932
14390
  return find(instance.traces, (trace) => {
13933
14391
  return trace._id === traceId;
@@ -14147,6 +14605,8 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14147
14605
  method: "get",
14148
14606
  });
14149
14607
 
14608
+ const moment = getMoment();
14609
+
14150
14610
  return {
14151
14611
  box: box,
14152
14612
  _id: instanceId,
@@ -14157,7 +14617,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14157
14617
  applicant_name: instance.applicant_name,
14158
14618
  submitter: instance.submitter,
14159
14619
  submit_date: instance.submit_date
14160
- ? amisRequire("moment")(instance.submit_date).format("YYYY-MM-DD")
14620
+ ? (moment && moment(instance.submit_date).format("YYYY-MM-DD"))
14161
14621
  : "",
14162
14622
  state: instance.state,
14163
14623
  approveValues: values,
@@ -14197,8 +14657,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14197
14657
  finishDate = approve.is_read ? "已读" : "未处理";
14198
14658
  judge = null;
14199
14659
  } else {
14200
- finishDate =
14201
- amisRequire("moment")(finishDate).format("YYYY-MM-DD HH:mm");
14660
+ finishDate = moment && moment(finishDate).format("YYYY-MM-DD HH:mm");
14202
14661
  }
14203
14662
 
14204
14663
  switch (judge) {
@@ -14251,5 +14710,5 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14251
14710
  };
14252
14711
  };
14253
14712
 
14254
- export { index as Field, Router, absoluteUrl, amisRender, amisRootClick, cloneObject, conditionsToFilters, createObject, defaultsDeep, deleteVariable, execute, executeButton, extendObject, fetchAPI, filtersToConditions, getApp, getApps, getAuthToken, getAuthorization, getButton, getButtonVisible, getButtonVisibleOn$1 as getButtonVisibleOn, getButtons, getCalendarSchema, getDefaultRenderData, getEnv, getEnvs, getEvn, getField, getFileSrc, getFlowFormSchema, getFormPageInitSchema, getFormSchema, getIdsPickerSchema, getImageSrc, getInstanceInfo, getListPageInitSchema, getListSchema, getListViewButtons, getListViewColumns, getListViewFilter, getListViewItemButtons, getListViewSort, getListviewInitSchema, getLookupSapceUserTreeSchema, getNotifications, getObjectDetailButtons, getObjectDetailButtonsSchemas, getObjectDetailMoreButtons, getObjectFieldsFilterBarSchema, getObjectFieldsFilterButtonSchema, getObjectFieldsFilterFormSchema, getObjectListHeader$1 as getObjectListHeader, getObjectListHeaderFieldsFilterBar, getObjectListHeaderFirstLine, getObjectListHeaderSecordLine, getObjectListViewButtonsSchemas, getObjectRecordDetailHeader, getObjectRecordDetailRelatedListButtonsSchemas, getObjectRecordDetailRelatedListHeader, getObjectRelated, getObjectRelatedList, getObjectRelatedListButtons, getObjectRelatedListHeader, getPage, getRecord, getRecordDetailHeaderSchema, getRecordDetailRelatedListSchema, getRecordDetailSchema, getRecordPageInitSchema, getRecordPermissions, getRecordServiceSchema, getReferenceTo, getRelatedFieldValue, getRelatedListSchema, getRelatedsCount, getRootUrl, getSelectUserSchema, getSpaceUsersPickerAmisSchema, getSpaceUsersPickerSchema, getSteedosAuth, getTableSchema, getTenantId, getUISchema, getUISchemaSync, getUserId, getViewSchema, isExpression, isObject, lookupToAmis, lookupToAmisIdsPicker, lookupToAmisPicker, lookupToAmisSelect, lookupToAmisSelectUser, markReadAll, parseSingleExpression, registerRemoteAssets, registerRenders, setEnv, setEnvs, setRootUrl, setSteedosAuth, setUISchemaFunction, setVariable, standardButtonsTodo };
14713
+ export { index as Field, Router, absoluteUrl, amisRender, amisRootClick, cloneObject, conditionsToFilters, createObject, defaultsDeep, deleteVariable, execute, executeButton, extendObject, fetchAPI, filtersToConditions, getApp, getApps, getAuthToken, getAuthorization, getButton, getButtonVisible, getButtonVisibleOn$1 as getButtonVisibleOn, getButtons, getCalendarSchema, getDefaultRenderData, getEnv, getEnvs, getEvn, getField, getFileSrc, getFlowFormSchema, getFormPageInitSchema, getFormSchema, getGlobalNowData, getIdsPickerSchema, getImageSrc, getInstanceInfo, getListPageInitSchema, getListSchema, getListViewButtons, getListViewColumns, getListViewFilter, getListViewItemButtons, getListViewSort, getListviewInitSchema, getLookupSapceUserTreeSchema, getNotifications, getObjectDetailButtons, getObjectDetailButtonsSchemas, getObjectDetailMoreButtons, getObjectFieldsFilterBarSchema, getObjectFieldsFilterButtonSchema, getObjectFieldsFilterFormSchema, getObjectListHeader$1 as getObjectListHeader, getObjectListHeaderFieldsFilterBar, getObjectListHeaderFirstLine, getObjectListHeaderSecordLine, getObjectListViewButtonsSchemas, getObjectRecordDetailHeader, getObjectRecordDetailRelatedListButtonsSchemas, getObjectRecordDetailRelatedListHeader, getObjectRelated, getObjectRelatedList, getObjectRelatedListButtons, getObjectRelatedListHeader, getPage, getRecord, getRecordDetailHeaderSchema, getRecordDetailRelatedListSchema, getRecordDetailSchema, getRecordPageInitSchema, getRecordPermissions, getRecordServiceSchema, getReferenceTo, getRelatedFieldValue, getRelatedListSchema, getRelatedsCount, getRootUrl, getSelectUserSchema, getSpaceUsersPickerAmisSchema, getSpaceUsersPickerSchema, getSteedosAuth, getTableSchema, getTenantId, getUISchema, getUISchemaSync, getUserId, getViewSchema, isExpression, isObject, lookupToAmis, lookupToAmisIdsPicker, lookupToAmisPicker, lookupToAmisSelect, lookupToAmisSelectUser, markReadAll, parseSingleExpression, registerRemoteAssets, registerRenders, setEnv, setEnvs, setRootUrl, setSteedosAuth, setUISchemaFunction, setVariable, standardButtonsTodo };
14255
14714
  //# sourceMappingURL=index.esm.js.map