@steedos-widgets/amis-lib 3.6.2-beta.1 → 3.6.2-beta.10

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
@@ -367,22 +367,26 @@ const getSteedosAuth = () => {
367
367
  * @Description:
368
368
  */
369
369
 
370
-
371
370
  const Router = {
372
371
  getTabDisplayAs(tab_id){
372
+ const uiSchema = getUISchemaSync$1(tab_id, false);
373
373
  var urlSearch = new URLSearchParams(document.location.search);
374
374
  if(urlSearch.has('display')){
375
375
  return urlSearch.get('display')
376
376
  }
377
377
  const key = `tab_${tab_id}_display`;
378
378
  // const key = `page_display`;
379
- const value = localStorage.getItem(key);
380
- return value ? value : 'grid'
379
+ const value = sessionStorage.getItem(key);
380
+ let defaultDisplay = "grid";
381
+ if(uiSchema.enable_split){
382
+ defaultDisplay = "split";
383
+ }
384
+ return value ? value : defaultDisplay;
381
385
  },
382
386
 
383
387
  setTabDisplayAs(tab_id, displayAs){
384
388
  const key = `tab_${tab_id}_display`;
385
- localStorage.setItem(key, displayAs);
389
+ sessionStorage.setItem(key, displayAs);
386
390
  },
387
391
  getAppPath({formFactor, appId}){
388
392
  return `/app/${appId}`;
@@ -486,7 +490,7 @@ function getComparableAmisVersion() {
486
490
  * @Author: baozhoutao@steedos.com
487
491
  * @Date: 2022-05-23 09:53:08
488
492
  * @LastEditors: liaodaxue
489
- * @LastEditTime: 2023-10-11 17:32:17
493
+ * @LastEditTime: 2024-01-17 16:00:27
490
494
  * @Description:
491
495
  */
492
496
 
@@ -558,7 +562,7 @@ function getSelectMap(selectOptions){
558
562
 
559
563
  function getNameTplUrl(field, ctx){
560
564
  if(ctx.objectName === 'cms_files'){
561
- return `\${context.rootUrl}/api/files/files/\${versions[0]}?download=true`
565
+ return "${(versions[0] && versions[0].url) ? versions[0].url+'?download=true' : context.rootUrl+'/api/files/files/'+versions[0]+'?download=true'}"
562
566
  }
563
567
  const href = Router.getObjectDetailPath({
564
568
  ...ctx, formFactor: ctx.formFactor, appId: "${appId}", objectName: ctx.objectName || "${objectName}", recordId: `\${${ctx.idFieldName}}`
@@ -1430,9 +1434,9 @@ var frontend_display_type_is_split = "分栏视图";
1430
1434
  var frontend_display_as = "显示为";
1431
1435
  var frontend_record_sum = "个项目";
1432
1436
  var frontend_button_reload_tooltip = "刷新";
1433
- var frontend_button_search_tooltip = "筛选";
1437
+ var frontend_button_search_tooltip = "搜索";
1434
1438
  var frontend_fields_filter_button_search = "搜索";
1435
- var frontend_fields_filter_button_settings = "设置搜索项";
1439
+ var frontend_fields_filter_button_settings = "选择搜索项";
1436
1440
  var frontend_button_listview_control_tooltip = "列表视图控制";
1437
1441
  var frontend_button_listview_control_label = "列表视图控制";
1438
1442
  var frontend_listview_control_columns = "显示的列";
@@ -2087,9 +2091,13 @@ async function getTableColumns(fields, options){
2087
2091
  const quickEditSchema = allowEdit ? await getQuickEditSchema(field, options) : allowEdit;
2088
2092
  let className = "";
2089
2093
  if(field.wrap != true){
2090
- className += " whitespace-nowrap ";
2094
+ if(field.wrap != false && field.is_wide){
2095
+ className += " break-words ";
2096
+ }else {
2097
+ className += " whitespace-nowrap ";
2098
+ }
2091
2099
  }else {
2092
- className += " break-all ";
2100
+ className += " break-words ";
2093
2101
  }
2094
2102
  let columnItem;
2095
2103
  if((field.is_name || field.name === options.labelFieldName) && options.objectName === 'cms_files'){
@@ -2186,12 +2194,24 @@ async function getTableColumns(fields, options){
2186
2194
  if(field.type === 'textarea'){
2187
2195
  className += 'min-w-56';
2188
2196
  }
2189
- if(field.type === 'date'){
2190
- className += 'date-min-w';
2191
- }
2192
- if(field.type === 'datetime'){
2193
- className += 'datetime-min-w';
2197
+ // if(field.type === 'date'){
2198
+ // className += 'date-min-w';
2199
+ // }
2200
+ // if(field.type === 'datetime'){
2201
+ // className += 'datetime-min-w';
2202
+ // }
2203
+
2204
+ //field上的amis属性里的clssname需要单独判断类型合并
2205
+ if (typeof field.amis?.className == "object") {
2206
+ className = {
2207
+ [className]: "true",
2208
+ ...field.amis.className
2209
+ };
2210
+ } else if (typeof field.amis?.className == "string") {
2211
+ className = `${className} ${field.amis.className} `;
2194
2212
  }
2213
+ delete field.amis?.className;
2214
+
2195
2215
  if(!field.hidden && !field.extra){
2196
2216
  columnItem = Object.assign({}, {
2197
2217
  name: field.name,
@@ -2274,7 +2294,7 @@ function getMobileLines(tpls){
2274
2294
  }
2275
2295
  if(isLeft){
2276
2296
  // 左侧半行
2277
- lineChildrenClassName = "steedos-listview-item-left truncate";
2297
+ lineChildrenClassName = "steedos-listview-item-left truncate h-5";
2278
2298
  if(item.field.is_wide){
2279
2299
  // 左侧全行样式可以单独写,如果需要配置两行省略号效果,可以加样式类 two-lines-truncate
2280
2300
  lineChildrenClassName = "steedos-listview-item-wide";
@@ -2286,14 +2306,26 @@ function getMobileLines(tpls){
2286
2306
  }
2287
2307
  else {
2288
2308
  // 右侧半行,这里加样式类 flex flex-shrink-0,是为了省略号只显示在左半行,右半行文字一般比较短,如果也加省略号效果的话,左侧文字多的话,右侧没几个字就显示省略号了
2289
- lineChildrenClassName = "steedos-listview-item-right truncate ml-2 flex flex-shrink-0";
2309
+ lineChildrenClassName = "steedos-listview-item-right truncate ml-2 flex flex-shrink-0 h-5";
2310
+ }
2311
+ //支持字段amis属性配置classname,识别classname的类型,与原样式合并
2312
+ var className;
2313
+ if (typeof item.field.amis?.className == "object") {
2314
+ className = {
2315
+ [lineChildrenClassName]: "true",
2316
+ ...item.field.amis.className
2317
+ };
2318
+ } else if (typeof item.field.amis?.className == "string") {
2319
+ className = `${lineChildrenClassName} ${item.field.amis.className} `;
2320
+ } else {
2321
+ className = lineChildrenClassName;
2290
2322
  }
2291
2323
  lineChildren.push({
2292
2324
  "type": "tpl",
2293
2325
  "tpl": item.tpl,
2294
- "className": lineChildrenClassName
2326
+ className
2295
2327
  });
2296
-
2328
+
2297
2329
  if(item.field.is_wide){
2298
2330
  // 宽字段占整行
2299
2331
  isLeft = true;
@@ -2343,8 +2375,7 @@ async function getMobileTableColumns(fields, options){
2343
2375
  tpl = await getFieldTpl(field, options);
2344
2376
  }
2345
2377
  if(!tpl){
2346
- //qhd需求简易处理,加上raw以支持审批王名称字段通过颜色区分缓急,若之后手机端列表支持配置amis,则可以去掉
2347
- tpl = `\${${field.name} | raw}`;
2378
+ tpl = `\${${field.name}}`;
2348
2379
  }
2349
2380
  if(!field.hidden && !field.extra){
2350
2381
  tpls.push({ field, tpl });
@@ -2357,7 +2388,7 @@ async function getMobileTableColumns(fields, options){
2357
2388
 
2358
2389
  let column = {
2359
2390
  name: nameField.name,
2360
- label: nameField.label,
2391
+ label: options.displayAs == 'split' ? '' : nameField.label,
2361
2392
  sortable: nameField.sortable,
2362
2393
  type: "button",
2363
2394
  level: "link",
@@ -2386,7 +2417,15 @@ async function getMobileTableColumns(fields, options){
2386
2417
  "actions": [
2387
2418
  {
2388
2419
  "script": `
2389
- let cms_url = "/api/files/files/"+event.data.versions[0]+"?download=true"
2420
+ let cms_url = '';
2421
+ let value = event.data.versions[0];
2422
+ if(value){
2423
+ if(value.url){
2424
+ cms_url = value.url;
2425
+ }else{
2426
+ cms_url = "/api/files/files/"+value+"?download=true"
2427
+ }
2428
+ }
2390
2429
  Steedos.cordovaDownload(encodeURI(Steedos.absoluteUrl(cms_url)), event.data.name);
2391
2430
  `,
2392
2431
  "actionType": "custom"
@@ -2502,7 +2541,8 @@ async function getTableOperation(ctx){
2502
2541
  label: " ",
2503
2542
  fixed: 'right',
2504
2543
  labelClassName: 'text-center',
2505
- className: 'text-center steedos-listview-operation w-10',
2544
+ //TODO:目前3.6.3-patch.3版本中对于动态classname处理存在问题,简单处理固定列问题,等待amis解决crud的columns不支持动态classname的问题
2545
+ className: 'text-center steedos-listview-operation w-10 is-sticky is-sticky-right is-sticky-first-right',
2506
2546
  buttons: [
2507
2547
  {
2508
2548
  "type": "steedos-dropdown-button",
@@ -2598,7 +2638,7 @@ async function getTableSchema$1(fields, options){
2598
2638
  }
2599
2639
  return {
2600
2640
  mode: "cards",
2601
- perPageAvailable: [5, 10, 20, 50, 100, 500],
2641
+ perPageAvailable: [20, 50, 100, 500],
2602
2642
  name: "thelist",
2603
2643
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
2604
2644
  className: "",
@@ -2631,7 +2671,7 @@ async function getTableSchema$1(fields, options){
2631
2671
 
2632
2672
  return {
2633
2673
  mode: "table",
2634
- perPageAvailable: [5, 10, 20, 50, 100, 500],
2674
+ perPageAvailable: [20, 50, 100, 500],
2635
2675
  name: "thelist",
2636
2676
  headerToolbarClassName: "py-2 px-2 border-gray-300 border-solid border-b",
2637
2677
  className: "",
@@ -3017,6 +3057,16 @@ async function getTableApi(mainObject, fields, options){
3017
3057
  }
3018
3058
  // SteedosUI.getRef(api.body.$self.$scopeId)?.parent?.getComponentById(setDataToComponentId)?.setData({$count: payload.data.count})
3019
3059
  };
3060
+ let formFactor = "${options.formFactor}";
3061
+ if(formFactor !== "SMALL"){
3062
+ const listviewComponent = $(".steedos-object-listview .antd-Table-table");
3063
+ const firstListviewComponent = listviewComponent && listviewComponent[0];
3064
+ if(firstListviewComponent){
3065
+ setTimeout(()=>{
3066
+ firstListviewComponent.scrollIntoView();
3067
+ }, 600);
3068
+ }
3069
+ }
3020
3070
  ${options.adaptor || ''}
3021
3071
  return payload;
3022
3072
  `;
@@ -3128,12 +3178,21 @@ function getReadonlyFormAdaptor(object, fields, options){
3128
3178
  }
3129
3179
  payload.data = data;
3130
3180
  payload.data.__objectName = "${object.name}";
3131
- payload.data.__record = record;
3181
+ payload.data.record = record;
3182
+
3183
+ payload.data.NAME_FIELD_VALUE = record.${object.NAME_FIELD_KEY || 'name'};
3184
+ payload.data._master = {
3185
+ record: record,
3186
+ objectName: "${object.name}",
3187
+ recordId: record._id
3188
+ }
3132
3189
  window.postMessage(Object.assign({type: "record.loaded"}, {record: record}), "*")
3133
3190
  }
3134
3191
  if(payload.errors){
3135
3192
  payload.status = 2;
3136
3193
  payload.msg = payload.errors[0].message;
3194
+ }else{
3195
+ payload.data.recordLoaded = true;
3137
3196
  }
3138
3197
  ${options && options.initApiAdaptor || ''}
3139
3198
  return payload;
@@ -3276,7 +3335,7 @@ async function getEditFormInitApi(object, recordId, fields, options){
3276
3335
  cache: API_CACHE,
3277
3336
  requestAdaptor: `
3278
3337
  // 所有不想在network请求中发送的数据都应该从data中分离出来,data变量只需要留下query才需要发送出去
3279
- var { recordId, objectName, uiSchema, global, context, ...data} = api.data;
3338
+ var { recordId, objectName, uiSchema, global, context, _master, ...data} = api.data;
3280
3339
  if(!recordId){
3281
3340
  // 新建则不请求任何数据
3282
3341
  data.query = "{data:" + objectName + "(filters: " + JSON.stringify(["_id", "=", null]) + ", top: 1){_id}}";
@@ -3354,10 +3413,11 @@ async function getEditFormInitApi(object, recordId, fields, options){
3354
3413
  ...initialValues
3355
3414
  }
3356
3415
  ${options.initApiAdaptor || ''}
3416
+ // console.log('getEditFormInitApi======>', payload);
3357
3417
  return payload;
3358
3418
  `,
3359
3419
  responseData: {
3360
- initialValues: "$$",
3420
+ "&": "$$",
3361
3421
  editFormInited: true
3362
3422
  },
3363
3423
  data: data,
@@ -3396,6 +3456,18 @@ function getBatchDelete(objectName){
3396
3456
  return {
3397
3457
  method: 'post',
3398
3458
  url: getApi$2(),
3459
+ adaptor: `
3460
+ if(payload.errors){
3461
+ payload.data.deleteErrorMessage = [];
3462
+ payload.errors.forEach(function(error){
3463
+ let errorRecord = error.path.map(function (item) {
3464
+ return item.split('delete__')[1].to_float() + 1;
3465
+ }).toString();
3466
+ payload.data.deleteErrorMessage.push("第" + errorRecord + "条记录删除出现异常,报错信息为(" + (window.t ? window.t(error.message) : error.message) + ")");
3467
+ })
3468
+ }
3469
+ return payload;
3470
+ `,
3399
3471
  requestAdaptor: `
3400
3472
  var ids = api.data.ids.split(",");
3401
3473
  var deleteArray = [];
@@ -4190,7 +4262,7 @@ async function getListBody(fields, options){
4190
4262
 
4191
4263
  function getDefaultParams(options){
4192
4264
  return {
4193
- perPage: options.top || options.perPage || 10
4265
+ perPage: options.top || options.perPage || 20
4194
4266
  }
4195
4267
  }
4196
4268
 
@@ -4393,7 +4465,6 @@ const getSchema$5 = async (uiSchema, ctx) => {
4393
4465
  "objectApiName": "\${objectName}",
4394
4466
  "recordId": "",
4395
4467
  "mode": "edit",
4396
- "layout": "normal"
4397
4468
  };
4398
4469
 
4399
4470
  if (payload && payload.schema) {
@@ -5098,7 +5169,7 @@ const StandardButtons = {
5098
5169
  }
5099
5170
  };
5100
5171
 
5101
- const getGlobalData$1 = () => {
5172
+ const getGlobalData = () => {
5102
5173
  return {
5103
5174
  now: new Date(),
5104
5175
  };
@@ -5157,7 +5228,7 @@ const getButtonVisible = (button, ctx) => {
5157
5228
  button._visible,
5158
5229
  props.record,
5159
5230
  "#",
5160
- getGlobalData$1(),
5231
+ getGlobalData(),
5161
5232
  props.userSession
5162
5233
  );
5163
5234
  };
@@ -6535,6 +6606,48 @@ function getObjectListHeader$1(objectSchema, listViewName, ctx) {
6535
6606
  return headerSchema;
6536
6607
  }
6537
6608
 
6609
+ function getBackButtonSchema(){
6610
+ return {
6611
+ "type": "service",
6612
+ "onEvent": {
6613
+ "@history_paths.changed": {
6614
+ "actions": [
6615
+ {
6616
+ "actionType": "reload",
6617
+ // amis 3.6需要传入data来触发下面的window:historyPaths重新计算,此问题随机偶发,加上data后正常
6618
+ "data": {
6619
+ }
6620
+ }
6621
+ ]
6622
+ }
6623
+ },
6624
+ "body":[{
6625
+ "type": "button",
6626
+ "visibleOn": "${window:innerWidth > 768 && (window:historyPaths.length > 1 || window:historyPaths[0].params.record_id) && display !== 'split'}",
6627
+ "className":"flex mr-4",
6628
+ "onEvent": {
6629
+ "click": {
6630
+ "actions": [
6631
+ {
6632
+ "actionType": "custom",
6633
+ "script": "window.goBack()"
6634
+ }
6635
+ ]
6636
+ }
6637
+ },
6638
+ "body": [
6639
+ {
6640
+ "type": "steedos-icon",
6641
+ "category": "utility",
6642
+ "name": "back",
6643
+ "colorVariant": "default",
6644
+ "className": "slds-button_icon slds-global-header__icon w-4"
6645
+ }
6646
+ ]
6647
+ }]
6648
+ }
6649
+ }
6650
+
6538
6651
  /**
6539
6652
  * 记录详细界面顶部头amisSchema,也是标题面板组件的amisSchema
6540
6653
  * @param {*} objectSchema 对象UISchema
@@ -6543,11 +6656,21 @@ function getObjectListHeader$1(objectSchema, listViewName, ctx) {
6543
6656
  * @returns amisSchema
6544
6657
  */
6545
6658
  async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6659
+ // console.log(`getObjectRecordDetailHeader====>`, options)
6546
6660
  const { showRecordTitle = true } = options || {};
6547
6661
  // console.log('getObjectRecordDetailHeader==>', objectSchema, recordId)
6548
6662
  const { name, label, icon, NAME_FIELD_KEY } = objectSchema;
6549
6663
 
6550
- let amisButtonsSchema = getObjectDetailButtonsSchemas(objectSchema, recordId, options);
6664
+ let amisButtonsSchema = [];
6665
+ if(options.showButtons != false){
6666
+ amisButtonsSchema = getObjectDetailButtonsSchemas(objectSchema, recordId, options);
6667
+ }
6668
+
6669
+ let backButtonsSchema = null;
6670
+
6671
+ if(options.showBackButton != false){
6672
+ backButtonsSchema = getBackButtonSchema();
6673
+ }
6551
6674
 
6552
6675
  // console.log(`getObjectRecordDetailHeader==>`, amisButtonsSchema)
6553
6676
 
@@ -6562,45 +6685,9 @@ async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6562
6685
  "type": "grid",
6563
6686
  "columns": [
6564
6687
  {
6565
- "body": [{
6566
- "type": "service",
6567
- "onEvent": {
6568
- "@history_paths.changed": {
6569
- "actions": [
6570
- {
6571
- "actionType": "reload",
6572
- // amis 3.6需要传入data来触发下面的window:historyPaths重新计算,此问题随机偶发,加上data后正常
6573
- "data": {
6574
- }
6575
- }
6576
- ]
6577
- }
6578
- },
6579
- "body":[{
6580
- "type": "button",
6581
- "visibleOn": "${window:innerWidth > 768 && (window:historyPaths.length > 1 || window:historyPaths[0].params.record_id) && display !== 'split'}",
6582
- "className":"flex mr-4",
6583
- "onEvent": {
6584
- "click": {
6585
- "actions": [
6586
- {
6587
- "actionType": "custom",
6588
- "script": "window.goBack()"
6589
- }
6590
- ]
6591
- }
6592
- },
6593
- "body": [
6594
- {
6595
- "type": "steedos-icon",
6596
- "category": "utility",
6597
- "name": "back",
6598
- "colorVariant": "default",
6599
- "className": "slds-button_icon slds-global-header__icon w-4"
6600
- }
6601
- ]
6602
- }]
6603
- },{
6688
+ "body": [
6689
+ backButtonsSchema
6690
+ ,{
6604
6691
  "type": "tpl",
6605
6692
  "className": "block",
6606
6693
  // "tpl": `<img class='slds-icon slds-icon_container slds-icon-standard-${standardIcon}' src='\${context.rootUrl}/unpkg.com/@salesforce-ux/design-system/assets/icons/standard/${icon}.svg'>`
@@ -6621,8 +6708,7 @@ async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6621
6708
  },
6622
6709
  {
6623
6710
  "type": "tpl",
6624
- "tpl": "${name}",
6625
- // "tpl": "${(record && uiSchema && record[uiSchema.NAME_FIELD_KEY]) || name}",
6711
+ "tpl": "${NAME_FIELD_VALUE}",
6626
6712
  "inline": false,
6627
6713
  "wrapperComponent": "",
6628
6714
  "className": "record-detail-header-name leading-5 text-xl font-bold"
@@ -6650,7 +6736,7 @@ async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6650
6736
  let body = [
6651
6737
  {
6652
6738
  "type": "wrapper",
6653
- "className": "p-0",
6739
+ "className": "p-4 bg-gray-100 border-b",
6654
6740
  "body": [
6655
6741
  {
6656
6742
  "type": "grid",
@@ -6665,7 +6751,7 @@ async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6665
6751
  if(showRecordTitle){
6666
6752
  body.push({
6667
6753
  "type": "wrapper",
6668
- "className": "p-0",
6754
+ "className": "p-4",
6669
6755
  "body": [
6670
6756
  {
6671
6757
  "type": "grid",
@@ -6677,11 +6763,76 @@ async function getObjectRecordDetailHeader(objectSchema, recordId, options) {
6677
6763
  });
6678
6764
  }
6679
6765
 
6766
+ let max = 10;
6767
+ if(options.formFactor === 'SMALL'){
6768
+ max = 4;
6769
+ }else {
6770
+
6771
+ let divWidth = window.innerWidth;
6772
+
6773
+ if(options.display === 'split'){
6774
+ divWidth = divWidth - 388;
6775
+ }
6776
+
6777
+ if(document.body.classList.contains('sidebar')){
6778
+ divWidth = divWidth - 210;
6779
+ }
6780
+
6781
+ // 根据屏幕宽度计算显示数量, 使高亮字段只占1行
6782
+ max = Math.trunc(divWidth / 200 );
6783
+ if(max > 10){
6784
+ max = 10;
6785
+ }
6786
+ }
6787
+
6788
+ // console.log('=======================max=========================', max)
6789
+
6790
+ if(objectSchema.compactLayouts){
6791
+ const details = [];
6792
+ _.each(_.slice(_.difference(objectSchema.compactLayouts, [objectSchema.NAME_FIELD_KEY]), 0, max), (fieldName)=>{
6793
+ const field = objectSchema.fields[fieldName];
6794
+ if(field){
6795
+ details.push({
6796
+ type: 'steedos-field',
6797
+ static: true,
6798
+ config: field,
6799
+ });
6800
+ }
6801
+ });
6802
+
6803
+ // 注意: 以下注释不能删除. tailwind css 动态编译时会识别以下注释, 生成对应的样式
6804
+ // lg:grid-cols-1
6805
+ // lg:grid-cols-2
6806
+ // lg:grid-cols-3
6807
+ // lg:grid-cols-4
6808
+ // lg:grid-cols-5
6809
+ // lg:grid-cols-6
6810
+ // lg:grid-cols-7
6811
+ // lg:grid-cols-8
6812
+ // lg:grid-cols-9
6813
+ // lg:grid-cols-10
6814
+ // lg:grid-cols-11
6815
+ // lg:grid-cols-12
6816
+
6817
+ body.push({
6818
+ "type": "wrapper",
6819
+ "body": {
6820
+ "type": "form",
6821
+ // "className": "gap-2 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-5 3xl:grid-cols-8 4xl:grid-cols-8 5xl:grid-cols-10", //max-h-12 overflow-hidden
6822
+ "className": `gap-2 grid grid-cols-1 lg:grid-cols-${max}`,
6823
+ "wrapWithPanel": false,
6824
+ "actions": [],
6825
+ "body": details,
6826
+ "hiddenOn": "${recordLoaded != true}"
6827
+ },
6828
+ "className": "steedos-record-compact-layouts p-4 bg-white compact-layouts border-b"
6829
+ });
6830
+ }
6831
+
6680
6832
  return {
6681
6833
  type: 'service',
6682
6834
  id: `page_readonly_${name}_header`,
6683
6835
  name: `page`,
6684
- data: { objectName: name, _id: recordId, recordPermissions: objectSchema.permissions, uiSchema: objectSchema, record: "${record}" },
6685
6836
  body: body,
6686
6837
  className: ''
6687
6838
  }
@@ -6753,7 +6904,7 @@ async function getObjectRecordDetailRelatedListHeader(relatedObjectSchema, relat
6753
6904
  "className": "flex justify-between"
6754
6905
  }
6755
6906
  ],
6756
- "className": "p-3"
6907
+ "className": "steedos-record-related-header py-2 px-0"
6757
6908
  };
6758
6909
  return recordRelatedListHeader;
6759
6910
  }
@@ -7738,14 +7889,14 @@ const getDisplayAsButton = function(objectName, showDisplayAs){
7738
7889
  {
7739
7890
  "type": "button",
7740
7891
  "label": i18next__default["default"].t('frontend_display_type_is_table'),
7741
- "onClick": "const key = 'tab_"+objectName+"_display';localStorage.setItem(key, 'grid');let url = document.location.pathname; var urlSearch = new URLSearchParams(document.location.search); if(urlSearch.get(\"side_object\") && urlSearch.get(\"side_listview_id\")){url=`/app/${props.data.appId}/${urlSearch.get(\"side_object\")}/grid/${urlSearch.get(\"side_listview_id\")}`;}; props.env.jumpTo(url + '?display=grid');",
7892
+ "onClick": "const key = 'tab_"+objectName+"_display';sessionStorage.setItem(key, 'grid');let url = document.location.pathname; var urlSearch = new URLSearchParams(document.location.search); if(urlSearch.get(\"side_object\") && urlSearch.get(\"side_listview_id\")){url=`/app/${props.data.appId}/${urlSearch.get(\"side_object\")}/grid/${urlSearch.get(\"side_listview_id\")}`;}; props.env.jumpTo(url + '?display=grid');",
7742
7893
  "rightIcon": displayAs != 'split' ? "fa fa-check" : null,
7743
7894
  "rightIconClassName": "m-l-sm"
7744
7895
  },
7745
7896
  {
7746
7897
  "type": "button",
7747
7898
  "label": i18next__default["default"].t('frontend_display_type_is_split'),
7748
- "onClick": "const key = 'tab_"+objectName+"_display';localStorage.setItem(key, 'split');const url = document.location.pathname + '?display=split'; props.env.jumpTo(url);",
7899
+ "onClick": "const key = 'tab_"+objectName+"_display';sessionStorage.setItem(key, 'split');const url = document.location.pathname + '?display=split'; props.env.jumpTo(url);",
7749
7900
  "rightIcon": displayAs === 'split' ? "fa fa-check" : null,
7750
7901
  "rightIconClassName": "m-l-sm"
7751
7902
  }
@@ -7888,7 +8039,7 @@ function getObjectHeaderQuickSearchBox(mainObject, fields, formFactor, { isLooku
7888
8039
  {
7889
8040
  "type": "search-box",
7890
8041
  "name": keywordsSearchBoxName,
7891
- "placeholder": "搜索此列表",
8042
+ "placeholder": "快捷搜索",
7892
8043
  "value": crudKeywords,
7893
8044
  // "clearable": true,//因为清除并不会触发失去焦点事件,只有禁用,但是它会触发change事件,所以等升级到amis 3.4+后可以重新放开
7894
8045
  "clearAndSubmit": true,
@@ -8092,7 +8243,10 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
8092
8243
  // ]
8093
8244
  if(options.displayAs === 'split'){
8094
8245
  return [
8095
- "switch-per-page",
8246
+ {
8247
+ "type": "switch-per-page",
8248
+ "visibleOn": "${count >= 20}"
8249
+ },
8096
8250
  {
8097
8251
  "type": "pagination",
8098
8252
  "maxButtons": 5,
@@ -8114,7 +8268,6 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
8114
8268
  else {
8115
8269
  if(options && options.isRelated){
8116
8270
  return [
8117
- "statistics",
8118
8271
  {
8119
8272
  "type": "pagination",
8120
8273
  "maxButtons": 10,
@@ -8127,7 +8280,6 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
8127
8280
  const no_pagination = mainObject.paging && (mainObject.paging.enabled === false);
8128
8281
  const is_lookup = options.isLookup;
8129
8282
  const commonConfig = [
8130
- "statistics",
8131
8283
  {
8132
8284
  "type": "pagination",
8133
8285
  "maxButtons": 10,
@@ -8138,7 +8290,10 @@ function getObjectFooterToolbar(mainObject, formFactor, options) {
8138
8290
  if (no_pagination && is_lookup) {
8139
8291
  return commonConfig;
8140
8292
  } else {
8141
- return ["switch-per-page", ...commonConfig];
8293
+ return [{
8294
+ "type": "switch-per-page",
8295
+ "visibleOn": "${count >= 20}"
8296
+ }, ...commonConfig];
8142
8297
  }
8143
8298
  }
8144
8299
  }
@@ -8246,6 +8401,29 @@ function getBulkActions(objectSchema){
8246
8401
  "className": "hidden",
8247
8402
  "id": "batchDelete",
8248
8403
  "api": getBatchDelete(objectSchema.name),
8404
+ "feedback": {
8405
+ "title": "删除警告",
8406
+ "visibleOn": "${deleteErrorMessage}",
8407
+ "body": [
8408
+ {
8409
+ "type": "each",
8410
+ "name": "deleteErrorMessage",
8411
+ "items": {
8412
+ "type": "alert",
8413
+ "body": "${item}",
8414
+ "level": "danger",
8415
+ "className": "mb-3"
8416
+ }
8417
+ }
8418
+ ],
8419
+ "actions": [
8420
+ {
8421
+ "type": "button",
8422
+ "actionType": "close",
8423
+ "label": "关闭"
8424
+ }
8425
+ ]
8426
+ }
8249
8427
  }
8250
8428
  // {
8251
8429
  // "label": "批量修改",
@@ -8392,6 +8570,10 @@ async function getObjectCRUD(objectSchema, fields, options){
8392
8570
  const rowsDiff = _.cloneDeep(api.data.rowsDiff);
8393
8571
  rowsDiff.forEach(function (item, index) {
8394
8572
  for(key in item){
8573
+ // image、select等字段清空值后保存的空字符串转换为null。
8574
+ if(item[key] === ''){
8575
+ item[key] = null;
8576
+ }
8395
8577
  if(_.includes(imageNames, key)){
8396
8578
  if(typeof item[key] == "string"){
8397
8579
  const match = item[key].match(/\\/([^\\/]+)$/);
@@ -8438,7 +8620,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8438
8620
  // "is-steedos-crud-data-empty": "${!items || COUNT(items) == 0}"
8439
8621
  // },
8440
8622
  bodyClassName: {
8441
- "bg-white": "true",
8623
+ "mb-0": true,
8442
8624
  "is-steedos-crud-data-empty": "${!items || COUNT(items) == 0}"
8443
8625
  },
8444
8626
  crudClassName: crudClassName,
@@ -8458,7 +8640,9 @@ async function getObjectCRUD(objectSchema, fields, options){
8458
8640
  return payload;
8459
8641
  `
8460
8642
  },
8461
- rowClassNameExpr: options.rowClassNameExpr
8643
+ // 外层data发生变化的时候, 不会重新渲染rowClassNameExpr, 所以先用css标记tr唯一标识
8644
+ // 使用表达式给tr添加初始选中状态
8645
+ rowClassNameExpr: options.rowClassNameExpr || "<%= data._id === data.recordId ? 'steedos-record-tr steedos-record-tr-' + data._id + ' steedos-record-selected' : 'steedos-record-tr steedos-record-tr-' + data._id %>"
8462
8646
  }, bodyProps);
8463
8647
 
8464
8648
  }
@@ -8473,7 +8657,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8473
8657
 
8474
8658
  if(body.columns && options.formFactor != 'SMALL'){
8475
8659
  //将_display放入crud的columns的倒数第二列中(最后一列会影响固定列),可以通过setvalue修改行内数据域的_display,而不影响上层items的_display,用于批量编辑
8476
- body.columns.splice(body.columns.length - 1, 0, {name: '_display',type: 'static', width: 32, placeholder: "",id: objectSchema.name + "_display_${_index}", className: "hidden"});
8660
+ body.columns.splice(body.columns.length -1 , 0, {name: '_display',type: 'static', width: 1, placeholder: "",id: objectSchema.name + "_display_${_index}", tpl: "${''}"});
8477
8661
  }
8478
8662
 
8479
8663
  if (defaults) {
@@ -8531,11 +8715,6 @@ async function getObjectCRUD(objectSchema, fields, options){
8531
8715
  }
8532
8716
  }
8533
8717
 
8534
- const getGlobalData = (mode)=>{
8535
- const user = getSteedosAuth();
8536
- return {mode: mode, user: user, spaceId: user.spaceId, userId: user.userId}
8537
- };
8538
-
8539
8718
  const getFormFields$1 = (objectSchema, formProps)=>{
8540
8719
  /**
8541
8720
  * fieldsExtend: 重写字段定义
@@ -8597,7 +8776,7 @@ async function getFormSchemaWithDataFilter(form, options = {}){
8597
8776
  }
8598
8777
 
8599
8778
  async function getObjectForm(objectSchema, ctx){
8600
- const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign, tabId, appId, defaults, submitSuccActions = [],
8779
+ const { recordId, formFactor, layout = formFactor === 'SMALL' ? 'normal' : "horizontal", labelAlign, tabId, appId, defaults, submitSuccActions = [],
8601
8780
  formDataFilter, onFormDataFilter, amisData, env } = ctx;
8602
8781
  const fields = ___default["default"].values(objectSchema.fields);
8603
8782
  const formFields = getFormFields$1(objectSchema, ctx);
@@ -8613,9 +8792,7 @@ async function getObjectForm(objectSchema, ctx){
8613
8792
  id: `service_${formSchema.id}`,
8614
8793
  className: 'p-0',
8615
8794
  name: `page_edit_${recordId}`,
8616
- api: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
8617
8795
  data:{
8618
- editFormInited: false,
8619
8796
  ...amisData
8620
8797
  },
8621
8798
  // data: {global: getGlobalData('edit'), recordId: recordId, objectName: objectSchema.name, context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
@@ -8624,8 +8801,9 @@ async function getObjectForm(objectSchema, ctx){
8624
8801
  body: [defaultsDeep({}, formSchema, {
8625
8802
  type: "form",
8626
8803
  mode: layout,
8804
+ initApi: await getEditFormInitApi(objectSchema, recordId, fields, ctx),
8627
8805
  data: {
8628
- "&": "${initialValues}"
8806
+ editFormInited: false,
8629
8807
  },
8630
8808
  labelAlign,
8631
8809
  persistData: false,
@@ -8639,11 +8817,15 @@ async function getObjectForm(objectSchema, ctx){
8639
8817
  submitText: "", // amis 表单不显示提交按钮, 表单提交由项目代码接管
8640
8818
  api: await getSaveApi(objectSchema, recordId, fields, ctx),
8641
8819
  initFetch: recordId != 'new',
8642
- body: await getFormBody(fields, formFields, Object.assign({}, ctx, {fieldGroups: objectSchema.field_groups})),
8820
+ body: {
8821
+ type: 'wrapper',
8822
+ className: 'p-0 m-0',
8823
+ body: await getFormBody(fields, formFields, Object.assign({}, ctx, {fieldGroups: objectSchema.field_groups})),
8824
+ hiddenOn: "${editFormInited != true}",
8825
+ },
8643
8826
  panelClassName:'m-0 sm:rounded-lg shadow-none border-none',
8644
8827
  bodyClassName: 'p-0',
8645
8828
  className: 'steedos-amis-form',
8646
- hiddenOn: "${editFormInited != true}",
8647
8829
  onEvent: {
8648
8830
  "submitSucc": {
8649
8831
  "weight": 0,
@@ -8688,7 +8870,7 @@ async function getObjectForm(objectSchema, ctx){
8688
8870
  }
8689
8871
 
8690
8872
  async function getObjectDetail(objectSchema, recordId, ctx){
8691
- const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "normal", labelAlign,
8873
+ const { formFactor, layout = formFactor === 'SMALL' ? 'normal' : "horizontal", labelAlign,
8692
8874
  formDataFilter, onFormDataFilter, amisData, env } = ctx;
8693
8875
  const fields = ___default["default"].values(objectSchema.fields);
8694
8876
  const formFields = getFormFields$1(objectSchema, ctx);
@@ -8697,8 +8879,7 @@ async function getObjectDetail(objectSchema, recordId, ctx){
8697
8879
  type: 'service',
8698
8880
  name: `page_readonly_${recordId}`,
8699
8881
  id: serviceId,
8700
- data: {global: getGlobalData('read'), context: {rootUrl: getRootUrl(), tenantId: getTenantId(), authToken: getAuthToken()}},
8701
- api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
8882
+ // api: await getReadonlyFormInitApi(objectSchema, recordId, fields, ctx),
8702
8883
  body: [
8703
8884
  {
8704
8885
  "type": "wrapper", //form 的 hiddenOn 会导致 form onEvent 异常, 使用wrapper包裹一次form,并在wrapper上控制显隐
@@ -8724,60 +8905,41 @@ async function getObjectDetail(objectSchema, recordId, ctx){
8724
8905
  ),
8725
8906
  className: 'steedos-amis-form bg-white',
8726
8907
  actions: [], // 不显示表单默认的提交按钮
8727
- onEvent: {
8728
- [`@data.changed.${objectSchema.name}`]: { // 由于amis service 组件的 onEvent 存在bug ,此处借助form来刷新 上层 service https://github.com/baidu/amis/issues/6294
8729
- "actions": [
8730
- {
8731
- "actionType": "reload",
8732
- "componentId": serviceId,
8733
- "expression": "this.__deletedRecord != true"
8734
- },
8735
- {
8736
- // "args": {
8737
- // "url": "/app/${appId}/${objectName}/grid/${side_listview_id}",
8738
- // "blank": false
8739
- // },
8740
- "actionType": "custom",
8741
- "script": "window.goBack()",
8742
- "expression": "this.__deletedRecord === true"
8743
- }
8744
- ]
8745
- }
8746
- }
8747
8908
  },
8748
8909
  }
8749
8910
  ],
8750
- onEvent: {
8751
- "fetchInited": {
8752
- "weight": 0,
8753
- "actions": [
8754
- {
8755
- actionType: 'broadcast',
8756
- eventName: "recordLoaded",
8757
- args: {
8758
- eventName: "recordLoaded"
8759
- },
8760
- data: {
8761
- objectName: "${event.data.__objectName}",
8762
- record: "${event.data.__record}"
8763
- },
8764
- expression: "${event.data.__response.error != true}"
8765
- },
8766
- {
8767
- "actionType": "setValue",
8768
- "args": {
8769
- value: {
8770
- "recordLoaded": true,
8771
- }
8772
- },
8773
- expression: "${event.data.__response.error != true}"
8774
- }
8775
- ]
8776
- }
8777
- }
8911
+ // onEvent: {
8912
+ // "fetchInited": {
8913
+ // "weight": 0,
8914
+ // "actions": [
8915
+ // {
8916
+ // actionType: 'broadcast',
8917
+ // eventName: "recordLoaded",
8918
+ // args: {
8919
+ // eventName: "recordLoaded"
8920
+ // },
8921
+ // data: {
8922
+ // objectName: "${event.data.__objectName}",
8923
+ // record: "${event.data.__record}"
8924
+ // },
8925
+ // expression: "${event.data.__response.error != true}"
8926
+ // },
8927
+ // {
8928
+ // "actionType": "setValue",
8929
+ // "args": {
8930
+ // value: {
8931
+ // "recordLoaded": true,
8932
+ // }
8933
+ // },
8934
+ // expression: "${event.data.__response.error != true}"
8935
+ // }
8936
+ // ]
8937
+ // }
8938
+ // }
8778
8939
  };
8779
8940
 
8780
8941
  amisSchema.body[0].body = await getFormSchemaWithDataFilter(amisSchema.body[0].body, { formDataFilter, onFormDataFilter, amisData, env });
8942
+ // console.log('getObjectDetail=====>', amisSchema);
8781
8943
  return amisSchema;
8782
8944
  }
8783
8945
 
@@ -8857,8 +9019,8 @@ const getRecordPermissions = async (objectName, recordId)=>{
8857
9019
  /*
8858
9020
  * @Author: baozhoutao@steedos.com
8859
9021
  * @Date: 2022-07-05 15:55:39
8860
- * @LastEditors: liaodaxue
8861
- * @LastEditTime: 2023-11-14 15:55:32
9022
+ * @LastEditors: baozhoutao@steedos.com
9023
+ * @LastEditTime: 2024-01-15 10:34:46
8862
9024
  * @Description:
8863
9025
  */
8864
9026
 
@@ -9033,7 +9195,7 @@ async function getRecordDetailRelatedListSchema(objectName, recordId, relatedObj
9033
9195
  setDataToComponentId: componentId,
9034
9196
  // tableHiddenOn: hiddenEmptyTable ? "this.$count === 0" : null,
9035
9197
  appId: appId,
9036
- crudClassName: 'border-t border-gray-300 hidden',
9198
+ crudClassName: 'steedos-record-related-crud hidden',
9037
9199
  refField,
9038
9200
  ...ctx
9039
9201
  };
@@ -9046,7 +9208,7 @@ async function getRecordDetailRelatedListSchema(objectName, recordId, relatedObj
9046
9208
  amisSchema: {
9047
9209
  type: "service",
9048
9210
  id: componentId,
9049
- className: `steedos-record-related-list ${componentId} rounded border border-gray-300 bg-gray-100 mb-4 ${className}`,
9211
+ className: `steedos-record-related-list py-2 first:pt-0 border-b last:border-b-0 ${componentId} ${className}`,
9050
9212
  data: {
9051
9213
  relatedKey: relatedKey,
9052
9214
  listViewId: `amis-\${appId}-${relatedObjectName}-listview`,
@@ -9238,11 +9400,44 @@ async function getRelatedListSchema(
9238
9400
  };
9239
9401
  }
9240
9402
 
9403
+ async function getObjectRelatedListsMiniSchema(objectApiName){
9404
+ const relatedLists = await getObjectRelatedList(objectApiName);
9405
+
9406
+ const relatedListsMiniSchema = [];
9407
+
9408
+ for (const relatedList of relatedLists) {
9409
+ relatedListsMiniSchema.push(
9410
+ {
9411
+ type: 'steedos-record-detail-list-mini',
9412
+ objectApiName: objectApiName,
9413
+ // recordId: recordId,
9414
+ formFactor: formFactor,
9415
+ relatedObjectApiName: relatedList.object_name,
9416
+ foreign_key: relatedList.foreign_key,
9417
+ relatedKey: relatedList.foreign_key,
9418
+ columns: relatedList.columns,
9419
+ sort: relatedList.sort,
9420
+ filters: relatedList.filters,
9421
+ visible_on: relatedList.visible_on,
9422
+ perPage: relatedList.page_size || perPage,
9423
+ hiddenEmptyTable: true,
9424
+ relatedLabel: relatedList.label
9425
+ }
9426
+ );
9427
+ }
9428
+
9429
+ return {
9430
+ type: 'wrapper',
9431
+ className: "steedos-record-detail-related-lists-mini",
9432
+ body: relatedListsMiniSchema
9433
+ }
9434
+ }
9435
+
9241
9436
  /*
9242
9437
  * @Author: baozhoutao@steedos.com
9243
9438
  * @Date: 2022-07-05 15:55:39
9244
- * @LastEditors: liaodaxue
9245
- * @LastEditTime: 2023-10-20 11:38:25
9439
+ * @LastEditors: baozhoutao@steedos.com
9440
+ * @LastEditTime: 2024-01-16 11:14:34
9246
9441
  * @Description:
9247
9442
  */
9248
9443
 
@@ -9414,7 +9609,7 @@ async function getField(objectName, fieldName) {
9414
9609
  async function getFormSchema(objectName, ctx) {
9415
9610
  const uiSchema = await getUISchema(objectName);
9416
9611
  const amisSchema = await getObjectForm(uiSchema, ctx);
9417
- console.log(`getFormSchema====>`, amisSchema);
9612
+ // console.log(`getFormSchema====>`, amisSchema)
9418
9613
  return {
9419
9614
  uiSchema,
9420
9615
  amisSchema,
@@ -9740,110 +9935,164 @@ async function getRecordDetailSchema(objectName, appId, props = {}){
9740
9935
  "label": "对象表单",
9741
9936
  "objectApiName": "${objectName}",
9742
9937
  "recordId": "${recordId}",
9743
- "id": "u:d4a495811d57",
9744
9938
  appId: appId
9745
9939
  }
9746
9940
  ],
9747
- "id": "u:5d4e7e3f6ecc"
9748
9941
  };
9749
9942
  const related = {
9750
9943
  "title": i18next__default["default"].t('frontend_record_detail_tab_related'),
9751
- "className": "px-0 pt-4",
9944
+ "className": "px-0 py-4",
9752
9945
  "body": [
9753
9946
  {
9754
9947
  "type": "steedos-object-related-lists",
9755
9948
  "label": "相关列表",
9756
9949
  "objectApiName": "${objectName}",
9757
9950
  "recordId": "${recordId}",
9758
- "id": "u:3b85b7b7a7f6",
9759
9951
  appId: appId
9760
9952
  }
9761
9953
  ],
9762
- "id": "u:1a0326aeec2b"
9763
9954
  };
9764
9955
  const content = {
9765
9956
  "type": "tabs",
9766
- "className": "sm:mt-3 bg-white sm:rounded sm:border border-gray-300 p-4",
9957
+ "className": "steedos-record-tabs bg-white p-4 m-0 mt-2 border-y",
9958
+ "contentClassName": "bg-none",
9767
9959
  "tabs": [
9768
9960
  detailed
9769
9961
  ],
9770
- "id": "u:a649e4094a12"
9771
9962
  };
9772
9963
  if(relatedLists.length){
9773
9964
  content.tabs.push(related);
9774
9965
  }
9966
+ // content.tabs = reverse(content.tabs)
9775
9967
  return {
9776
9968
  uiSchema,
9777
9969
  amisSchema: {
9778
- "type": "service",
9970
+ "type": "steedos-record-service",
9779
9971
  "body": [
9780
9972
  {
9781
9973
  "type": "steedos-record-detail-header",
9782
9974
  "label": "标题面板",
9783
9975
  "objectApiName": "${objectName}",
9784
9976
  "recordId": "${recordId}",
9785
- "id": "u:48d2c28eb755"
9977
+ "id": "u:48d2c28eb755",
9978
+ "showButtons": props.showButtons,
9979
+ "showBackButton": props.showBackButton,
9786
9980
  },
9787
9981
  content
9788
9982
  ],
9789
- data: {
9790
- "_master.objectName": "${objectName}",
9791
- "_master.recordId": "${recordId}"
9792
- },
9793
- onEvent: {
9794
- "recordLoaded": {
9795
- "actions": [
9796
- {
9797
- "actionType": "reload",
9798
- "data": {
9799
- "name": `\${record.${uiSchema.NAME_FIELD_KEY || 'name'}}`,
9800
- "_master.record": `\${record}`,
9801
- // 不清楚reload 如何给对象下的某个key复制, 所以此处重复设置_master的objectName、recordId
9802
- "_master.objectName": "${objectName}",
9803
- "_master.recordId": "${recordId}"
9804
- }
9805
- }
9806
- ]
9807
- },
9808
- ...props.onEvent
9809
- },
9983
+ "objectApiName": "${objectName}",
9984
+ "recordId": "${recordId}",
9985
+ onEvent: props.onEvent,
9810
9986
  }
9811
9987
  }
9812
9988
  }
9813
9989
 
9814
- async function getRecordServiceSchema(objectName, appId, props = {}) {
9990
+ async function getRecordServiceSchema(objectName, appId, props = {}, body) {
9815
9991
  const uiSchema = await getUISchema(objectName);
9992
+ const fields = ___default["default"].values(uiSchema.fields);
9993
+ const serviceId = `u:steedos-record-service-${objectName}`;
9816
9994
  return {
9817
9995
  uiSchema,
9818
9996
  amisSchema: {
9819
- "type": "service",
9820
- "body": [],
9821
- data: {
9822
- "_master.objectName": "${objectName}",
9823
- "_master.recordId": "${recordId}"
9824
- },
9825
- "style": {
9826
- "padding": "var(--Page-body-padding)",
9827
- ...props.style
9828
- },
9997
+ type: 'service',
9998
+ className: "p-0 m-0",
9829
9999
  onEvent: {
9830
- "recordLoaded": {
10000
+ [`@data.changed.${objectName}`]: {
9831
10001
  "actions": [
9832
10002
  {
9833
10003
  "actionType": "reload",
9834
- "data": {
9835
- "name": `\${record.${uiSchema.NAME_FIELD_KEY || 'name'}}`,
9836
- "_master.record": `\${record}`,
9837
- // 不清楚reload 如何给对象下的某个key复制, 所以此处重复设置_master的objectName、recordId
9838
- "_master.objectName": "${objectName}",
9839
- "_master.recordId": "${recordId}"
9840
- }
10004
+ "componentId": serviceId,
10005
+ "expression": "this.__deletedRecord != true"
10006
+ },
10007
+ {
10008
+ "actionType": "custom",
10009
+ "script": "window.goBack()",
10010
+ "expression": "this.__deletedRecord === true"
9841
10011
  }
9842
10012
  ]
9843
10013
  },
9844
- ...props.onEvent
10014
+ },
10015
+ body: {
10016
+ "type": "service",
10017
+ id: serviceId,
10018
+ className: 'steedos-record-service p-0',
10019
+ api: await getReadonlyFormInitApi(uiSchema, props.recordId, fields, props),
10020
+ body: {
10021
+ "type": "wrapper",
10022
+ "className": "p-0 m-0",
10023
+ "body": body || [],
10024
+ "hiddenOn": "${recordLoaded != true}"
10025
+ },
10026
+ data: {
10027
+ "_master.objectName": "${objectName}",
10028
+ "_master.recordId": "${recordId}",
10029
+ ...(props.data || {})
10030
+ },
10031
+ "style": {
10032
+ // "padding": "var(--Page-body-padding)",
10033
+ ...props.style
10034
+ },
10035
+ onEvent: {
10036
+ // 如果定义了fetchInited,则无法接收到广播事件@data.changed
10037
+ "fetchInited": {
10038
+ "weight": 0,
10039
+ "actions": [
10040
+ {
10041
+ actionType: 'broadcast',
10042
+ eventName: "recordLoaded",
10043
+ data: {
10044
+ objectName: "${event.data.__objectName}",
10045
+ record: "${event.data.record}"
10046
+ },
10047
+ expression: "${event.data.__response.error != true}"
10048
+ },
10049
+ ]
10050
+ },
10051
+ ...props.onEvent
10052
+ }
9845
10053
  }
9846
10054
  }
10055
+
10056
+
10057
+ }
10058
+ }
10059
+
10060
+ async function getRecordDetailMiniSchema(objectName, appId, props = {}){
10061
+ const uiSchema = await getUISchema(objectName);
10062
+ const fields = ___default["default"].values(uiSchema.fields);
10063
+
10064
+ props.initApiAdaptor = 'payload.data=Object.assign({}, payload.data, payload.data.record); payload.data._finished=true; console.log("payload data is ====>", payload)';
10065
+
10066
+ // TODO 处理相关表
10067
+ // getObjectRelatedListsMiniSchema
10068
+
10069
+ return {
10070
+ type: "form",
10071
+ wrapWithPanel: false,
10072
+ actions: [],
10073
+ initApi: await getReadonlyFormInitApi(uiSchema, props.recordId, fields, props),
10074
+ body: {
10075
+ "type": "wrapper",
10076
+ "className": "p-0 m-0",
10077
+ "body": [
10078
+ {
10079
+ "type": "steedos-record-detail-header",
10080
+ "showButtons": false,
10081
+ "showBackButton": false,
10082
+ "objectApiName": "${objectName}",
10083
+ "recordId": "${recordId}",
10084
+ },
10085
+ // {
10086
+ // "type": "steedos-object-related-lists",
10087
+ // "label": "相关列表",
10088
+ // "objectApiName": "${objectName}",
10089
+ // "staticRecordId": "${recordId}",
10090
+ // formFactor: "SMALL",
10091
+ // appId: appId
10092
+ // }
10093
+ ],
10094
+ "hiddenOn": "${_finished != true}"
10095
+ }
9847
10096
  }
9848
10097
  }
9849
10098
 
@@ -10784,9 +11033,11 @@ async function lookupToAmisPicker(field, readonly, ctx){
10784
11033
  */
10785
11034
  if(enable_tree){
10786
11035
  const rows = _.map(payload.data.rows, (item)=>{
10787
- delete item.children;
10788
- delete item.parent;
10789
- return item;
11036
+ if (!item.children) {
11037
+ return { ...item, children: [] };
11038
+ } else {
11039
+ return item;
11040
+ }
10790
11041
  })
10791
11042
  payload.data.rows = rows;
10792
11043
  }
@@ -11235,9 +11486,17 @@ async function lookupToAmis(field, readonly, ctx){
11235
11486
  }
11236
11487
  // console.log(`lookupToAmis====`, field, readonly, ctx)
11237
11488
  if(readonly){
11238
- return {
11239
- type: getAmisStaticFieldType('picker', readonly),
11240
- tpl: getRelatedFieldTpl(field, ctx)
11489
+ if(field.reference_to){
11490
+ return {
11491
+ type: 'steedos-field',
11492
+ config: field,
11493
+ static: true
11494
+ }
11495
+ }else {
11496
+ return {
11497
+ type: getAmisStaticFieldType('picker', readonly),
11498
+ tpl: getRelatedFieldTpl(field, ctx)
11499
+ }
11241
11500
  }
11242
11501
  }
11243
11502
  if(field.reference_to && !___namespace.isString(field.reference_to) && !readonly){
@@ -12231,11 +12490,9 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
12231
12490
  if(field.subFields){
12232
12491
  convertData = {
12233
12492
  type: 'steedos-input-table',
12234
- showIndex: true,
12235
12493
  editable: !readonly,
12236
12494
  addable: !readonly,
12237
12495
  removable: !readonly,
12238
- draggable: !readonly,
12239
12496
  fields: [],
12240
12497
  amis:{
12241
12498
  columnsTogglable: false
@@ -12287,7 +12544,7 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
12287
12544
  if(field.is_wide || convertData.type === 'group'){
12288
12545
  convertData.className = 'col-span-2 m-0';
12289
12546
  }else {
12290
- convertData.className = 'm-1';
12547
+ convertData.className = 'm-0';
12291
12548
  }
12292
12549
  if(readonly){
12293
12550
  convertData.className = `${convertData.className} border-b`;
@@ -12312,6 +12569,10 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
12312
12569
  }
12313
12570
  }
12314
12571
 
12572
+ if(ctx.amisData && ctx.amisData._master && ctx.amisData._master.relatedKey === field.name){
12573
+ convertData.className = `${convertData.className || ''} hidden`;
12574
+ }
12575
+
12315
12576
  if(___namespace.isString(baseData.required)){
12316
12577
  if(baseData.required.startsWith("{{")){
12317
12578
  baseData.requiredOn = `${baseData.required.substring(2, baseData.required.length -2).replace(/formData./g, 'data.')}`;
@@ -12692,9 +12953,61 @@ async function getFormBody(permissionFields, formFields, ctx){
12692
12953
  /*
12693
12954
  * @Author: 殷亮辉 yinlianghui@hotoa.com
12694
12955
  * @Date: 2023-11-15 09:50:22
12695
- * @LastEditors: liaodaxue
12696
- * @LastEditTime: 2024-01-09 18:12:28
12956
+ * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
12957
+ * @LastEditTime: 2024-01-18 10:29:57
12958
+ */
12959
+
12960
+ /**
12961
+ * 子表组件字段值中每行数据的键值key移除指定前缀
12962
+ * @param {*} value 子表组件字段值,数组
12963
+ * @param {*} fieldPrefix 字段前缀
12964
+ * @returns 转换后的子表组件字段值
12965
+ */
12966
+ function getTableValueWithoutFieldPrefix(value, fieldPrefix){
12967
+ let convertedValue = [];
12968
+ (value || []).forEach((itemValue)=>{
12969
+ var newItemValue = {};
12970
+ for(let n in itemValue){
12971
+ newItemValue[n.replace(new RegExp(`^${fieldPrefix}`), "")] = itemValue[n];
12972
+ }
12973
+ convertedValue.push(newItemValue);
12974
+ });
12975
+ return convertedValue;
12976
+ }
12977
+
12978
+ /**
12979
+ * 子表组件字段值中每行数据的键值key补上指定前缀
12980
+ * @param {*} value 子表组件字段值,数组
12981
+ * @param {*} fieldPrefix 字段前缀
12982
+ * @returns 转换后的子表组件字段值
12697
12983
  */
12984
+ function getTableValuePrependFieldPrefix(value, fieldPrefix){
12985
+ let convertedValue = [];
12986
+ (value || []).forEach((itemValue)=>{
12987
+ var newItemValue = {};
12988
+ for(let n in itemValue){
12989
+ if(typeof itemValue[n] !== undefined){
12990
+ newItemValue[`${fieldPrefix}${n}`] = itemValue[n];
12991
+ }
12992
+ }
12993
+ convertedValue.push(newItemValue);
12994
+ });
12995
+ return convertedValue;
12996
+ }
12997
+
12998
+ /**
12999
+ * 子表组件字段集合属性中每个字段name移除指定前缀
13000
+ * @param {*} fields 子表组件字段集合,数组
13001
+ * @param {*} fieldPrefix 字段前缀
13002
+ * @returns 转换后的子表组件字段值
13003
+ */
13004
+ function getTableFieldsWithoutFieldPrefix(fields, fieldPrefix){
13005
+ return (fields || []).map((item) => {
13006
+ const newItem = _$1.clone(item);//这里不clone的话,会造成子表组件重新render,从而审批王那边点开子表行编辑窗口时报错
13007
+ newItem.name = newItem.name.replace(new RegExp(`^${fieldPrefix}`), "");
13008
+ return newItem;
13009
+ });
13010
+ }
12698
13011
 
12699
13012
  /**
12700
13013
  * @param {*} props
@@ -12842,7 +13155,19 @@ function getFormPagination(props, mode) {
12842
13155
  let currentIndex = event.data.index;
12843
13156
  // 翻页到下一页之前需要先把当前页改动的内容保存到中间变量__tableItems中
12844
13157
  let currentFormValues = scope.getComponentById(__formId).getValues();
12845
- fieldValue[currentIndex] = currentFormValues;
13158
+ var parent = event.data.parent;
13159
+ var __parentIndex = event.data.__parentIndex;
13160
+ if(parent){
13161
+ fieldValue[__parentIndex].children[currentIndex] = currentFormValues;
13162
+ // 重写父节点,并且改变其某个属性以让子节点修改的内容回显到界面上
13163
+ fieldValue[__parentIndex] = Object.assign({}, fieldValue[__parentIndex], {
13164
+ children: fieldValue[__parentIndex].children,
13165
+ __fix_rerender_after_children_modified_tag: new Date().getTime()
13166
+ });
13167
+ }
13168
+ else{
13169
+ fieldValue[currentIndex] = currentFormValues;
13170
+ }
12846
13171
  // 翻页到下一页前需要同时把改动的内容保存到最终正式的表单字段中,所以额外给正式表单字段执行一次setValue
12847
13172
  doAction({
12848
13173
  "componentId": "${props.id}",
@@ -12909,7 +13234,8 @@ function getFormPagination(props, mode) {
12909
13234
  },
12910
13235
  {
12911
13236
  "type": "tpl",
12912
- "tpl": "${__page}/${__tableItems.length}"
13237
+ // 这里用__super.parent,加__super是为了防止当前记录有字段名为parent的重名变量
13238
+ "tpl": "${__page}/${__super.parent ? __tableItems[__parentIndex]['children'].length : __tableItems.length}"
12913
13239
  },
12914
13240
  {
12915
13241
  "type": "button",
@@ -12917,7 +13243,9 @@ function getFormPagination(props, mode) {
12917
13243
  "icon": `fa fa-angle-right`,
12918
13244
  "level": "link",
12919
13245
  "pageChangeDirection": "next",
12920
- "disabledOn": showPagination ? "${__page >= __tableItems.length}" : "true",
13246
+ // "disabledOn": showPagination ? "${__page >= __tableItems.length}" : "true",
13247
+ // 这里用__super.parent,加__super是为了防止当前记录有字段名为parent的重名变量
13248
+ "disabledOn": showPagination ? "${__page >= (__super.parent ? __tableItems[__parentIndex]['children'].length : __tableItems.length)}" : "true",
12921
13249
  "size": "sm",
12922
13250
  "id": buttonNextId,
12923
13251
  "onEvent": {
@@ -12950,14 +13278,14 @@ function getFormPaginationWrapper(props, form, mode) {
12950
13278
  "data": {
12951
13279
  // 这里加__super前缀是因为__parentForm变量(即主表单)中可能会正好有名为index的字段
12952
13280
  // 比如“对象字段”对象options字段是一个子表字段,但是主表(即“对象字段”对象)中正好有一个名为index的字段
12953
- "&": "${__tableItems[__super.index]}"
13281
+ "&": "${__super.parent ? __tableItems[__parentIndex]['children'][__super.index] : __tableItems[__super.index]}"
12954
13282
  }
12955
13283
  });
12956
13284
  let formBody = [
12957
13285
  {
12958
13286
  "type": "wrapper",
12959
13287
  "size": "none",
12960
- "className": "flex justify-end sticky top-0 right-0 left-0 z-20 bg-white -mt-2",
13288
+ "className": "flex justify-end sticky top-0 right-0 left-0 z-20 bg-white",
12961
13289
  "body": [
12962
13290
  getFormPagination(props, mode)
12963
13291
  ]
@@ -12973,7 +13301,8 @@ function getFormPaginationWrapper(props, form, mode) {
12973
13301
  }
12974
13302
  ];
12975
13303
  let onServiceInitedScript = `
12976
- // 以下脚本是为了解决有时弹出编辑表单时,表单中的值比最后一次编辑保存的值会延迟一拍。
13304
+
13305
+ // 以下脚本解决了有时弹出编辑表单时,表单中的值比最后一次编辑保存的值会延迟一拍。
12977
13306
  // 比如:inlineEditMode模式时,用户在表格单元格中直接修改数据,然后弹出的表单form中并没有包含单元格中修改的内容
12978
13307
  // 另外有的地方在非inlineEditMode模式时也会有这种延迟一拍问题,比如对象字段中下拉框类型字段的”选择项“属性
12979
13308
  // 再比如工作流规则详细页面修改了子表字段”时间触发器“值后,在只读界面点击查看按钮弹出的表单中__tableItems值是修改前的值
@@ -12986,6 +13315,11 @@ function getFormPaginationWrapper(props, form, mode) {
12986
13315
  // 这里不可以用event.data["${props.name}"]因为amis input talbe有一层单独的作用域,其值会延迟一拍
12987
13316
  // 这里如果不.clone的话,在弹出窗口中显示的子表组件,添加行后点窗口的取消按钮关闭窗口后无法把之前的操作还原,即把之前添加的行自动移除
12988
13317
  let lastestFieldValue = _.clone(wrapperServiceData["${props.name}"] || []);
13318
+ let fieldPrefix = "${props.fieldPrefix}";
13319
+ if(fieldPrefix){
13320
+ let getTableValueWithoutFieldPrefix = new Function('v', 'f', "return (" + ${getTableValueWithoutFieldPrefix.toString()} + ")(v, f)");
13321
+ lastestFieldValue = getTableValueWithoutFieldPrefix(lastestFieldValue, fieldPrefix);
13322
+ }
12989
13323
  //不可以直接像event.data.__tableItems = lastestFieldValue; 这样整个赋值,否则作用域会断
12990
13324
  let mode = "${mode}";
12991
13325
  if(mode === "new"){
@@ -13008,6 +13342,16 @@ function getFormPaginationWrapper(props, form, mode) {
13008
13342
  event.data.__tableItems.forEach(function(n,i){
13009
13343
  event.data.__tableItems[i] = lastestFieldValue[i];
13010
13344
  });
13345
+
13346
+ var parent = event.data.parent;
13347
+ var fieldValue = event.data.__tableItems;
13348
+ if(parent){
13349
+ // 如果是子行,即在节点嵌套情况下,当前节点如果是children属性下的子节点时,则算出其所属父行的索引值
13350
+ var primaryKey = "${props.primaryKey}";
13351
+ event.data.__parentIndex = _.findIndex(fieldValue, function(item){
13352
+ return item[primaryKey] == parent[primaryKey];
13353
+ });
13354
+ }
13011
13355
  `;
13012
13356
  let schema = {
13013
13357
  "type": "service",
@@ -13028,6 +13372,7 @@ function getFormPaginationWrapper(props, form, mode) {
13028
13372
  // "body": formBody,
13029
13373
  "data": {
13030
13374
  "__page": "${index + 1}",
13375
+ "__parentIndex": null,//兼容节点嵌套情况,即节点中有children属性时,这里记录当前节点所属上层节点index,只支持向上找一层,不支持多层
13031
13376
  // "__total": `\${${props.name}.length}`,
13032
13377
  // "__total": "${__tableItems.length}",
13033
13378
  // "__paginationServiceId": serviceId,
@@ -13075,7 +13420,22 @@ async function getForm(props, mode = "edit", formId) {
13075
13420
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13076
13421
  //这里加__super.__super前缀是因为__parentForm变量(即主表单)中可能会正好有名为index的字段
13077
13422
  // 比如“对象字段”对象options字段是一个子表字段,但是主表(即“对象字段”对象)中正好有一个名为index的字段
13078
- fieldValue[event.data.__super.__super.index] = JSON.parse(JSON.stringify(event.data));
13423
+ // fieldValue[event.data.__super.__super.index] = JSON.parse(JSON.stringify(event.data));
13424
+ var currentIndex = event.data.__super.__super.index;
13425
+ var currentFormValues = JSON.parse(JSON.stringify(event.data));
13426
+ var parent = event.data.__super.__super.parent;
13427
+ var __parentIndex = event.data.__super.__super.__parentIndex;
13428
+ if(parent){
13429
+ fieldValue[__parentIndex].children[currentIndex] = currentFormValues;
13430
+ // 重写父节点,并且改变其某个属性以让子节点修改的内容回显到界面上
13431
+ fieldValue[__parentIndex] = Object.assign({}, fieldValue[__parentIndex], {
13432
+ children: fieldValue[__parentIndex].children,
13433
+ __fix_rerender_after_children_modified_tag: new Date().getTime()
13434
+ });
13435
+ }
13436
+ else{
13437
+ fieldValue[currentIndex] = currentFormValues;
13438
+ }
13079
13439
  doAction({
13080
13440
  "componentId": "${props.id}",
13081
13441
  "actionType": "setValue",
@@ -13215,7 +13575,18 @@ async function getButtonActions(props, mode) {
13215
13575
  let scope = event.context.scoped;
13216
13576
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13217
13577
  // 新建一条空白行并保存到子表组件
13218
- fieldValue.push({});
13578
+ var parent = event.data.__super.parent;
13579
+ var primaryKey = "${props.primaryKey}";
13580
+ var __parentIndex = parent && _.findIndex(fieldValue, function(item){
13581
+ return item[primaryKey] == parent[primaryKey];
13582
+ });
13583
+ if(parent){
13584
+ fieldValue[__parentIndex].children.push({});
13585
+ // 这里实测不需要fieldValue[__parentIndex] = ... 来重写整个父行让子表回显,所以没加相关代码
13586
+ }
13587
+ else{
13588
+ fieldValue.push({});
13589
+ }
13219
13590
  doAction({
13220
13591
  "componentId": "${props.id}",
13221
13592
  "actionType": "setValue",
@@ -13227,7 +13598,13 @@ async function getButtonActions(props, mode) {
13227
13598
  let __paginationServiceId = "${formPaginationId}";
13228
13599
  let __paginationData = scope.getComponentById(__paginationServiceId).getData();
13229
13600
  event.data.index = __paginationData.index;
13230
- event.data.__page = fieldValue.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13601
+ if(parent){
13602
+ event.data.__page = fieldValue[__parentIndex].children.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13603
+ event.data.__parentIndex = __parentIndex; //执行下面的翻页按钮事件中依赖了__parentIndex值
13604
+ }
13605
+ else{
13606
+ event.data.__page = fieldValue.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13607
+ }
13231
13608
  // 触发翻页按钮事件,实现保存当前页数据并跳转到最后一行
13232
13609
  scope.getComponentById(buttonNextId).props.dispatchEvent("click", event.data);
13233
13610
  `;
@@ -13238,7 +13615,19 @@ async function getButtonActions(props, mode) {
13238
13615
  let newItem = scope.getComponentById(__formId).getValues();//这里不可以用event.data,因为其拿到的是弹出表单时的初始值,不是用户实时填写的数据
13239
13616
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13240
13617
  // 复制当前页数据到新建行并保存到子表组件
13241
- fieldValue.push(newItem);
13618
+ // fieldValue.push(newItem);
13619
+ var parent = event.data.__super.parent;
13620
+ var primaryKey = "${props.primaryKey}";
13621
+ var __parentIndex = parent && _.findIndex(fieldValue, function(item){
13622
+ return item[primaryKey] == parent[primaryKey];
13623
+ });
13624
+ if(parent){
13625
+ fieldValue[__parentIndex].children.push(newItem);
13626
+ // 这里实测不需要fieldValue[__parentIndex] = ... 来重写整个父行让子表回显,所以没加相关代码
13627
+ }
13628
+ else{
13629
+ fieldValue.push(newItem);
13630
+ }
13242
13631
  doAction({
13243
13632
  "componentId": "${props.id}",
13244
13633
  "actionType": "setValue",
@@ -13250,7 +13639,13 @@ async function getButtonActions(props, mode) {
13250
13639
  let __paginationServiceId = "${formPaginationId}";
13251
13640
  let __paginationData = scope.getComponentById(__paginationServiceId).getData();
13252
13641
  event.data.index = __paginationData.index;
13253
- event.data.__page = fieldValue.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13642
+ if(parent){
13643
+ event.data.__page = fieldValue[__parentIndex].children.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13644
+ event.data.__parentIndex = __parentIndex; //执行下面的翻页按钮事件中依赖了__parentIndex值
13645
+ }
13646
+ else{
13647
+ event.data.__page = fieldValue.length - 1;//这里不可以用Object.assign否则,event.data中上层作用域数据会丢失
13648
+ }
13254
13649
  // 触发翻页按钮事件,实现保存当前页数据并跳转到最后一行
13255
13650
  scope.getComponentById(buttonNextId).props.dispatchEvent("click", event.data);
13256
13651
  `;
@@ -13326,13 +13721,16 @@ async function getButtonActions(props, mode) {
13326
13721
  "_master": "${_master}",
13327
13722
  "global": "${global}",
13328
13723
  "uiSchema": "${uiSchema}",
13329
- "index": "${index}",
13724
+ "index": "${index}",//amis组件自带行索引,在节点嵌套情况下,当前节点如果是children属性下的子节点时,这里的index是当前节点在children中的索引,而不是外层父节点的index
13725
+ "parent": "${__super.parent}",//amis组件自带父节点数据域数据,即节点嵌套情况下,当前节点为某个节点(比如A节点)的children属性下的子节点时,当前节点的父节点(即A节点)的数据域数据
13330
13726
  // "__tableItems": `\${${props.name}}`
13331
13727
  // 为了解决"弹出的dialog窗口中子表组件会影响页面布局界面中父作用域字段值",比如设计字段布局微页面中的设置分组功能,弹出的就是子表dialog
13332
13728
  // 所以这里使用json|toJson转一次,断掉event.data.__tableItems与上层任用域中props.name的联系
13333
13729
  // "__tableItems": `\${${props.name}|json|toJson}`
13334
- "__tableItems": `\${(${props.name} || [])|json|toJson}`
13335
- },
13730
+ // 在节点嵌套情况下,当前节点正好是带children属性的节点的话,这里弹出的dialog映射到的会是children数组,这是amis目前的规则,
13731
+ // 所以这里加判断有children时,用__super.__super让映射到正确的作用域层,如果不加,则__tableItems取到的会是children数组,而不是整个子表组件的值
13732
+ "__tableItems": `\${((children ? __super.__super.${props.name} : __super.${props.name}) || [])|json|toJson}`
13733
+ },
13336
13734
  "actions": dialogButtons,
13337
13735
  "onEvent": {
13338
13736
  "confirm": {
@@ -13354,35 +13752,39 @@ async function getButtonActions(props, mode) {
13354
13752
  Object.assign(actionShowEditDialog.dialog, props.dialog);
13355
13753
  }
13356
13754
  if (mode == "new") {
13357
- `
13358
- let newItem = {};
13359
- if(event.data["${props.name}"]){
13360
- // let fieldValue = event.data.__tableItems;
13361
- // 这里不用__tableItems是因为新建的时候没有翻页,里面没有也不需要走__tableItems变量
13362
- // let fieldValue = _.clone(event.data["${props.name}"]);
13363
- let fieldValue = event.data["${props.name}"];
13364
- fieldValue.push(newItem);
13365
- doAction({
13366
- "componentId": "${props.id}",
13367
- "actionType": "setValue",
13368
- "args": {
13369
- "value": fieldValue
13370
- }
13371
- });
13372
- event.data.index = fieldValue.length - 1;
13373
- }
13374
- else{
13375
- // 这里不可以执行event.data["${props.name}"]=[newItem],数据域会断掉
13376
- doAction({
13377
- "componentId": "${props.id}",
13378
- "actionType": "setValue",
13379
- "args": {
13380
- "value": [newItem]
13381
- }
13382
- });
13383
- event.data.index = 1;
13384
- }
13385
- `;
13755
+ // let onNewLineScript = `
13756
+ // let newItem = {};
13757
+ // if(event.data["${props.name}"]){
13758
+ // // let fieldValue = event.data.__tableItems;
13759
+ // // 这里不用__tableItems是因为新建的时候没有翻页,里面没有也不需要走__tableItems变量
13760
+ // // let fieldValue = _.clone(event.data["${props.name}"]);
13761
+ // let fieldValue = event.data["${props.name}"];
13762
+ // fieldValue.push(newItem);
13763
+ // doAction({
13764
+ // "componentId": "${props.id}",
13765
+ // "actionType": "setValue",
13766
+ // "args": {
13767
+ // "value": fieldValue
13768
+ // }
13769
+ // });
13770
+ // event.data.index = fieldValue.length - 1;
13771
+ // }
13772
+ // else{
13773
+ // // 这里不可以执行event.data["${props.name}"]=[newItem],数据域会断掉
13774
+ // doAction({
13775
+ // "componentId": "${props.id}",
13776
+ // "actionType": "setValue",
13777
+ // "args": {
13778
+ // "value": [newItem]
13779
+ // }
13780
+ // });
13781
+ // event.data.index = 1;
13782
+ // }
13783
+ // `;
13784
+ // let actionNewLine = {
13785
+ // "actionType": "custom",
13786
+ // "script": onNewLineScript
13787
+ // };
13386
13788
  // 新增行时不需要在弹出编辑表单前先加一行,因为会在编辑表单所在service初始化时判断到是新增就自动增加一行,因为这里拿不到event.data.__tableItems,也无法变更其值
13387
13789
  // actions = [actionNewLine, actionShowEditDialog];
13388
13790
  actions = [actionShowEditDialog];
@@ -13417,15 +13819,17 @@ async function getButtonActions(props, mode) {
13417
13819
  // 映射到中间变量__parentForm而不是直接用&展开映射是为了避免表单中字段名与作用域中变量重名
13418
13820
  // "__parentForm": "${__super.__super || {}}",
13419
13821
  "__parentForm": parentFormData,
13822
+ "_master": "${_master}",
13420
13823
  "global": "${global}",
13421
13824
  "uiSchema": "${uiSchema}",
13422
13825
  "index": "${index}",
13826
+ "parent": "${__super.parent}",//amis组件自带父节点数据域数据,即节点嵌套情况下,当前节点为某个节点(比如A节点)的children属性下的子节点时,当前节点的父节点(即A节点)的数据域数据
13423
13827
  // "__tableItems": `\${${props.name}}`
13424
13828
  // 为了解决"弹出的dialog窗口中子表组件会影响页面布局界面中父作用域字段值",比如设计字段布局微页面中的设置分组功能,弹出的就是子表dialog
13425
13829
  // 所以这里使用json|toJson转一次,断掉event.data.__tableItems与上层任用域中props.name的联系
13426
13830
  // "__tableItems": `\${${props.name}|json|toJson}`
13427
- "__tableItems": `\${(${props.name} || [])|json|toJson}`
13428
- },
13831
+ "__tableItems": `\${((__super.parent ? __super.__super.${props.name} : __super.${props.name}) || [])|json|toJson}`
13832
+ },
13429
13833
  }
13430
13834
  }
13431
13835
  ];
@@ -13441,7 +13845,23 @@ async function getButtonActions(props, mode) {
13441
13845
  // 这里不可以用event.data["${props.name}"]因为amis input talbe有一层单独的作用域,其值会延迟一拍
13442
13846
  // 这里_.clone是因为字段设计布局设置分组这种弹出窗口中的子表组件,直接删除后,点取消无法还原
13443
13847
  let lastestFieldValue = _.clone(wrapperServiceData["${props.name}"]);
13444
- lastestFieldValue.splice(event.data.index, 1);
13848
+ var currentIndex = event.data.index;
13849
+ var parent = event.data.__super.parent;
13850
+ var primaryKey = "${props.primaryKey}";
13851
+ var __parentIndex = parent && _.findIndex(lastestFieldValue, function(item){
13852
+ return item[primaryKey] == parent[primaryKey];
13853
+ });
13854
+ if(parent){
13855
+ lastestFieldValue[__parentIndex].children.splice(currentIndex, 1);
13856
+ // 重写父节点,并且改变其某个属性以让子节点修改的内容回显到界面上
13857
+ lastestFieldValue[__parentIndex] = Object.assign({}, lastestFieldValue[__parentIndex], {
13858
+ children: lastestFieldValue[__parentIndex].children,
13859
+ __fix_rerender_after_children_modified_tag: new Date().getTime()
13860
+ });
13861
+ }
13862
+ else{
13863
+ lastestFieldValue.splice(currentIndex, 1);
13864
+ }
13445
13865
  doAction({
13446
13866
  "componentId": "${props.id}",
13447
13867
  "actionType": "setValue",
@@ -13527,39 +13947,53 @@ const getAmisInputTableSchema = async (props) => {
13527
13947
  if (!props.id) {
13528
13948
  props.id = "steedos_input_table_" + props.name + "_" + Math.random().toString(36).substr(2, 9);
13529
13949
  }
13950
+ if (!props.primaryKey) {
13951
+ props.primaryKey = "_id";
13952
+ }
13953
+ let showOperation = props.showOperation;
13954
+ if(showOperation !== false){
13955
+ showOperation = true;
13956
+ }
13957
+ // props.fieldPrefix = "project_milestone_";
13958
+ if (props.fieldPrefix) {
13959
+ props.fields = getTableFieldsWithoutFieldPrefix(props.fields, props.fieldPrefix);
13960
+ }
13530
13961
  let serviceId = getComponentId("table_service", props.id);
13531
13962
  let buttonsForColumnOperations = [];
13532
13963
  let inlineEditMode = props.inlineEditMode;
13533
13964
  let showAsInlineEditMode = inlineEditMode && props.editable;
13534
- if (props.editable) {
13535
- let showEditButton = true;
13536
- if (showAsInlineEditMode) {
13537
- // 始终显示弹出子表表单按钮,如果需要判断只在有列被隐藏时才需要显示弹出表单按钮放开下面的if逻辑就好
13538
- showEditButton = true;
13539
- // // inline edit模式下只在有列被隐藏时才需要显示编辑按钮
13540
- // if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length) {
13541
- // showEditButton = true;
13542
- // }
13543
- // else {
13544
- // showEditButton = false;
13545
- // }
13965
+ if(showOperation){
13966
+ if (props.editable) {
13967
+ let showEditButton = true;
13968
+ if (showAsInlineEditMode) {
13969
+ // 始终显示弹出子表表单按钮,如果需要判断只在有列被隐藏时才需要显示弹出表单按钮放开下面的if逻辑就好
13970
+ showEditButton = true;
13971
+ // // inline edit模式下只在有列被隐藏时才需要显示编辑按钮
13972
+ // if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length) {
13973
+ // showEditButton = true;
13974
+ // }
13975
+ // else {
13976
+ // showEditButton = false;
13977
+ // }
13978
+ }
13979
+ // 编辑时显示编辑按钮
13980
+ if (showEditButton) {
13981
+ let buttonEditSchema = await getButtonEdit(props, showAsInlineEditMode);
13982
+ buttonsForColumnOperations.push(buttonEditSchema);
13983
+ }
13546
13984
  }
13547
- // 编辑时显示编辑按钮
13548
- if (showEditButton) {
13549
- let buttonEditSchema = await getButtonEdit(props, showAsInlineEditMode);
13550
- buttonsForColumnOperations.push(buttonEditSchema);
13985
+ else {
13986
+ // 只读时显示查看按钮
13987
+ // 如果想只在有列被隐藏时才需要显示查看按钮可以加上判断:if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length)
13988
+ let buttonViewSchema = await getButtonView(props);
13989
+ buttonsForColumnOperations.push(buttonViewSchema);
13990
+ }
13991
+ if (props.removable) {
13992
+ let buttonDeleteSchema = await getButtonDelete(props);
13993
+ buttonsForColumnOperations.push(buttonDeleteSchema);
13551
13994
  }
13552
13995
  }
13553
- else {
13554
- // 只读时显示查看按钮
13555
- // 如果想只在有列被隐藏时才需要显示查看按钮可以加上判断:if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length)
13556
- let buttonViewSchema = await getButtonView(props);
13557
- buttonsForColumnOperations.push(buttonViewSchema);
13558
- }
13559
- if (props.removable) {
13560
- let buttonDeleteSchema = await getButtonDelete(props);
13561
- buttonsForColumnOperations.push(buttonDeleteSchema);
13562
- }
13996
+ let amis = props["input-table"] || props.amis;//额外支持"input-table"代替amis属性,是因为在字段yml文件中用amis作为key不好理解
13563
13997
  let inputTableSchema = {
13564
13998
  "type": "input-table",
13565
13999
  "label": props.label,
@@ -13577,8 +14011,37 @@ const getAmisInputTableSchema = async (props) => {
13577
14011
  "strictMode": props.strictMode,
13578
14012
  "showTableAddBtn": false,
13579
14013
  "showFooterAddBtn": false,
13580
- "className": props.tableClassName
14014
+ "className": props.tableClassName,
14015
+ "pipeOut": (value, data) => {
14016
+ value = (value || []).map(function(item){
14017
+ delete item.__fix_rerender_after_children_modified_tag;
14018
+ return item;
14019
+ });
14020
+ if(props.fieldPrefix){
14021
+ value = getTableValuePrependFieldPrefix(value, props.fieldPrefix);
14022
+ }
14023
+ if(amis.pipeOut){
14024
+ if(typeof amis.pipeOut === 'function'){
14025
+ return amis.pipeOut(value, data);
14026
+ }
14027
+ }
14028
+ return value;
14029
+ }
13581
14030
  };
14031
+ if(amis.pipeIn){
14032
+ inputTableSchema.pipeIn = amis.pipeIn;
14033
+ }
14034
+ if(props.fieldPrefix){
14035
+ inputTableSchema.pipeIn = (value, data) => {
14036
+ value = getTableValueWithoutFieldPrefix(value, props.fieldPrefix);
14037
+ if(amis.pipeIn){
14038
+ if(typeof amis.pipeIn === 'function'){
14039
+ return amis.pipeIn(value, data);
14040
+ }
14041
+ }
14042
+ return value;
14043
+ };
14044
+ }
13582
14045
  if (buttonsForColumnOperations.length) {
13583
14046
  inputTableSchema.columns.push({
13584
14047
  "name": "__op__",
@@ -13590,17 +14053,18 @@ const getAmisInputTableSchema = async (props) => {
13590
14053
  if (showAsInlineEditMode) {
13591
14054
  inputTableSchema.needConfirm = false;
13592
14055
  }
13593
- let amis = props["input-table"] || props.amis;//额外支持"input-table"代替amis属性,是因为在字段yml文件中用amis作为key不好理解
13594
14056
  if (amis) {
13595
14057
  // 支持配置amis属性重写或添加最终生成的input-table中任何属性。
13596
14058
  delete amis.id;//如果steedos-input-table组件配置了amis.id属性,会造成新建编辑行功能不生效
14059
+ delete amis.pipeIn;//该属性在上面合并过了
14060
+ delete amis.pipeOut;//该属性在上面合并过了
13597
14061
  Object.assign(inputTableSchema, amis);
13598
14062
  }
13599
14063
  const isAnyFieldHasDependOn = (props.fields || []).find(function (item) {
13600
14064
  return item.depend_on;
13601
14065
  });
13602
14066
  if (isAnyFieldHasDependOn) {
13603
- // 有任意一个子字段有depend_on属性时,强制设置禁用静态模式
14067
+ // 有任意一个子字段有depend_on属性时,强制设置禁用静态模式,因为strictMode模式下,dependOn的字段值变更后,不会rerender整个子表
13604
14068
  Object.assign(inputTableSchema, {
13605
14069
  strictMode: false
13606
14070
  });
@@ -13705,7 +14169,7 @@ async function getListPageInitSchema(objectApiName, formFactor, userSession) {
13705
14169
  // 获取
13706
14170
  async function getRecordPageInitSchema(objectApiName){
13707
14171
  const relatedList = await getObjectRelatedList(objectApiName);
13708
- const uiSchema = await getUISchema(objectApiName);
14172
+ await getUISchema(objectApiName);
13709
14173
  let body = [
13710
14174
  // detailHeaderAmisSchema,
13711
14175
  {
@@ -13713,28 +14177,7 @@ async function getRecordPageInitSchema(objectApiName){
13713
14177
  "label": "标题面板",
13714
14178
  "objectApiName": "${objectName}",
13715
14179
  "recordId": "${recordId}",
13716
- "onEvent": {
13717
- "recordLoaded": {
13718
- "actions": [
13719
- {
13720
- "actionType": "setValue",
13721
- "args": {
13722
- "value": {
13723
- "recordLoaded": true,
13724
- }
13725
- }
13726
- },
13727
- {
13728
- "actionType": "reload",
13729
- "data": {
13730
- "name": `\${record.${uiSchema?.NAME_FIELD_KEY || 'name'}}`,
13731
- "record": `\${record}`,
13732
- "recordLoaded": true,
13733
- }
13734
- }
13735
- ]
13736
- }
13737
- }
14180
+ "onEvent": {}
13738
14181
  }
13739
14182
  ];
13740
14183
  let contentBody = {
@@ -16369,9 +16812,11 @@ exports.getObjectRelated = getObjectRelated;
16369
16812
  exports.getObjectRelatedList = getObjectRelatedList;
16370
16813
  exports.getObjectRelatedListButtons = getObjectRelatedListButtons;
16371
16814
  exports.getObjectRelatedListHeader = getObjectRelatedListHeader;
16815
+ exports.getObjectRelatedListsMiniSchema = getObjectRelatedListsMiniSchema;
16372
16816
  exports.getPage = getPage;
16373
16817
  exports.getRecord = getRecord;
16374
16818
  exports.getRecordDetailHeaderSchema = getRecordDetailHeaderSchema;
16819
+ exports.getRecordDetailMiniSchema = getRecordDetailMiniSchema;
16375
16820
  exports.getRecordDetailRelatedListSchema = getRecordDetailRelatedListSchema;
16376
16821
  exports.getRecordDetailSchema = getRecordDetailSchema;
16377
16822
  exports.getRecordPageInitSchema = getRecordPageInitSchema;