@steedos-widgets/amis-lib 3.6.2-beta.13 → 3.6.2-beta.15

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
@@ -416,8 +416,8 @@ const Router = {
416
416
  /*
417
417
  * @Author: baozhoutao@steedos.com
418
418
  * @Date: 2022-07-20 16:29:22
419
- * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
420
- * @LastEditTime: 2023-12-28 14:59:08
419
+ * @LastEditors: liaodaxue
420
+ * @LastEditTime: 2024-01-25 14:44:17
421
421
  * @Description:
422
422
  */
423
423
 
@@ -489,6 +489,25 @@ function getComparableAmisVersion() {
489
489
  }
490
490
  }
491
491
 
492
+ /**
493
+ * 判断浏览器类型
494
+ * @returns 按需返回浏览器类型;
495
+ */
496
+ function getBowserType() {
497
+ const userAgent = navigator.userAgent;
498
+ if (userAgent.indexOf("Chrome")!== -1 && userAgent.indexOf("Safari") !== -1 && userAgent.indexOf("Edg") === -1) {
499
+ return "Chrome";
500
+ } else if (userAgent.indexOf("Firefox") !== -1) {
501
+ return "Firefox";
502
+ } else if (userAgent.indexOf("Safari") !== -1 && userAgent.indexOf("Chrome") === -1 && userAgent.indexOf("Edge") === -1) {
503
+ return "Safari";
504
+ } else if (userAgent.indexOf("Edg") !== -1) {
505
+ return "Edge";
506
+ } else {
507
+ return "Unknown browser"; // 其他浏览器...(可根据自己需要确定是否新增其他浏览器的判断)
508
+ }
509
+ }
510
+
492
511
  /*
493
512
  * @Author: baozhoutao@steedos.com
494
513
  * @Date: 2022-05-23 09:53:08
@@ -1892,7 +1911,8 @@ async function getQuickEditSchema(field, options){
1892
1911
  "failed": "失败了呢。。"
1893
1912
  }
1894
1913
  }
1895
- }
1914
+ },
1915
+ "expression": "${!recordPermissions.modifyAllRecords}"
1896
1916
  },
1897
1917
  {
1898
1918
  "actionType": "setValue",
@@ -1908,7 +1928,7 @@ async function getQuickEditSchema(field, options){
1908
1928
  "componentId": quickEditId,
1909
1929
  "args": {
1910
1930
  "value":{
1911
- "quickedit_record_permissions": "${event.data}"
1931
+ "quickedit_record_permissions": "${recordPermissions.modifyAllRecords ? {'allowEdit': true} : event.data}"
1912
1932
  }
1913
1933
  }
1914
1934
  }
@@ -1972,7 +1992,7 @@ async function getQuickEditSchema(field, options){
1972
1992
  `
1973
1993
  }
1974
1994
  },
1975
- "expression":"${event.data.value}"
1995
+ "expression":"${event.data.value && !recordPermissions.modifyAllRecords}"
1976
1996
  },
1977
1997
  {
1978
1998
  "actionType": "setValue",
@@ -2003,10 +2023,20 @@ async function getQuickEditSchema(field, options){
2003
2023
  "script": `
2004
2024
  const noPermission = event.data.noPermission;
2005
2025
  const crudComponent = event.context.scoped.getComponentById("${options.crudId}");
2006
- const selectedItems = crudComponent && crudComponent.props.store.selectedItems.concat();
2026
+ let selectedItems = crudComponent && crudComponent.props.store.selectedItems.concat();
2007
2027
  noPermission.forEach(function (item) {
2008
2028
  crudComponent && crudComponent.unSelectItem(_.find(selectedItems,{_id:item}));
2029
+ _.remove(selectedItems, (selected) => selected._id === item);
2009
2030
  })
2031
+ doAction({
2032
+ "componentId": "${quickEditId}",
2033
+ "actionType": "setValue",
2034
+ "args": {
2035
+ "value": {
2036
+ selectedItems
2037
+ }
2038
+ }
2039
+ });
2010
2040
  `
2011
2041
  },
2012
2042
  {
@@ -2097,7 +2127,8 @@ async function getTableColumns(fields, options){
2097
2127
  //增加quickEdit属性,实现快速编辑
2098
2128
  const quickEditSchema = allowEdit ? await getQuickEditSchema(field, options) : allowEdit;
2099
2129
  let className = "";
2100
- if(/Safari/.test(navigator.userAgent)){
2130
+ const bowserType = getBowserType();
2131
+ if(bowserType === "Safari"){
2101
2132
  className += " whitespace-nowrap ";
2102
2133
  }else {
2103
2134
  if(field.wrap != true){
@@ -2106,6 +2137,18 @@ async function getTableColumns(fields, options){
2106
2137
  className += " break-words ";
2107
2138
  }
2108
2139
  }
2140
+
2141
+ if (typeof field.amis?.className == "object") {
2142
+ className = {
2143
+ [className]: "true",
2144
+ ...field.amis.className
2145
+ };
2146
+ } else if (typeof field.amis?.className == "string") {
2147
+ className = `${className} ${field.amis.className} `;
2148
+ }
2149
+ let fieldAmis = ___namespace.clone(field.amis);
2150
+ delete fieldAmis?.className;
2151
+
2109
2152
  let columnItem;
2110
2153
  if((field.is_name || field.name === options.labelFieldName) && options.objectName === 'cms_files'){
2111
2154
  const previewFileScript = `
@@ -2156,7 +2199,7 @@ async function getTableColumns(fields, options){
2156
2199
  toggled: field.toggled,
2157
2200
  static: true,
2158
2201
  className,
2159
- }, field.amis, {name: field.name});
2202
+ }, fieldAmis, {name: field.name});
2160
2203
  }else if(field.type === 'avatar' || field.type === 'image' || field.type === 'file'){
2161
2204
  columnItem = Object.assign({}, {
2162
2205
  type: "switch",
@@ -2167,7 +2210,7 @@ async function getTableColumns(fields, options){
2167
2210
  static: true,
2168
2211
  className,
2169
2212
  ...getAmisFileReadonlySchema(field)
2170
- }, field.amis, {name: field.name});
2213
+ }, fieldAmis, {name: field.name});
2171
2214
  }
2172
2215
  else if(field.type === 'select'){
2173
2216
  const map = getSelectMap(field.options);
@@ -2182,7 +2225,7 @@ async function getTableColumns(fields, options){
2182
2225
  className,
2183
2226
  inputClassName: "inline",
2184
2227
  static: true,
2185
- }, field.amis, {name: field.name});
2228
+ }, fieldAmis, {name: field.name});
2186
2229
  }
2187
2230
  else {
2188
2231
  const tpl = await getFieldTpl(field, options);
@@ -2209,15 +2252,6 @@ async function getTableColumns(fields, options){
2209
2252
  // }
2210
2253
 
2211
2254
  //field上的amis属性里的clssname需要单独判断类型合并
2212
- if (typeof field.amis?.className == "object") {
2213
- className = {
2214
- [className]: "true",
2215
- ...field.amis.className
2216
- };
2217
- } else if (typeof field.amis?.className == "string") {
2218
- className = `${className} ${field.amis.className} `;
2219
- }
2220
- delete field.amis?.className;
2221
2255
 
2222
2256
  if(!field.hidden && !field.extra){
2223
2257
  columnItem = Object.assign({}, {
@@ -2234,7 +2268,7 @@ async function getTableColumns(fields, options){
2234
2268
  static: true,
2235
2269
  options: field.type === 'html' ? {html: true} : null
2236
2270
  // toggled: true
2237
- }, field.amis, {name: field.name});
2271
+ }, fieldAmis, {name: field.name});
2238
2272
 
2239
2273
  if(field.type === 'color'){
2240
2274
  columnItem.type = 'color';
@@ -8638,14 +8672,7 @@ async function getObjectCRUD(objectSchema, fields, options){
8638
8672
  headers: {
8639
8673
  Authorization: "Bearer ${context.tenantId},${context.authToken}",
8640
8674
  },
8641
- requestAdaptor: quickSaveApiRequestAdaptor,
8642
- adaptor: `
8643
- if(payload.errors){
8644
- payload.status = 2;
8645
- payload.msg = window.t ? window.t(payload.errors[0].message) : payload.errors[0].message;
8646
- }
8647
- return payload;
8648
- `
8675
+ requestAdaptor: quickSaveApiRequestAdaptor
8649
8676
  },
8650
8677
  // 外层data发生变化的时候, 不会重新渲染rowClassNameExpr, 所以先用css标记tr唯一标识
8651
8678
  // 使用表达式给tr添加初始选中状态
@@ -8662,6 +8689,21 @@ async function getObjectCRUD(objectSchema, fields, options){
8662
8689
  crudModeClassName = `steedos-crud-mode-${body.mode}`;
8663
8690
  }
8664
8691
 
8692
+ body.quickSaveApi.adaptor = `
8693
+ if(payload.errors){
8694
+ payload.status = 2;
8695
+ payload.msg = window.t ? window.t(payload.errors[0].message) : payload.errors[0].message;
8696
+ }
8697
+ debugger;
8698
+ var scope = SteedosUI.getRef(context.scopeId);
8699
+ var scopeParent = scope && scope.parent;
8700
+ var crudScoped = scopeParent.getComponentById('${body.id}');
8701
+ setTimeout(()=>{
8702
+ crudScoped && crudScoped.control.updateAutoFillHeight();
8703
+ }, 500);
8704
+ return payload;
8705
+ `;
8706
+
8665
8707
  if(body.columns && options.formFactor != 'SMALL'){
8666
8708
  //将_display放入crud的columns的倒数第二列中(最后一列会影响固定列),可以通过setvalue修改行内数据域的_display,而不影响上层items的_display,用于批量编辑
8667
8709
  body.columns.splice(body.columns.length -1 , 0, {name: '_display',type: 'static', width: 1, placeholder: "",id: objectSchema.name + "_display_${_index}", tpl: "${''}"});
@@ -12211,7 +12253,7 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
12211
12253
  convertData = {
12212
12254
  type: getAmisStaticFieldType('datetime', readonly),
12213
12255
  inputFormat: 'YYYY-MM-DD HH:mm',
12214
- format: 'YYYY-MM-DDTHH:mm:ss.SSSZ',
12256
+ format: 'YYYY-MM-DDTHH:mm:00.000Z',
12215
12257
  tpl: readonly ? getDateTimeTpl(field) : null,
12216
12258
  utc: true,
12217
12259
  };
@@ -12983,8 +13025,56 @@ function uuidv4() {
12983
13025
  * @Author: 殷亮辉 yinlianghui@hotoa.com
12984
13026
  * @Date: 2023-11-15 09:50:22
12985
13027
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
12986
- * @LastEditTime: 2024-01-24 14:56:03
13028
+ * @LastEditTime: 2024-01-26 17:47:16
13029
+ */
13030
+
13031
+ /**
13032
+ * 子表组件字段值中每行数据补上字段值为空的的字段值,把值统一设置为空字符串,是为了解决amis amis 3.6/6.0 input-table组件bug:行中字段值为空时会显示为父作用域中的同名变量值,见:https://github.com/baidu/amis/issues/9520
13033
+ * amis #9520修正后此函数及相关代码可以移除
13034
+ * @param {*} value 子表组件字段值,数组
13035
+ * @param {*} fields 子表组件fields属性,数组
13036
+ * @returns 转换后的子表组件字段值
13037
+ */
13038
+ function getTableValueWithEmptyValue(value, fields) {
13039
+ return (value || []).map((itemValue) => {
13040
+ //这里不clone的话,会造成在pipeIn函数执行该函数后像pipeOut一样最终输出到表单项中,即库里字段值会被改了
13041
+ const newItemValue = _$1.clone(itemValue);
13042
+ (fields || []).forEach((itemField) => {
13043
+ if(itemField.name && (newItemValue[itemField.name] === undefined || newItemValue[itemField.name] === null)){
13044
+ // 这里newItemValue中不存在 itemField.name 属性,或者值为null时都会有“显示为父作用域中的同名变量值”的问题,所以null和undefined都要重置为空字符串
13045
+ // 实测数字、下拉框、多选lookup等字段类型重置为空字符串都不会有问题,而且实测amis from组件的清空表单字段值功能就是把表单中的各种字段类型设置为空字符串,所以看起来也符合amis规范
13046
+ newItemValue[itemField.name] = "";
13047
+ }
13048
+ if (newItemValue.children) {
13049
+ newItemValue.children = getTableValueWithEmptyValue(newItemValue.children, fields);
13050
+ }
13051
+ });
13052
+ return newItemValue;
13053
+ });
13054
+ }
13055
+
13056
+ /**
13057
+ * 把子表组件字段值中每行数据中经过上面getTableValueWithEmptyValue函数空字段值移除
13058
+ * amis #9520修正后此函数及相关代码可以移除
13059
+ * @param {*} value 子表组件字段值,数组
13060
+ * @param {*} fields 子表组件fields属性,数组
13061
+ * @returns 转换后的子表组件字段值
12987
13062
  */
