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

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",
@@ -3270,7 +3334,7 @@ async function getObjectFieldsFilterBarSchema(objectSchema, ctx) {
3270
3334
  showFieldsFilter = true;
3271
3335
  }
3272
3336
  filterService.setData({showFieldsFilter});
3273
- resizeWindow();
3337
+ // resizeWindow();//已迁移到搜索栏表单提交事件中执行,因为表单项change后也会触发表单提交了
3274
3338
  // 使用filterForm.getValues()的话,并不能拿到本地存储中的过滤条件,所以需要从event.data中取。
3275
3339
  let filterFormValues = event.data;
3276
3340
  let isFieldsFilterEmpty = SteedosUI.isFilterFormValuesEmpty(filterFormValues);
@@ -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高度显示有问题
@@ -5219,7 +5286,8 @@ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLooku
5219
5286
  "placeholder": "搜索此列表",
5220
5287
  "value": crudKeywords,
5221
5288
  "clearable": true,
5222
- "clearAndSubmit": true
5289
+ "clearAndSubmit": true,
5290
+ "searchImediately": true
5223
5291
  }
5224
5292
  ]
5225
5293
  }
@@ -5394,6 +5462,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
5394
5462
  }
5395
5463
 
5396
5464
  function getObjectFooterToolbar(mainObject, formFactor, options) {
5465
+ // crud card模式与table模式两种情况下showPageInput默认值不一样,所以需要显式设置为false
5397
5466
  if (formFactor === 'SMALL') {
5398
5467
  // return [
5399
5468
  // "load-more",
@@ -5403,14 +5472,17 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5403
5472
  "switch-per-page",
5404
5473
  {
5405
5474
  "type": "pagination",
5406
- "maxButtons": 5
5475
+ "maxButtons": 5,
5476
+ "showPageInput": false
5407
5477
  }
5408
5478
  ]
5409
5479
  }else {
5410
5480
  return [
5481
+ // "statistics",
5411
5482
  {
5412
5483
  "type": "pagination",
5413
- "maxButtons": 5
5484
+ "maxButtons": 5,
5485
+ "showPageInput": false
5414
5486
  }
5415
5487
  ]
5416
5488
  }
@@ -5419,32 +5491,81 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
5419
5491
  if(options && options.isRelated){
5420
5492
  return [
5421
5493
  "statistics",
5422
- "pagination"
5494
+ {
5495
+ "type": "pagination",
5496
+ "maxButtons": 10,
5497
+ "showPageInput": false
5498
+ }
5423
5499
  ]
5424
5500
 
5425
5501
  }
5426
5502
  else {
5427
- return [
5428
- "switch-per-page",
5503
+ const no_pagination = mainObject.paging && (mainObject.paging.enabled === false);
5504
+ const is_lookup = options.isLookup;
5505
+ const commonConfig = [
5429
5506
  "statistics",
5430
- "pagination"
5431
- ]
5507
+ {
5508
+ "type": "pagination",
5509
+ "maxButtons": 10,
5510
+ "showPageInput": false
5511
+ }
5512
+ ];
5513
+
5514
+ if (no_pagination && is_lookup) {
5515
+ return commonConfig;
5516
+ } else {
5517
+ return ["switch-per-page", ...commonConfig];
5518
+ }
5432
5519
  }
5433
5520
  }
5434
5521
  }
5435
5522
 
5436
5523
  async function getObjectFilter(objectSchema, fields, options) {
5437
5524
  const fieldsFilterBarSchema = await getObjectListHeaderFieldsFilterBar(objectSchema, null, options);
5525
+ let onSubmitSuccScript = `
5526
+ let isLookup = event.data.isLookup;
5527
+ if(isLookup){
5528
+ return;
5529
+ }
5530
+ // 列表搜索栏字段值变更后立刻触发提交表单执行crud搜索,所以这里需要额外重算crud高度及筛选按钮红色星号图标显示隐藏
5531
+ let resizeWindow = function(){
5532
+ //触发amis crud 高度重算
5533
+ setTimeout(()=>{
5534
+ window.dispatchEvent(new Event("resize"))
5535
+ }, 1000);
5536
+ }
5537
+ resizeWindow();
5538
+ const scope = event.context.scoped;
5539
+ // let filterFormValues = event.data;
5540
+ let filterForm = SteedosUI.getClosestAmisComponentByType(scope, "form");
5541
+ let filterFormService = SteedosUI.getClosestAmisComponentByType(filterForm.context, "service");
5542
+ // 使用event.data的话,并不能拿到本地存储中的过滤条件,所以需要从filterFormService中取。
5543
+ let filterFormValues = filterFormService.getData()
5544
+ let isFieldsFilterEmpty = SteedosUI.isFilterFormValuesEmpty(filterFormValues);
5545
+ let crud = SteedosUI.getClosestAmisComponentByType(scope, "crud");
5546
+ let crudService = crud && SteedosUI.getClosestAmisComponentByType(crud.context, "service");
5547
+ crudService && crudService.setData({isFieldsFilterEmpty});
5548
+ `;
5438
5549
  return {
5439
5550
  "title": "",
5440
5551
  "submitText": "",
5441
5552
  "className": "",
5442
- // "debug": true,
5553
+ "debug": true,
5443
5554
  "mode": "normal",
5444
5555
  "wrapWithPanel": false,
5445
5556
  "body": [
5446
5557
  fieldsFilterBarSchema
5447
- ]
5558
+ ],
5559
+ "onEvent": {
5560
+ "submitSucc": {
5561
+ "actions": [
5562
+ {
5563
+ "actionType": "custom",
5564
+ "script": onSubmitSuccScript
5565
+ }
5566
+ ]
5567
+ }
5568
+ }
5448
5569
  }
5449
5570
  }
5450
5571
 
@@ -6065,13 +6186,15 @@ async function lookupToAmisPicker(field, readonly, ctx){
6065
6186
  pickerSchema.headerToolbar = getObjectHeaderToolbar(refObjectConfig, fieldsArr, ctx.formFactor, { headerToolbarItems, isLookup: true, keywordsSearchBoxName });
6066
6187
  const isAllowCreate = refObjectConfig.permissions.allowCreate;
6067
6188
  const isCreate = ___namespace.isBoolean(field.create) ? field.create : true;
6068
- if (isAllowCreate && isCreate) {
6189
+ // lookup字段配置过滤条件就强制不显示新建按钮
6190
+ let isHasFilters = (field.filters || field._filtersFunction) ? true : false;
6191
+ if (isAllowCreate && isCreate && !isHasFilters) {
6069
6192
  const new_button = await getSchema$5(refObjectConfig, { appId: ctx.appId, objectName: refObjectConfig.name, formFactor: ctx.formFactor });
6070
6193
  new_button.align = "right";
6071
6194
  // 保持快速搜索放在最左侧,新建按钮往里插,而不是push到最后
6072
6195
  pickerSchema.headerToolbar.splice(pickerSchema.headerToolbar.length - 1, 0, new_button);
6073
6196
  }
6074
- pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar();
6197
+ pickerSchema.footerToolbar = refObjectConfig.enable_tree ? [] : getObjectFooterToolbar(refObjectConfig,ctx.formFactor,{isLookup: true});
6075
6198
  if (ctx.filterVisible !== false) {
6076
6199
  pickerSchema.filter = await getObjectFilter(refObjectConfig, fields, {
6077
6200
  ...ctx,
@@ -6199,10 +6322,10 @@ async function lookupToAmisSelect(field, readonly, ctx){
6199
6322
  // const labelFieldKey = referenceTo && referenceTo.labelField?.name || 'name';
6200
6323
 
6201
6324
  let apiInfo;
6202
-
6325
+ let defaultValueOptionsQueryData;
6203
6326
  if(referenceTo){
6204
6327
  // 字段值单独走一个请求合并到source的同一个GraphQL接口中
6205
- const defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6328
+ defaultValueOptionsQueryData = await getFindQuery({ name: referenceTo.objectName }, null, [
6206
6329
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6207
6330
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6208
6331
  ], {
@@ -6215,7 +6338,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6215
6338
  }, null, [
6216
6339
  Object.assign({}, referenceTo.labelField, {alias: 'label'}),
6217
6340
  Object.assign({}, referenceTo.valueField, {alias: 'value'})
6218
- ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`, moreQueries: [defaultValueOptionsQueryData.query]});
6341
+ ], {expand: false, alias: 'options', queryOptions: `filters: {__filters}, top: {__top}, sort: "{__sort}"`});
6219
6342
 
6220
6343
  apiInfo.adaptor = `
6221
6344
  const data = payload.data;
@@ -6309,11 +6432,16 @@ async function lookupToAmisSelect(field, readonly, ctx){
6309
6432
  var optionsFiltersOp = "${field.multiple ? "in" : "="}";
6310
6433
  var optionsFilters = [["${valueFieldKey}", optionsFiltersOp, []]];
6311
6434
  if (defaultValue && !api.data.$term) {
6435
+ const defaultValueOptionsQueryData = ${JSON.stringify(defaultValueOptionsQueryData)};
6436
+ const defaultValueOptionsQuery = defaultValueOptionsQueryData?.query?.replace(/^{/,"").replace(/}$/,"");
6312
6437
  // 字段值单独请求,没值的时候在请求中返回空
6313
6438
  optionsFilters = [["${valueFieldKey}", optionsFiltersOp, defaultValue]];
6314
6439
  if(filters.length > 0){
6315
6440
  optionsFilters = [filters, optionsFilters];
6316
6441
  }
6442
+ if(defaultValueOptionsQuery){
6443
+ api.data.query = "{"+api.data.query.replace(/^{/,"").replace(/}$/,"")+","+defaultValueOptionsQuery+"}";
6444
+ }
6317
6445
  }
6318
6446
  api.data.query = api.data.query.replace(/{__options_filters}/g, JSON.stringify(optionsFilters));
6319
6447
  return api;
@@ -6355,7 +6483,7 @@ async function lookupToAmisSelect(field, readonly, ctx){
6355
6483
  disabledOn: `${readonly} || ( (this._master && (this._master.relatedKey ==='${field.name}')) || ((this.relatedKey ==='${field.name}') && (${field.multiple} != true)) )`,
6356
6484
  // labelField: labelField,
6357
6485
  // valueField: valueField,
6358
- source: apiInfo,
6486
+ // source: apiInfo,
6359
6487
  autoComplete: apiInfo,
6360
6488
  searchable: true,
6361
6489
  };
@@ -6434,10 +6562,10 @@ async function lookupToAmis(field, readonly, ctx){
6434
6562
 
6435
6563
  const refObject = await getUISchema(referenceTo.objectName);
6436
6564
 
6437
- // 此处不参考 steedos 的 enable_enhanced_lookup 规则. 如果默认是开启弹出选择,用户选择过程操作太繁琐, 所以默认是关闭弹出选择.
6438
- // 由于amis picker 目前不支持联动, 配置了depend_on时, 使用使用select ,以支持联动
6439
- // TODO: 确认 amis picker 支持联动时, 清理field.depend_on判断
6440
- if(refObject.enable_enhanced_lookup == true && ___namespace.isEmpty(field.depend_on)){
6565
+ // 优先取字段中配置的enable_enhanced_lookup,字段上没配置时,才从对象上取enable_enhanced_lookup属性
6566
+ let enableEnhancedLookup = ___namespace.isBoolean(field.enable_enhanced_lookup) ? field.enable_enhanced_lookup : refObject.enable_enhanced_lookup;
6567
+ // 默认使用下拉框模式显示lookup选项,只能配置了enable_enhanced_lookup才使用弹出增强模式
6568
+ if(enableEnhancedLookup == true){
6441
6569
  return await lookupToAmisPicker(field, readonly, ctx);
6442
6570
  }else if(refObject.enable_tree) {
6443
6571
  return await lookupToAmisTreeSelect(field, readonly, Object.assign({}, ctx, {
@@ -6754,8 +6882,8 @@ function getAmisStaticFieldType(type, readonly, options){
6754
6882
  /*
6755
6883
  * @Author: baozhoutao@steedos.com
6756
6884
  * @Date: 2022-10-28 14:15:09
6757
- * @LastEditors: baozhoutao@steedos.com
6758
- * @LastEditTime: 2022-11-02 18:06:16
6885
+ * @LastEditors: liaodaxue
6886
+ * @LastEditTime: 2023-10-30 17:51:54
6759
6887
  * @Description:
6760
6888
  */
6761
6889
 
@@ -6806,11 +6934,26 @@ const getAmisFileEditSchema = (steedosField)=>{
6806
6934
  useChunk: false, // 关闭分块上传
6807
6935
  receiver: {
6808
6936
  method: "post",
6937
+ dataType: "form-data",
6809
6938
  url: `\${context.rootUrl}/s3/${tableName}`,
6810
- data: {
6811
- $: "$$",
6812
- context: `\${context}`,
6813
- },
6939
+ requestAdaptor: `
6940
+ const { _master, global,context } = api.body;
6941
+ // const { recordId, objectName } = _master;
6942
+ const { spaceId, userId, user } = global;
6943
+ /*
6944
+ record_id: recordId,
6945
+ parent: recordId,
6946
+ object_name: objectName,
6947
+ owner_name: user.name,
6948
+ space: spaceId,
6949
+ owner: userId
6950
+ */
6951
+ // 参考platform 2.2版本,附件字段保存时cfs.files.filerecord、cfs.images.filerecord表中的metadata下只保存space、owner两个属性值。
6952
+ api.data.append('space', spaceId);
6953
+ api.data.append('owner', userId);
6954
+
6955
+ return api;
6956
+ `,
6814
6957
  adaptor: `
6815
6958
  const { context } = api.body;
6816
6959
  var rootUrl = context.rootUrl + "/api/files/${tableName}/";
@@ -6996,8 +7139,6 @@ function getSelectFieldOptions(field){
6996
7139
  }
6997
7140
 
6998
7141
  async function convertSFieldToAmisField(field, readonly, ctx) {
6999
- // console.log('convertSFieldToAmisField====>', field, readonly, ctx)
7000
- const isMobile = window.innerWidth <= 768;
7001
7142
  // 创建人和修改人、创建时间和修改时间不显示
7002
7143
  if(___namespace.includes(OMIT_FIELDS, field.name) && ctx.showSystemFields != true){
7003
7144
  return;
@@ -7086,26 +7227,33 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7086
7227
  };
7087
7228
  break;
7088
7229
  case 'date':
7089
- convertData = isMobile && !readonly ? {
7090
- type: "native-date",
7091
- pipeIn: (value, data) => {
7092
- if (value) {
7093
- value = moment(value).utc().format('YYYY-MM-DD');
7094
- return value;
7095
- } else {
7096
- return "";
7097
- }
7098
-
7099
- },
7100
- pipeOut: (value, oldValue, data) => {
7101
- if (value) {
7102
- value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7103
- return value;
7104
- } else {
7105
- return "";
7106
- }
7107
- }
7108
- } : {
7230
+ // convertData = isMobile && !readonly ? {
7231
+ // type: "native-date",
7232
+ // pipeIn: (value, data) => {
7233
+ // if (value) {
7234
+ // value = moment(value).utc().format('YYYY-MM-DD');
7235
+ // return value;
7236
+ // } else {
7237
+ // return "";
7238
+ // }
7239
+
7240
+ // },
7241
+ // pipeOut: (value, oldValue, data) => {
7242
+ // if (value) {
7243
+ // value = moment(value).format('YYYY-MM-DDT00:00:00.000[Z]');
7244
+ // return value;
7245
+ // } else {
7246
+ // return "";
7247
+ // }
7248
+ // }
7249
+ // } : {
7250
+ // type: getAmisStaticFieldType('date', readonly),
7251
+ // inputFormat: "YYYY-MM-DD",
7252
+ // format:'YYYY-MM-DDT00:00:00.000[Z]',
7253
+ // tpl: readonly ? Tpl.getDateTpl(field) : null,
7254
+ // // utc: true
7255
+ // }
7256
+ convertData = {
7109
7257
  type: getAmisStaticFieldType('date', readonly),
7110
7258
  inputFormat: "YYYY-MM-DD",
7111
7259
  format:'YYYY-MM-DDT00:00:00.000[Z]',
@@ -7124,43 +7272,51 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7124
7272
  };
7125
7273
  break;
7126
7274
  case 'datetime':
7127
- convertData = isMobile && !readonly ? {
7128
- type: "combo",
7129
- pipeIn: (value, data) => {
7130
- let revalue = {};
7131
- if (value && value != "Invalid date") {
7132
- value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7133
- revalue[field.name + "-native-date"] = value.split(' ')[0];
7134
- revalue[field.name + "-native-time"] = value.split(' ')[1];
7135
- } else {
7136
- revalue[field.name + "-native-date"] = "";
7137
- revalue[field.name + "-native-time"] = "";
7138
- }
7139
- return revalue;
7140
- },
7141
- pipeOut: (value, oldValue, data) => {
7142
- let revalue = "";
7143
- if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7144
- revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7145
- revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7146
- }
7147
- return revalue;
7148
- },
7149
- items: [
7150
- {
7151
- type: "native-date",
7152
- name: field.name + "-native-date",
7153
- className: "steedos-native-date",
7154
- value: ""
7155
- },
7156
- {
7157
- type: "native-time",
7158
- name: field.name + "-native-time",
7159
- className: "steedos-native-time",
7160
- value: ""
7161
- }
7162
- ]
7163
- } : {
7275
+ // convertData = isMobile && !readonly ? {
7276
+ // type: "combo",
7277
+ // pipeIn: (value, data) => {
7278
+ // let revalue = {};
7279
+ // if (value && value != "Invalid date") {
7280
+ // value = moment(value).format('YYYY-MM-DD HH:mm:ss');
7281
+ // revalue[field.name + "-native-date"] = value.split(' ')[0];
7282
+ // revalue[field.name + "-native-time"] = value.split(' ')[1];
7283
+ // } else {
7284
+ // revalue[field.name + "-native-date"] = "";
7285
+ // revalue[field.name + "-native-time"] = "";
7286
+ // }
7287
+ // return revalue;
7288
+ // },
7289
+ // pipeOut: (value, oldValue, data) => {
7290
+ // let revalue = "";
7291
+ // if (value[field.name + "-native-date"] && value[field.name + "-native-time"]) {
7292
+ // revalue = value[field.name + "-native-date"] + " " + value[field.name + "-native-time"];
7293
+ // revalue = moment(revalue).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]');
7294
+ // }
7295
+ // return revalue;
7296
+ // },
7297
+ // items: [
7298
+ // {
7299
+ // type: "native-date",
7300
+ // name: field.name + "-native-date",
7301
+ // className: "steedos-native-date",
7302
+ // value: ""
7303
+ // },
7304
+ // {
7305
+ // type: "native-time",
7306
+ // name: field.name + "-native-time",
7307
+ // className: "steedos-native-time",
7308
+ // value: ""
7309
+ // }
7310
+ // ]
7311
+ // } : {
7312
+ // type: getAmisStaticFieldType('datetime', readonly),
7313
+ // inputFormat: 'YYYY-MM-DD HH:mm',
7314
+ // format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
7315
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7316
+ // utc: true,
7317
+ // }
7318
+
7319
+ convertData = {
7164
7320
  type: getAmisStaticFieldType('datetime', readonly),
7165
7321
  inputFormat: 'YYYY-MM-DD HH:mm',
7166
7322
  format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
@@ -7180,26 +7336,34 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7180
7336
  };
7181
7337
  break;
7182
7338
  case 'time':
7183
- convertData = isMobile && !readonly ? {
7184
- type: "native-time",
7185
- pipeIn: (value, data) => {
7186
- if (value) {
7187
- value = moment(value).utc().format('HH:mm');
7188
- return value;
7189
- } else {
7190
- return "";
7191
- }
7192
-
7193
- },
7194
- pipeOut: (value, oldValue, data) => {
7195
- if (value) {
7196
- value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7197
- return value;
7198
- } else {
7199
- return "";
7200
- }
7201
- }
7202
- } : {
7339
+ // convertData = isMobile && !readonly ? {
7340
+ // type: "native-time",
7341
+ // pipeIn: (value, data) => {
7342
+ // if (value) {
7343
+ // value = moment(value).utc().format('HH:mm');
7344
+ // return value;
7345
+ // } else {
7346
+ // return "";
7347
+ // }
7348
+
7349
+ // },
7350
+ // pipeOut: (value, oldValue, data) => {
7351
+ // if (value) {
7352
+ // value = moment('1970-01-01 ' + value).format('1970-01-01THH:mm:00.000[Z]');
7353
+ // return value;
7354
+ // } else {
7355
+ // return "";
7356
+ // }
7357
+ // }
7358
+ // } : {
7359
+ // type: getAmisStaticFieldType('time', readonly),
7360
+ // inputFormat: 'HH:mm',
7361
+ // timeFormat:'HH:mm',
7362
+ // format:'1970-01-01THH:mm:00.000[Z]',
7363
+ // tpl: readonly ? Tpl.getDateTimeTpl(field) : null,
7364
+ // // utc: true
7365
+ // }
7366
+ convertData = {
7203
7367
  type: getAmisStaticFieldType('time', readonly),
7204
7368
  inputFormat: 'HH:mm',
7205
7369
  timeFormat:'HH:mm',
@@ -7249,7 +7413,20 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
7249
7413
  type: getAmisStaticFieldType('number', readonly),
7250
7414
  min: field.min,
7251
7415
  max: field.max,
7252
- precision: field.scale
7416
+ precision: field.scale,
7417
+ suffix: "%",
7418
+ pipeIn: (value, data) => {
7419
+ if(value){
7420
+ return value*100;
7421
+ }
7422
+ return value;
7423
+ },
7424
+ pipeOut: (value, oldValue, data) => {
7425
+ if(value){
7426
+ return value/100;
7427
+ }
7428
+ return value;
7429
+ },
7253
7430
  };
7254
7431
  }
7255
7432
  break;
@@ -7583,7 +7760,9 @@ async function getFieldSearchable(perField, permissionFields, ctx){
7583
7760
 
7584
7761
  const amisField = await convertSFieldToAmisField(_field, false, Object.assign({}, ctx, {fieldNamePrefix: fieldNamePrefix, required: false, showSystemFields: true, inFilterForm: true}));
7585
7762
  if(amisField){
7586
- return amisField;
7763
+ return Object.assign({}, amisField,{
7764
+ submitOnChange: true
7765
+ });
7587
7766
  }
7588
7767
  }
7589
7768
  }
@@ -7661,8 +7840,46 @@ var config = {
7661
7840
  };
7662
7841
 
7663
7842
  async function getQuickEditSchema(field, options){
7664
- const quickEditId = options.objectName + "_" + field.name + "QuickEdit";//定义快速编辑的表单id,用于setvalue传值
7843
+ //判断在amis3.2以上环境下,放开批量编辑
7844
+ let isAmisVersionforBatchEdit = false;
7845
+ if(window.amisRequire && window.amisRequire('amis')){
7846
+ isAmisVersionforBatchEdit = window.amisRequire('amis').version[0] >= 3 && window.amisRequire('amis').version[2] >= 2;
7847
+ }else if(window.Amis){
7848
+ isAmisVersionforBatchEdit = window.Amis.version[0] >= 3 && window.Amis.version[2] >= 2;
7849
+ }
7850
+ const quickEditId = options.objectName + "_" + field.name + "_quickEdit";//定义快速编辑的表单id,用于setvalue传值
7665
7851
  var quickEditSchema = { body: [], id: quickEditId };
7852
+ //select,avatar,image,file等组件无法行记录字段赋值,暂不支持批量编辑;
7853
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
7854
+ const submitEvent = {
7855
+ submit: {
7856
+ actions: [
7857
+ {
7858
+ actionType: "custom",
7859
+ script: `
7860
+ let items = _.cloneDeep(event.data.items);
7861
+ let selectedItems = _.cloneDeep(event.data.selectedItems);
7862
+ if(event.data.isBatchEdit){
7863
+ selectedItems.forEach(function(selectedItem){
7864
+ selectedItem._display.${field.name} = event.data._display.${field.name};
7865
+ doAction({actionType: 'setValue', "args": {"value": selectedItem._display},componentId: "_display_" + selectedItem._index});
7866
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + selectedItem._index});
7867
+ })
7868
+ }else{
7869
+ doAction({actionType: 'setValue', "args": {"value": event.data._display},componentId: "_display_" + event.data._index});
7870
+ doAction({actionType: 'setValue', "args": {"value": event.data.${field.name}},componentId: "${options.objectName + "_" + field.name + "_"}" + event.data._index});
7871
+ }
7872
+ `
7873
+ },
7874
+ {
7875
+ "actionType": "closeDialog"
7876
+ }
7877
+ ]
7878
+ }
7879
+ };
7880
+ quickEditSchema.onEvent = submitEvent;
7881
+ }
7882
+
7666
7883
  if (field.disabled) {
7667
7884
  quickEditSchema = false;
7668
7885
  } else {
@@ -7679,7 +7896,7 @@ async function getQuickEditSchema(field, options){
7679
7896
  {
7680
7897
  "actionType": "custom",
7681
7898
  "script": `
7682
- var _display = event.data._display;
7899
+ var _display = _.cloneDeep(event.data._display);
7683
7900
  ${displayField}
7684
7901
  doAction({actionType: 'setValue', "args": {"value": {_display}},componentId: "${quickEditId}"});
7685
7902
  `
@@ -7701,7 +7918,7 @@ async function getQuickEditSchema(field, options){
7701
7918
  第二种是增加选项时,按照value的值,找到对应选项,并按照_display的规则为其赋值
7702
7919
  */
7703
7920
  TempDisplayField = `
7704
- const preData = event.data.__super.${field.name};
7921
+ const preData = _.cloneDeep(event.data.__super.${field.name});
7705
7922
  if(preData && event.data.${field.name}.length < preData.length){
7706
7923
  let deletedIndex;
7707
7924
  preData.forEach(function(item,index){
@@ -7745,7 +7962,7 @@ async function getQuickEditSchema(field, options){
7745
7962
  break;
7746
7963
  case "percent":
7747
7964
  TempDisplayField = `
7748
- _display["${field.name}"] = (event.data.value * 100).toFixed(${field.scale}) + '%';
7965
+ _display["${field.name}"] = event.data.value.toFixed(${field.scale}) + '%';
7749
7966
  `;
7750
7967
  quickEditSchema.body[0].onEvent["change"] = quickEditOnEvent(TempDisplayField);
7751
7968
  break;
@@ -7896,6 +8113,131 @@ async function getQuickEditSchema(field, options){
7896
8113
  }
7897
8114
 
7898
8115
  });
8116
+ if(field.type != 'avatar' && field.type != 'image' && field.type != 'file' && isAmisVersionforBatchEdit){
8117
+ quickEditSchema.body.push({
8118
+ "name": "isBatchEdit",
8119
+ "type": "checkbox",
8120
+ "option": [
8121
+ {
8122
+ "type": "tpl",
8123
+ "tpl": "更新${COUNT(selectedItems)}个选定记录"
8124
+ },
8125
+ {
8126
+ "type": "spinner",
8127
+ "showOn": "${batchPermissionLoading}",
8128
+ "size": "sm",
8129
+ "className": "mr-4"
8130
+ }
8131
+ ],
8132
+ "visibleOn": "${ARRAYSOME(selectedItems, item => item._id === _id) && COUNT(selectedItems)>1 && quickedit_record_permissions.allowEdit && quickedit_record_permissions_loading == false}",
8133
+ "disabledOn": "${batchPermissionLoading}",
8134
+ "onEvent":{
8135
+ "change":{
8136
+ "actions":[
8137
+ {
8138
+ "actionType": "setValue",
8139
+ "componentId": quickEditId,
8140
+ "args": {
8141
+ "value":{
8142
+ "batchPermissionLoading": true
8143
+ }
8144
+ },
8145
+ "expression":"${event.data.value}"
8146
+ },
8147
+ {
8148
+ "actionType": "ajax",
8149
+ "args": {
8150
+ "api": {
8151
+ "url": "${context.rootUrl}/graphql",
8152
+ "method": "post",
8153
+ "headers": {
8154
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
8155
+ },
8156
+ "data": {
8157
+ "query": "{rows:${objectName}(filters:[\"_id\",\"in\",${selectedItems | pick:_id | split | json}]){_id,_permissions{allowEdit}}}"
8158
+ },
8159
+ "adaptor": `
8160
+ const noPermission = [];
8161
+ payload.data.rows.forEach(function (row) {
8162
+ if(!row._permissions.allowEdit){
8163
+ noPermission.push(row._id);
8164
+ }
8165
+ })
8166
+ payload.data.noPermission = noPermission;
8167
+ return payload;
8168
+ `
8169
+ }
8170
+ },
8171
+ "expression":"${event.data.value}"
8172
+ },
8173
+ {
8174
+ "actionType": "setValue",
8175
+ "componentId": quickEditId,
8176
+ "args": {
8177
+ "value":{
8178
+ "batchPermissionLoading": false
8179
+ }
8180
+ },
8181
+ "expression":"${event.data.value}"
8182
+ },
8183
+ {
8184
+ "actionType": "dialog",
8185
+ "dialog":{
8186
+ "title": "记录权限",
8187
+ "showCloseButton": false,
8188
+ "body":[
8189
+ {
8190
+ "type": "tpl",
8191
+ "tpl": "当前选中记录中,有${COUNT(noPermission)}条记录无编辑权限,是否需要批量编辑其他记录?"
8192
+ }
8193
+ ],
8194
+ "onEvent":{
8195
+ "confirm":{
8196
+ "actions":[
8197
+ {
8198
+ "actionType": "custom",
8199
+ "script": `
8200
+ const noPermission = event.data.noPermission;
8201
+ const crudComponent = event.context.scoped.getComponentById("${options.crudId}");
8202
+ const selectedItems = crudComponent && crudComponent.props.store.selectedItems.concat();
8203
+ noPermission.forEach(function (item) {
8204
+ crudComponent && crudComponent.unSelectItem(_.find(selectedItems,{_id:item}));
8205
+ })
8206
+ `
8207
+ },
8208
+ {
8209
+ "actionType": "setValue",
8210
+ "componentId": quickEditId,
8211
+ "args": {
8212
+ "value":{
8213
+ "isBatchEdit": true
8214
+ }
8215
+ },
8216
+ }
8217
+ ]
8218
+ },
8219
+ "cancel":{
8220
+ "actions":[
8221
+ {
8222
+ "actionType": "setValue",
8223
+ "componentId": quickEditId,
8224
+ "args": {
8225
+ "value":{
8226
+ "isBatchEdit": false
8227
+ }
8228
+ },
8229
+ }
8230
+ ]
8231
+ }
8232
+ }
8233
+ },
8234
+ "expression":"${COUNT(event.data.noPermission)>0}"
8235
+ }
8236
+ ]
8237
+ }
8238
+ }
8239
+ });
8240
+ }
7899
8241
  } else {
7900
8242
  quickEditSchema = false;
7901
8243
  }
@@ -7930,6 +8272,8 @@ async function getTableColumns(fields, options){
7930
8272
  const columns = [];
7931
8273
  if(!options.isLookup){
7932
8274
  columns.push({name: '_index',type: 'text', width: 32, placeholder: ""});
8275
+ //将_display放入crud的columns中,可以通过setvalue修改行内数据域的_display,而不影响上层items的_display,用于批量编辑
8276
+ columns.push({name: '_display',type: 'static', width: 32, placeholder: "",id: "_display_${_index}", className: "hidden"});
7933
8277
  }
7934
8278
  const allowEdit = options.permissions?.allowEdit && !options.isLookup && options.enable_inline_edit != false;
7935
8279
 
@@ -7961,7 +8305,7 @@ async function getTableColumns(fields, options){
7961
8305
  {
7962
8306
  "args": {
7963
8307
  "api": {
7964
- "url": "${context.rootUrl}/api/files/files/${versions[0]}?download=true",
8308
+ "url": "${(versions[0] && versions[0].url) ? versions[0].url+'?download=true' : context.rootUrl+'/api/files/files/'+versions[0]+'?download=true'}",
7965
8309
  "method": "get",
7966
8310
  "headers": {
7967
8311
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
@@ -8008,7 +8352,7 @@ async function getTableColumns(fields, options){
8008
8352
  else if(field.type === 'select'){
8009
8353
  const map = getSelectMap(field.options);
8010
8354
  columnItem = Object.assign({}, {
8011
- type: "mapping",
8355
+ type: "static-mapping",
8012
8356
  name: field.name,
8013
8357
  label: field.label,
8014
8358
  map: map,
@@ -8023,7 +8367,7 @@ async function getTableColumns(fields, options){
8023
8367
  const tpl = await getFieldTpl(field, options);
8024
8368
  let type = 'text';
8025
8369
  if(tpl){
8026
- type = 'tpl';
8370
+ type = 'static';
8027
8371
  }else if(field.type === 'html'){
8028
8372
  type = 'markdown';
8029
8373
  }else if(field.type === 'url'){
@@ -8064,6 +8408,7 @@ async function getTableColumns(fields, options){
8064
8408
  columnItem.quickEdit = quickEditSchema;
8065
8409
  columnItem.quickEditEnabledOn = "${is_system !== true}";
8066
8410
  }
8411
+ columnItem.id = `${options.objectName}_${field.name}_\${_index}`;
8067
8412
  columns.push(columnItem);
8068
8413
  }
8069
8414
  }
@@ -8342,7 +8687,7 @@ async function getTableOperation(ctx){
8342
8687
  }
8343
8688
  return {
8344
8689
  type: 'operation',
8345
- label: i18next__default["default"].t('frontend_operation'),
8690
+ label: "",
8346
8691
  fixed: 'right',
8347
8692
  labelClassName: 'text-center',
8348
8693
  className: 'text-center steedos-listview-operation w-10',
@@ -8376,23 +8721,87 @@ async function getTableOperation(ctx){
8376
8721
  }
8377
8722
  }
8378
8723
 
8724
+ async function getDefaultCrudCard(columns, options) {
8725
+ let labelFieldName = options?.labelFieldName || "name";
8726
+ let titleColumn, bodyColumns = [];
8727
+ columns.forEach(function (item) {
8728
+ delete item.quickEdit;
8729
+ delete item.width;
8730
+ if (item.name === labelFieldName) {
8731
+ titleColumn = item;
8732
+ }
8733
+ else {
8734
+ if (item.name !== "_index") {
8735
+ bodyColumns.push(item);
8736
+ }
8737
+ }
8738
+ });
8739
+ let card = {
8740
+ "header": {
8741
+ "title": titleColumn.tpl
8742
+ },
8743
+ body: bodyColumns,
8744
+ // useCardLabel: false,
8745
+ toolbar: []
8746
+ };
8747
+ let hideToolbarOperation = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8748
+ if(!hideToolbarOperation){
8749
+ let toolbarOperation = await getTableOperation(options);
8750
+ if (toolbarOperation) {
8751
+ toolbarOperation.className += " inline-block w-auto";
8752
+ }
8753
+ card.toolbar.push(toolbarOperation);
8754
+ }
8755
+ return card;
8756
+ }
8757
+
8379
8758
  async function getTableSchema$1(fields, options){
8380
8759
  if(!options){
8381
8760
  options = {};
8382
8761
  }
8383
8762
  let { isLookup, hiddenColumnOperation } = options;
8763
+ const defaults = options.defaults;
8764
+ const listSchema = (defaults && defaults.listSchema) || {};
8765
+
8384
8766
  let columns = [];
8385
8767
  let useMobileColumns = options.formFactor === 'SMALL' || ["split"].indexOf(options.displayAs) > -1;
8386
8768
  if(isLookup){
8387
8769
  // 在lookup手机端列表模式调式好之前不使用getMobileTableColumns
8388
8770
  useMobileColumns = false;
8389
8771
  }
8772
+ if(listSchema.mode && listSchema.mode !== "table"){
8773
+ // 如果指定的mode,则不走我们内置的手机端列表效果,使用steedos组件内部开发的默认card/list效果,或者由用户自己实现card/list模式的crud列表
8774
+ useMobileColumns = false;
8775
+ }
8390
8776
  if(useMobileColumns){
8391
8777
  columns = await getMobileTableColumns(fields, options);
8392
8778
  }
8393
8779
  else {
8394
8780
  columns = await getTableColumns(fields, options);
8395
8781
 
8782
+ if(listSchema.mode === "cards"){
8783
+ let card = listSchema.card;
8784
+ if(!card){
8785
+ card = await getDefaultCrudCard(columns, options);
8786
+ }
8787
+ return {
8788
+ mode: "cards",
8789
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8790
+ name: "thelist",
8791
+ headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8792
+ className: "",
8793
+ draggable: false,
8794
+ defaultParams: getDefaultParams(options),
8795
+ card: card,
8796
+ syncLocation: false,
8797
+ keepItemSelectionOnPageChange: true,
8798
+ checkOnItemClick: isLookup ? true : false,
8799
+ labelTpl: `\${${options.labelFieldName}}`,
8800
+ autoFillHeight: false, // 自动高度效果不理想,先关闭
8801
+ columnsTogglable: false
8802
+ }
8803
+ }
8804
+
8396
8805
  if(!isLookup && !hiddenColumnOperation){
8397
8806
  columns.push(await getTableOperation(options));
8398
8807
  }
@@ -8400,6 +8809,7 @@ async function getTableSchema$1(fields, options){
8400
8809
 
8401
8810
  return {
8402
8811
  mode: "table",
8812
+ perPageAvailable: [5, 10, 20, 50, 100, 500],
8403
8813
  name: "thelist",
8404
8814
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
8405
8815
  className: "",
@@ -8870,18 +9280,30 @@ function getReadonlyFormAdaptor(object, fields, options){
8870
9280
  payload.status = 2;
8871
9281
  payload.msg = payload.errors[0].message;
8872
9282
  }
9283
+ ${options && options.initApiAdaptor || ''}
8873
9284
  return payload;
8874
9285
  `
8875
9286
  }
8876
9287
 
8877
9288
  async function getReadonlyFormInitApi(object, recordId, fields, options){
9289
+ let findOneOptions;
9290
+ if (!recordId && options && options.isEditor) {
9291
+ // 设计器中只读表单返回第一条记录
9292
+ findOneOptions = {
9293
+ filters: [],
9294
+ queryOptions: "top: 1"
9295
+ };
9296
+ }
8878
9297
  return {
8879
9298
  method: "post",
8880
9299
  url: getApi$2() + '&objectName=${objectName}' + "&recordId=${recordId}",
8881
9300
  cache: API_CACHE,
8882
- // requestAdaptor: "console.log('getReadonlyFormInitApi requestAdaptor', api);return api;",
9301
+ requestAdaptor: `
9302
+ ${options && options.initApiRequestAdaptor || ''}
9303
+ return api;
9304
+ `,
8883
9305
  adaptor: getReadonlyFormAdaptor(object, fields, options),
8884
- data: await getFindOneQuery$1(object, recordId, fields, options),
9306
+ data: await getFindOneQuery$1(object, recordId, fields, findOneOptions),
8885
9307
  headers: {
8886
9308
  Authorization: "Bearer ${context.tenantId},${context.authToken}"
8887
9309
  }
@@ -9022,7 +9444,7 @@ async function getEditFormInitApi(object, recordId, fields, options){
9022
9444
  ${getScriptForRewriteValueForFileFields(fields)}
9023
9445
 
9024
9446
  _.each(dataKeys, function(key){
9025
- if(fieldKeys.indexOf(key)<0){
9447
+ if(fieldKeys.indexOf(key)<0 && key !== "_display"){
9026
9448
  delete data[key];
9027
9449
  }
9028
9450
  })
@@ -9197,6 +9619,8 @@ async function getCalendarApi(mainObject, fields, options) {
9197
9619
 
9198
9620
  if(api.data.$self.additionalFilters){
9199
9621
  filters.push(api.data.$self.additionalFilters)
9622
+ }else if(api.data.$self.event.data.additionalFilters){
9623
+ filters.push(api.data.$self.event.data.additionalFilters)
9200
9624
  }
9201
9625
 
9202
9626
  var pageSize = api.data.pageSize || 10;
@@ -9522,6 +9946,7 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9522
9946
  businessHours.endTime = `${calendarOptions.endDayHour}:00`;
9523
9947
  }
9524
9948
 
9949
+ // api.trackExpression="\\\${additionalFilters}";
9525
9950
  const onEvent = {
9526
9951
  "getEvents": {
9527
9952
  "weight": 0,
@@ -9533,6 +9958,22 @@ async function getObjectCalendar(objectSchema, calendarOptions, options) {
9533
9958
  "actionType": "custom",
9534
9959
  "script": onGetEventsScript
9535
9960
  }
9961
+ // {
9962
+ // "actionType": "ajax",
9963
+ // "outputVar": "responseResult",
9964
+ // "args": {
9965
+ // "options": {
9966
+ // },
9967
+ // "api": api
9968
+ // // {
9969
+ // // "url": "111",
9970
+ // // "method": "post",
9971
+ // // "data": {
9972
+ // // "calendarOptions": JSON.stringify(calendarOptions);
9973
+ // // }
9974
+ // // }
9975
+ // }
9976
+ // }
9536
9977
  ]
9537
9978
  },
9538
9979
  "select": {
@@ -9856,7 +10297,7 @@ function deleteVariable(data, key) {
9856
10297
  * @Author: baozhoutao@steedos.com
9857
10298
  * @Date: 2022-05-26 16:02:08
9858
10299
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
9859
- * @LastEditTime: 2023-09-15 15:36:17
10300
+ * @LastEditTime: 2023-10-12 18:25:05
9860
10301
  * @Description:
9861
10302
  */
9862
10303
 
@@ -9876,8 +10317,9 @@ const getFieldSchemaArray = (formFields, ctx) => {
9876
10317
  }
9877
10318
 
9878
10319
  let forceHidden = false;
9879
- if(!recordId && field.readonly){
10320
+ if(!recordId && field.readonly && !ctx.isEditor){
9880
10321
  // 新建记录时,只读字段先隐藏,后续支持显示后,即任务:https://github.com/steedos/steedos-platform/issues/3164 完成后再放开
10322
+ // 表单只读时所有字段都是readonly,设计器中如果forceHidden会造成整个表单在只读的时候显示为空白了,所以要排除掉
9881
10323
  forceHidden = true;
9882
10324
  }
9883
10325
 
@@ -10119,6 +10561,9 @@ async function getObjectCRUD(objectSchema, fields, options){
10119
10561
  const nonpaged = objectSchema.paging && objectSchema.paging.enabled === false;
10120
10562
  const isTreeObject = objectSchema.enable_tree;
10121
10563
  const bulkActions = getBulkActions(objectSchema);
10564
+ const defaults = options.defaults;
10565
+ const listSchema = (defaults && defaults.listSchema) || {};
10566
+
10122
10567
  const bodyProps = {
10123
10568
  // toolbar: getToolbar(),
10124
10569
  // headerToolbar: getObjectHeaderToolbar(objectSchema, options.formFactor, {showDisplayAs}),
@@ -10130,9 +10575,12 @@ async function getObjectCRUD(objectSchema, fields, options){
10130
10575
  filter: options.filterVisible !== false && await getObjectFilter(objectSchema, fields, options),
10131
10576
  };
10132
10577
  if(options.formFactor !== 'SMALL' || ["split"].indexOf(options.displayAs) == -1){
10133
- Object.assign(bodyProps, {
10134
- bulkActions: options.bulkActions != false ? bulkActions : false
10135
- });
10578
+ if(listSchema.mode !== "cards"){
10579
+ // card模式时默认不显示勾选框
10580
+ Object.assign(bodyProps, {
10581
+ bulkActions: options.bulkActions != false ? bulkActions : false
10582
+ });
10583
+ }
10136
10584
  }
10137
10585
  // yml里配置的 不分页和enable_tree:true 优先级最高,组件中输入的top次之。
10138
10586
  options.queryCount = true;
@@ -10191,17 +10639,19 @@ async function getObjectCRUD(objectSchema, fields, options){
10191
10639
  }
10192
10640
  let tableOptions = Object.assign({
10193
10641
  idFieldName: objectSchema.idFieldName, labelFieldName: labelFieldName,
10194
- permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit
10642
+ permissions:objectSchema.permissions,enable_inline_edit:objectSchema.enable_inline_edit,
10643
+ crudId: listSchema.id || id
10195
10644
  }, options);
10196
10645
  tableOptions.amisData = createObject(options.amisData || {}, {});
10197
10646
  const table = await getTableSchema$1(fields, tableOptions);
10198
- delete table.mode;
10647
+ // delete table.mode;
10199
10648
  //image与avatar需要在提交修改时特别处理
10200
10649
  const imageNames = ___default["default"].compact(___default["default"].map(___default["default"].filter(fields, (field) => ["image","avatar"].includes(field.type)), 'name'));
10201
10650
  const quickSaveApiRequestAdaptor = `
10202
10651
  var graphqlOrder = "";
10203
10652
  var imageNames = ${JSON.stringify(imageNames)};
10204
- api.data.rowsDiff.forEach(function (item, index) {
10653
+ const rowsDiff = _.cloneDeep(api.data.rowsDiff);
10654
+ rowsDiff.forEach(function (item, index) {
10205
10655
  for(key in item){
10206
10656
  if(_.includes(imageNames, key)){
10207
10657
  if(typeof item[key] == "string"){
@@ -10215,6 +10665,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10215
10665
  }
10216
10666
  }
10217
10667
  }
10668
+ item = _.omit(item, '_display');
10218
10669
  const itemOrder = 'update' + index + ':' + api.data.objectName + '__update(id:"' + item._id + '", doc:' + JSON.stringify(JSON.stringify(_.omit(item, '_id'))) + ') {_id}';
10219
10670
  graphqlOrder += itemOrder;
10220
10671
  })
@@ -10265,12 +10716,14 @@ async function getObjectCRUD(objectSchema, fields, options){
10265
10716
 
10266
10717
  }
10267
10718
 
10268
- const defaults = options.defaults;
10269
-
10270
- const listSchema = (defaults && defaults.listSchema) || {};
10271
10719
  body = defaultsDeep({}, listSchema, body);
10272
10720
  body = await getCrudSchemaWithDataFilter(body, { crudDataFilter, onCrudDataFilter, amisData, env });
10273
10721
 
10722
+ let crudModeClassName = "";
10723
+ if(body.mode){
10724
+ crudModeClassName = `steedos-crud-mode-${body.mode}`;
10725
+ }
10726
+
10274
10727
  if (defaults) {
10275
10728
  const headerSchema = defaults.headerSchema;
10276
10729
  const footerSchema = defaults.footerSchema;
@@ -10299,7 +10752,7 @@ async function getObjectCRUD(objectSchema, fields, options){
10299
10752
  // TODO: data应该只留loaded,其他属性都改为从上层传递下来
10300
10753
  return {
10301
10754
  type: 'service',
10302
- className: '',
10755
+ className: crudModeClassName,
10303
10756
  //目前crud的service层id不认用户自定义id,只支持默认规则id,许多地方的格式都写死了service_listview_${objectname}
10304
10757
  id: `service_${id}`,
10305
10758
  name: `page`,
@@ -10353,8 +10806,29 @@ const getFormFields = (objectSchema, formProps)=>{
10353
10806
  return lodash.sortBy(___default["default"].values(fields), "sort_no");
10354
10807
  };
10355
10808
 
10809
+ async function getFormSchemaWithDataFilter(form, options = {}){
10810
+ const { formDataFilter, amisData, env } = options;
10811
+ let onFormDataFilter = options.onFormDataFilter;
10812
+ if (!onFormDataFilter && typeof formDataFilter === 'string') {
10813
+ onFormDataFilter = new Function(
10814
+ 'form',
10815
+ 'env',
10816
+ 'data',
10817
+ formDataFilter
10818
+ );
10819
+ }
10820
+
10821
+ try {
10822
+ onFormDataFilter && (form = await onFormDataFilter(form, env, amisData) || form);
10823
+ } catch (e) {
10824
+ console.warn(e);
10825
+ }
10826
+ return form;
10827
+ }
10828
+
10356
10829
  async function getObjectForm(objectSchema, ctx){
10357
- const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults } = ctx;
10830
+ const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults, submitSuccActions = [],
10831
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10358
10832
  const fields = ___default["default"].values(objectSchema.fields);
10359
10833
  const formFields = getFormFields(objectSchema, ctx);
10360
10834
  const formSchema = defaults && defaults.formSchema || {};
@@ -10371,7 +10845,8 @@ async function getObjectForm(objectSchema, ctx){
10371
10845
  name: `page_edit_${recordId}`,
10372
10846
  api: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
10373
10847
  data:{
10374
- editFormInited: false
10848
+ editFormInited: false,
10849
+ ...amisData
10375
10850
  },
10376
10851
  // data: {global: getGlobalData('edit'), recordId: recordId, objectName: objectSchema.name, context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10377
10852
  initApi: null,
@@ -10424,9 +10899,10 @@ async function getObjectForm(objectSchema, ctx){
10424
10899
  },
10425
10900
  "expression": `\${_master.objectName != '${objectSchema.name}' && _master.objectName}`
10426
10901
  },
10902
+ ...submitSuccActions,
10427
10903
  // {
10428
10904
  // "actionType": "custom",
10429
- // "script": "debugger;"
10905
+ // "script": `setTimeout(function(){doAction({'actionType': 'setValue','componentId': '${formSchema.id}','args': {'value': {'sort_no': 879}}})}, 300)`
10430
10906
  // },
10431
10907
  // {
10432
10908
  // "args": {},
@@ -10437,20 +10913,22 @@ async function getObjectForm(objectSchema, ctx){
10437
10913
  }
10438
10914
  })]
10439
10915
  };
10916
+ amisSchema.body[0] = await getFormSchemaWithDataFilter(amisSchema.body[0], { formDataFilter, onFormDataFilter, amisData, env });
10440
10917
  return amisSchema;
10441
10918
  }
10442
10919
 
10443
10920
  async function getObjectDetail(objectSchema, recordId, ctx){
10444
- const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, formInitProps } = ctx;
10921
+ const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign,
10922
+ formDataFilter, onFormDataFilter, amisData, env } = ctx;
10445
10923
  const fields = ___default["default"].values(objectSchema.fields);
10446
10924
  const formFields = getFormFields(objectSchema, ctx);
10447
10925
  const serviceId = `service_detail_page`;
10448
- return {
10926
+ const amisSchema = {
10449
10927
  type: 'service',
10450
10928
  name: `page_readonly_${recordId}`,
10451
10929
  id: serviceId,
10452
10930
  data: {global: getGlobalData('read'), context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
10453
- api: await getReadonlyFormInitApi(objectSchema, recordId, fields, formInitProps),
10931
+ api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
10454
10932
  body: [
10455
10933
  {
10456
10934
  "type": "wrapper", //form 的 hiddenOn 会导致 form onEvent 异常, 使用wrapper包裹一次form,并在wrapper上控制显隐
@@ -10469,7 +10947,11 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10469
10947
  "formData": "$$"
10470
10948
  },
10471
10949
  wrapWithPanel: false,
10472
- body: await getFormBody(_$1.map(fields, (field)=>{field.readonly = true; return field;}), _$1.map(formFields, (field)=>{field.readonly = true; return field;}), Object.assign({}, ctx, {showSystemFields: true,fieldGroups: objectSchema.field_groups})),
10950
+ body: await getFormBody(
10951
+ _$1.map(fields, (field) => { field.readonly = true; return field; }),
10952
+ _$1.map(formFields, (field) => { field.readonly = true; return field; }),
10953
+ Object.assign({}, ctx, { showSystemFields: true, fieldGroups: objectSchema.field_groups })
10954
+ ),
10473
10955
  className: 'steedos-amis-form bg-white',
10474
10956
  actions: [], // 不显示表单默认的提交按钮
10475
10957
  onEvent: {
@@ -10523,7 +11005,10 @@ async function getObjectDetail(objectSchema, recordId, ctx){
10523
11005
  ]
10524
11006
  }
10525
11007
  }
10526
- }
11008
+ };
11009
+
11010
+ amisSchema.body[0].body = await getFormSchemaWithDataFilter(amisSchema.body[0].body, { formDataFilter, onFormDataFilter, amisData, env });
11011
+ return amisSchema;
10527
11012
  }
10528
11013
 
10529
11014
  /*
@@ -10603,7 +11088,7 @@ const getRecordPermissions = async (objectName, recordId)=>{
10603
11088
  * @Author: baozhoutao@steedos.com
10604
11089
  * @Date: 2022-07-05 15:55:39
10605
11090
  * @LastEditors: liaodaxue
10606
- * @LastEditTime: 2023-09-25 17:18:08
11091
+ * @LastEditTime: 2023-11-14 15:55:32
10607
11092
  * @Description:
10608
11093
  */
10609
11094
 
@@ -10894,11 +11379,15 @@ async function getRelatedListSchema(
10894
11379
  ctx
10895
11380
  ) {
10896
11381
  const uiSchema = await getUISchema(objectName);
11382
+ if(!uiSchema){
11383
+ return {}
11384
+ }
11385
+ const listViewNames = _$1.map(uiSchema.list_views, 'name');
10897
11386
  const listView = _$1.find(
10898
11387
  uiSchema.list_views,
10899
11388
  (listView, name) => {
10900
- // 传入listViewName空值则取第一个
10901
- if(!listViewName){
11389
+ // 传入listViewName空值 或者 不存在 则取第一个
11390
+ if(!listViewName || listViewNames.indexOf(listViewName)<0){
10902
11391
  listViewName = name;
10903
11392
  }
10904
11393
  return name === listViewName || listView._id === listViewName;
@@ -10947,7 +11436,11 @@ async function getRelatedListSchema(
10947
11436
  if(setDataToComponentId){
10948
11437
  if(payload.data.count){
10949
11438
  setTimeout(function(){
10950
- window.$("." + setDataToComponentId + " .antd-Crud").removeClass("hidden");
11439
+ // 设计器中获取不到window.$从而导致报错, 所以用纯js替换下。
11440
+ // window.$("." + setDataToComponentId + " .antd-Crud").removeClass("hidden");
11441
+ document.querySelectorAll("." + setDataToComponentId + " .antd-Crud").forEach(function(element) {
11442
+ element.classList.remove("hidden");
11443
+ });
10951
11444
  }, 10);
10952
11445
  }
10953
11446
  };
@@ -10978,8 +11471,8 @@ async function getRelatedListSchema(
10978
11471
  /*
10979
11472
  * @Author: baozhoutao@steedos.com
10980
11473
  * @Date: 2022-07-05 15:55:39
10981
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
10982
- * @LastEditTime: 2023-09-21 17:35:06
11474
+ * @LastEditors: liaodaxue
11475
+ * @LastEditTime: 2023-10-20 11:38:25
10983
11476
  * @Description:
10984
11477
  */
10985
11478
 
@@ -11308,8 +11801,8 @@ async function getListSchema(
11308
11801
  "filtersFunction": listview_filters,
11309
11802
  "sort": sort,
11310
11803
  "ctx": ctx,
11311
- "requestAdaptor": listView.requestAdaptor,
11312
- "adaptor": listView.adaptor,
11804
+ "requestAdaptor": listView.requestAdaptor || ctx.requestAdaptor,
11805
+ "adaptor": listView.adaptor || ctx.adaptor,
11313
11806
  "headerToolbarItems": ctx.headerToolbarItems,
11314
11807
  "filterVisible": ctx.filterVisible,
11315
11808
  "rowClassNameExpr": ctx.rowClassNameExpr,
@@ -13954,10 +14447,18 @@ const getOpinionFieldStepsName = (field, top_keywords) => {
13954
14447
  * @Author: baozhoutao@steedos.com
13955
14448
  * @Date: 2022-09-09 17:47:37
13956
14449
  * @LastEditors: baozhoutao@steedos.com
13957
- * @LastEditTime: 2023-03-18 15:32:34
14450
+ * @LastEditTime: 2023-10-10 13:57:02
13958
14451
  * @Description:
13959
14452
  */
13960
14453
 
14454
+ const getMoment = ()=>{
14455
+ if(window.amisRequire){
14456
+ return window.amisRequire("moment");
14457
+ }else if(window.moment){
14458
+ return window.moment;
14459
+ }
14460
+ };
14461
+
13961
14462
  const getTrace = ({ instance, traceId }) => {
13962
14463
  return _$1.find(instance.traces, (trace) => {
13963
14464
  return trace._id === traceId;
@@ -14177,6 +14678,8 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14177
14678
  method: "get",
14178
14679
  });
14179
14680
 
14681
+ const moment = getMoment();
14682
+
14180
14683
  return {
14181
14684
  box: box,
14182
14685
  _id: instanceId,
@@ -14187,7 +14690,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14187
14690
  applicant_name: instance.applicant_name,
14188
14691
  submitter: instance.submitter,
14189
14692
  submit_date: instance.submit_date
14190
- ? amisRequire("moment")(instance.submit_date).format("YYYY-MM-DD")
14693
+ ? (moment && moment(instance.submit_date).format("YYYY-MM-DD"))
14191
14694
  : "",
14192
14695
  state: instance.state,
14193
14696
  approveValues: values,
@@ -14227,8 +14730,7 @@ const getInstanceInfo = async ({ instanceId, box }) => {
14227
14730
  finishDate = approve.is_read ? "已读" : "未处理";
14228
14731
  judge = null;
14229
14732
  } else {
14230
- finishDate =
14231
- amisRequire("moment")(finishDate).format("YYYY-MM-DD HH:mm");
14733
+ finishDate = moment && moment(finishDate).format("YYYY-MM-DD HH:mm");
14232
14734
  }
14233
14735
 
14234
14736
  switch (judge) {
@@ -14318,6 +14820,7 @@ exports.getFileSrc = getFileSrc;
14318
14820
  exports.getFlowFormSchema = getFlowFormSchema;
14319
14821
  exports.getFormPageInitSchema = getFormPageInitSchema;
14320
14822
  exports.getFormSchema = getFormSchema;
14823
+ exports.getGlobalNowData = getGlobalNowData;
14321
14824
  exports.getIdsPickerSchema = getIdsPickerSchema;
14322
14825
  exports.getImageSrc = getImageSrc;
14323
14826
  exports.getInstanceInfo = getInstanceInfo;