13063
+ function getTableValueWithoutEmptyValue(value, fields) {
13064
+ return (value || []).map((itemValue) => {
13065
+ const newItemValue = _$1.clone(itemValue);
13066
+ (fields || []).forEach((itemField) => {
13067
+ if(itemField.name && (newItemValue[itemField.name] === "" || newItemValue[itemField.name] === undefined || newItemValue[itemField.name] === null)){
13068
+ // 这里额外把null和undefined值也删除掉纯粹是没必要输出保存它们
13069
+ delete newItemValue[itemField.name];
13070
+ }
13071
+ if (newItemValue.children) {
13072
+ newItemValue.children = getTableValueWithoutEmptyValue(newItemValue.children, fields);
13073
+ }
13074
+ });
13075
+ return newItemValue;
13076
+ });
13077
+ }
12988
13078
 
12989
13079
  function getTablePrimaryKey(props) {
12990
13080
  return props.primaryKey || "_id";
@@ -13064,6 +13154,7 @@ function getTableValueWithoutFieldPrefix(value, fieldPrefix) {
13064
13154
  * 子表组件字段值中每行数据的键值key补上指定前缀
13065
13155
  * @param {*} value 子表组件字段值,数组
13066
13156
  * @param {*} fieldPrefix 字段前缀
13157
+ * @param {*} primaryKey 主键字段名,主键不参与被键值key规则,需要排除,审批王amis表单也是这个规则
13067
13158
  * @returns 转换后的子表组件字段值
13068
13159
  */
13069
13160
  function getTableValuePrependFieldPrefix(value, fieldPrefix, primaryKey) {
@@ -13331,9 +13422,14 @@ function getFormPagination(props, mode) {
13331
13422
  "onEvent": {
13332
13423
  "click": {
13333
13424
  "actions": [
13425
+ {
13426
+ "actionType": "validate",
13427
+ "componentId": formId
13428
+ },
13334
13429
  {
13335
13430
  "actionType": "custom",
13336
- "script": onPageChangeScript
13431
+ "script": onPageChangeScript,
13432
+ "expression": "${!!!event.data.validateResult.error}" //触发表单校验结果会存入validateResult,amis 3.2不支持,高版本比如 3.5.3支持
13337
13433
  }
13338
13434
  ]
13339
13435
  }
@@ -13358,9 +13454,14 @@ function getFormPagination(props, mode) {
13358
13454
  "onEvent": {
13359
13455
  "click": {
13360
13456
  "actions": [
13457
+ {
13458
+ "actionType": "validate",
13459
+ "componentId": formId
13460
+ },
13361
13461
  {
13362
13462
  "actionType": "custom",
13363
- "script": onPageChangeScript
13463
+ "script": onPageChangeScript,
13464
+ "expression": "${!!!event.data.validateResult.error}" //触发表单校验结果会存入validateResult,amis 3.2不支持,高版本比如 3.5.3支持
13364
13465
  }
13365
13466
  ]
13366
13467
  }
@@ -13852,9 +13953,14 @@ async function getButtonActions(props, mode) {
13852
13953
  "onEvent": {
13853
13954
  "click": {
13854
13955
  "actions": [
13956
+ {
13957
+ "actionType": "validate",
13958
+ "componentId": formId
13959
+ },
13855
13960
  {
13856
13961
  "actionType": "custom",
13857
- "script": onSaveAndNewItemScript
13962
+ "script": onSaveAndNewItemScript,
13963
+ "expression": "${!!!event.data.validateResult.error}" //触发表单校验结果会存入validateResult,amis 3.2不支持,高版本比如 3.5.3支持
13858
13964
  }
13859
13965
  ]
13860
13966
  }
@@ -13867,9 +13973,14 @@ async function getButtonActions(props, mode) {
13867
13973
  "onEvent": {
13868
13974
  "click": {
13869
13975
  "actions": [
13976
+ {
13977
+ "actionType": "validate",
13978
+ "componentId": formId
13979
+ },
13870
13980
  {
13871
13981
  "actionType": "custom",
13872
- "script": onSaveAndCopyItemScript
13982
+ "script": onSaveAndCopyItemScript,
13983
+ "expression": "${!!!event.data.validateResult.error}" //触发表单校验结果会存入validateResult,amis 3.2不支持,高版本比如 3.5.3支持
13873
13984
  }
13874
13985
  ]
13875
13986
  }
@@ -14135,18 +14246,51 @@ async function getButtonView(props) {
14135
14246
 
14136
14247
  async function getButtonDelete(props) {
14137
14248
  return {
14138
- "type": "button",
14139
- "label": "",
14140
- "icon": "fa fa-trash-alt",//不可以用fa-trash-o,因为设计字段布局界面中弹出的设置分组列表中显示不了这个图标
14249
+ "type": "dropdown-button",
14141
14250
  "level": "link",
14142
- "onEvent": {
14143
- "click": {
14144
- "actions": await getButtonActions(props, "delete")
14251
+ "icon": "fa fa-trash-alt",
14252
+ "size": "xs",
14253
+ "hideCaret": true,
14254
+ "closeOnClick": true,
14255
+ "body": [
14256
+ {
14257
+ "type": "wrapper",
14258
+ "size": "md",
14259
+ "className": "w-80",
14260
+ "body": [
14261
+ {
14262
+ "tpl": "确定要删除吗?",
14263
+ "type": "tpl"
14264
+ },
14265
+ {
14266
+ "type": "flex",
14267
+ "justify": "flex-end",
14268
+ "className": "mt-3",
14269
+ "items": [
14270
+ {
14271
+ "type": "button",
14272
+ "label": "取消",
14273
+ "className": "mr-2"
14274
+ },
14275
+ {
14276
+ "type": "button",
14277
+ "label": "删除",
14278
+ "level": "danger",
14279
+ "onEvent": {
14280
+ "click": {
14281
+ "actions": await getButtonActions(props, "delete")
14282
+ }
14283
+ }
14284
+ }
14285
+ ]
14286
+ }
14287
+ ]
14145
14288
  }
14146
- }
14147
- };
14289
+ ]
14290
+ }
14148
14291
  }
14149
14292
 
14293
+
14150
14294
  const getAmisInputTableSchema = async (props) => {
14151
14295
  if (!props.id) {
14152
14296
  props.id = "steedos_input_table_" + props.name + "_" + Math.random().toString(36).substr(2, 9);
@@ -14219,6 +14363,7 @@ const getAmisInputTableSchema = async (props) => {
14219
14363
  if (fieldPrefix) {
14220
14364
  value = getTableValueWithoutFieldPrefix(value, fieldPrefix);
14221
14365
  }
14366
+ value = getTableValueWithEmptyValue(value, fields);
14222
14367
  if (primaryKey) {
14223
14368
  // 这里临时给每行数据补上primaryKey字段值,如果库里不需要保存这里补上的字段值,pipeOut中会识别autoGeneratePrimaryKeyValue属性选择最终移除这里补上的字段值
14224
14369
  // 这里始终自动生成primaryKey字段值,而不是只在pipeOut输出整个子表字段值时才生成,是因为要支持当数据库里保存的子表字段行数据没有primaryKey字段值时的行嵌套模式(即节点的children属性)功能
@@ -14240,6 +14385,7 @@ const getAmisInputTableSchema = async (props) => {
14240
14385
  if (fieldPrefix) {
14241
14386
  value = getTableValuePrependFieldPrefix(value, fieldPrefix, primaryKey);
14242
14387
  }
14388
+ value = getTableValueWithoutEmptyValue(value, fields);
14243
14389
  if (props.autoGeneratePrimaryKeyValue === true) {
14244
14390
  // 如果需要把自动生成的primaryKey值输出保存的库中,则补全所有行中的primaryKey值
14245
14391
  // 这里如果不全部补全的话,初始从库里返回的字段值中拿到的行没primaryKey值的话就不会自动补上
@@ -14268,6 +14414,10 @@ const getAmisInputTableSchema = async (props) => {
14268
14414
  "width": buttonsForColumnOperations.length > 1 ? "60px" : "20px"
14269
14415
  });
14270
14416
  }
14417
+ // if (showAsInlineEditMode) {
14418
+ // // 因为要支持不同的列上配置inlineEditMode属性,所有不可以把整个子表组件都设置为inlineEditMode
14419
+ // inputTableSchema.needConfirm = false;
14420
+ // }
14271
14421
  if (amis) {
14272
14422
  // 支持配置amis属性重写或添加最终生成的input-table中任何属性。
14273
14423
  delete amis.id;//如果steedos-input-table组件配置了amis.id属性,会造成新建编辑行功能不生效
@@ -14308,6 +14458,17 @@ const getAmisInputTableSchema = async (props) => {
14308
14458
  "body": headerToolbar
14309
14459
  });
14310
14460
  }
14461
+ let className = "steedos-input-table";
14462
+
14463
+ if (typeof props.className == "object") {
14464
+ className = {
14465
+ [className]: "true",
14466
+ ...props.className
14467
+ };
14468
+ } else if (typeof props.className == "string") {
14469
+ className = `${className} ${props.className} `;
14470
+ }
14471
+
14311
14472
  let schema = {
14312
14473
  "type": "control",
14313
14474
  "body": {
@@ -14321,7 +14482,7 @@ const getAmisInputTableSchema = async (props) => {
14321
14482
  "labelAlign": props.labelAlign,
14322
14483
  //控制control的mode属性,https://aisuda.bce.baidu.com/amis/zh-CN/components/form/formitem#表单项展示
14323
14484
  "mode": props.mode || null,
14324
- "className": props.className
14485
+ className
14325
14486
  };
14326
14487
  // console.log("===schema===", schema);
14327
14488
  return schema;