@steedos-widgets/amis-lib 6.10.12 → 6.10.14
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/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/index.cjs.js +142 -50
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +143 -51
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +26 -23
- package/dist/index.umd.js.map +1 -1
- package/dist/types/workflow/flow.d.ts +2 -7
- package/dist/types/workflow/instance.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _$1 from 'lodash';
|
|
2
|
-
import ___default, { isEmpty, isArray, each, find, endsWith, cloneDeep, forEach, includes, trimEnd, has, isBoolean, omitBy, isNil, toArray, mergeWith, get, map, isString, union, slice, defaultsDeep as defaultsDeep$1, isObject as isObject$1, clone, filter, last, groupBy, sortBy, indexOf
|
|
2
|
+
import ___default, { isEmpty, isArray, each, find, endsWith, cloneDeep, forEach, includes, trimEnd, has, isBoolean, omitBy, isNil, toArray, mergeWith, get, map, isString, union, slice, defaultsDeep as defaultsDeep$1, isObject as isObject$1, clone, filter, last, groupBy, sortBy, indexOf } from 'lodash';
|
|
3
3
|
import i18next from 'i18next';
|
|
4
4
|
export { default as i18next } from 'i18next';
|
|
5
5
|
import { initReactI18next } from 'react-i18next';
|
|
@@ -4663,7 +4663,41 @@ async function getMobileTableColumns(fields, options){
|
|
|
4663
4663
|
tpls.push({ field, tpl });
|
|
4664
4664
|
}
|
|
4665
4665
|
}
|
|
4666
|
-
|
|
4666
|
+
function getUrlParams(search = window.location.search) {
|
|
4667
|
+
const params = {};
|
|
4668
|
+
const queryString = search.startsWith('?') ? search.slice(1) : search;
|
|
4669
|
+
|
|
4670
|
+
if (!queryString) return params;
|
|
4671
|
+
|
|
4672
|
+
queryString.split('&').forEach(pair => {
|
|
4673
|
+
const [key, value] = pair.split('=');
|
|
4674
|
+
if (key) {
|
|
4675
|
+
const decodedKey = decodeURIComponent(key);
|
|
4676
|
+
const decodedValue = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
|
|
4677
|
+
|
|
4678
|
+
// 处理数组参数(如:?color=red&color=blue)
|
|
4679
|
+
if (params.hasOwnProperty(decodedKey)) {
|
|
4680
|
+
if (Array.isArray(params[decodedKey])) {
|
|
4681
|
+
params[decodedKey].push(decodedValue);
|
|
4682
|
+
} else {
|
|
4683
|
+
params[decodedKey] = [params[decodedKey], decodedValue];
|
|
4684
|
+
}
|
|
4685
|
+
} else {
|
|
4686
|
+
params[decodedKey] = decodedValue;
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
});
|
|
4690
|
+
|
|
4691
|
+
return params;
|
|
4692
|
+
}
|
|
4693
|
+
|
|
4694
|
+
const urlParams = getUrlParams();
|
|
4695
|
+
|
|
4696
|
+
let url = getNameTplUrl(nameField, options);
|
|
4697
|
+
if(options.displayAs === 'split'){
|
|
4698
|
+
const additionalFilters = urlParams['additionalFilters'] || '';
|
|
4699
|
+
url = url + `&additionalFilters=${encodeURIComponent(additionalFilters)}`;
|
|
4700
|
+
}
|
|
4667
4701
|
|
|
4668
4702
|
const columnLines = getMobileLines(tpls);
|
|
4669
4703
|
|
|
@@ -11148,7 +11182,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
|
|
|
11148
11182
|
//TODO: dropdown-button只支持在按钮上方配置提示,对于上方按钮的点击会有影响,为保持统一,暂时去除,等待amis优化,https://github.com/baidu/amis/issues/7330
|
|
11149
11183
|
// "tooltip": i18next.t('frontend_button_reload_tooltip'),
|
|
11150
11184
|
"tooltipPlacement": "top",
|
|
11151
|
-
"className":
|
|
11185
|
+
"className": `bg-white p-2 rounded text-gray-500 list-view-btn-reload ${formFactor === 'SMALL' ? 'hidden' : ''}`,
|
|
11152
11186
|
"label": "",
|
|
11153
11187
|
"icon": "fa fa-sync",
|
|
11154
11188
|
// "visibleOn": "${!showFieldsFilter}",
|
|
@@ -11229,7 +11263,7 @@ function getObjectHeaderToolbar(mainObject, fields, formFactor, {
|
|
|
11229
11263
|
// if(toolbarCount){
|
|
11230
11264
|
// toolbars.push(toolbarCount);
|
|
11231
11265
|
// }
|
|
11232
|
-
|
|
11266
|
+
toolbars.push(toolbarReloadButton);
|
|
11233
11267
|
toolbars.push(toolbarDQuickSearchBox);
|
|
11234
11268
|
if(toolbarFilter){
|
|
11235
11269
|
toolbars.push(toolbarFilter);
|
|
@@ -11700,7 +11734,6 @@ async function getObjectCRUD(objectSchema, fields, options){
|
|
|
11700
11734
|
}, bodyProps);
|
|
11701
11735
|
|
|
11702
11736
|
}
|
|
11703
|
-
|
|
11704
11737
|
body = defaultsDeep({}, listSchema, body);
|
|
11705
11738
|
body = await getCrudSchemaWithDataFilter(body, { crudDataFilter, onCrudDataFilter, amisData, env });
|
|
11706
11739
|
|
|
@@ -15539,6 +15572,13 @@ async function convertSFieldToAmisField(field, readonly, ctx) {
|
|
|
15539
15572
|
labelField: 'label',
|
|
15540
15573
|
valueField: 'value'
|
|
15541
15574
|
};
|
|
15575
|
+
if(field.isAmis){
|
|
15576
|
+
delete field.mode;
|
|
15577
|
+
convertData = {
|
|
15578
|
+
...convertData,
|
|
15579
|
+
...field
|
|
15580
|
+
};
|
|
15581
|
+
}
|
|
15542
15582
|
const select_menuTpl = `<span class='flex items-center mt-0.5'>
|
|
15543
15583
|
<span role='img' aria-label='smile' class='anticon anticon-smile'>
|
|
15544
15584
|
<span class='slds-icon_container slds-icon-standard-\${REPLACE(icon,'_','-')}'>
|
|
@@ -16776,7 +16816,7 @@ function getFormFields(props, mode = "edit") {
|
|
|
16776
16816
|
fields = getTableFieldsWithoutFieldPrefix(fields, fieldPrefix);
|
|
16777
16817
|
}
|
|
16778
16818
|
return (fields || []).map(function (item) {
|
|
16779
|
-
let formItem = {
|
|
16819
|
+
let formItem = item.isAmis ? item : {
|
|
16780
16820
|
"type": "steedos-field",
|
|
16781
16821
|
"name": item.name,
|
|
16782
16822
|
"config": item
|
|
@@ -16791,6 +16831,9 @@ function getFormFields(props, mode = "edit") {
|
|
|
16791
16831
|
function getInputTableCell(field, showAsInlineEditMode) {
|
|
16792
16832
|
if (showAsInlineEditMode) {
|
|
16793
16833
|
// 这里不可以用quickEdit,因为amis存在bug:input-table内的字段在行编辑模式时会受到外层相同name的字段的影响 https://github.com/baidu/amis/issues/9653
|
|
16834
|
+
if(field.isAmis){
|
|
16835
|
+
return field;
|
|
16836
|
+
}
|
|
16794
16837
|
return {
|
|
16795
16838
|
"type": "steedos-field",
|
|
16796
16839
|
"config": Object.assign({}, field, {
|
|
@@ -16809,6 +16852,16 @@ function getInputTableCell(field, showAsInlineEditMode) {
|
|
|
16809
16852
|
}
|
|
16810
16853
|
}
|
|
16811
16854
|
else {
|
|
16855
|
+
if(field.isAmis){
|
|
16856
|
+
return {
|
|
16857
|
+
...field,
|
|
16858
|
+
inInputTable: true,
|
|
16859
|
+
"static": true,
|
|
16860
|
+
"readonly": true,
|
|
16861
|
+
label: field.label,
|
|
16862
|
+
name: field.name
|
|
16863
|
+
};
|
|
16864
|
+
}
|
|
16812
16865
|
return {
|
|
16813
16866
|
"type": "steedos-field",
|
|
16814
16867
|
"config": Object.assign({}, field, {
|
|
@@ -17211,6 +17264,7 @@ function getFormPaginationWrapper(props, form, mode) {
|
|
|
17211
17264
|
"method": "get",
|
|
17212
17265
|
"adaptor": `
|
|
17213
17266
|
const formBody = ${JSON.stringify(formBody)};
|
|
17267
|
+
console.log('formBody===>', formBody);
|
|
17214
17268
|
return {
|
|
17215
17269
|
"body": formBody
|
|
17216
17270
|
}
|
|
@@ -18951,7 +19005,6 @@ const showApproveSignImage = (judge) => {
|
|
|
18951
19005
|
};
|
|
18952
19006
|
|
|
18953
19007
|
const getUserApprove = ({ instance, userId }) => {
|
|
18954
|
-
console.log(`getUserApprove===>`, instance, userId);
|
|
18955
19008
|
const currentTrace = find(instance.traces, (trace) => {
|
|
18956
19009
|
return trace.is_finished != true;
|
|
18957
19010
|
});
|
|
@@ -19534,12 +19587,25 @@ const getSubmitActions = async (instance, submitEvents) => {
|
|
|
19534
19587
|
expression: "${event.data.instanceFormValidate && event.data.approvalFormValidate}"
|
|
19535
19588
|
},
|
|
19536
19589
|
{
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19590
|
+
"actionType": "wait",
|
|
19591
|
+
"args": {
|
|
19592
|
+
"time": 300
|
|
19593
|
+
}
|
|
19594
|
+
},
|
|
19595
|
+
{
|
|
19596
|
+
"actionType": "custom",
|
|
19597
|
+
"script": `
|
|
19598
|
+
const appId = context.props.data.appId;
|
|
19599
|
+
const objectName = context.props.data.objectName;
|
|
19600
|
+
const side_listview_id = context.props.data.side_listview_id;
|
|
19601
|
+
const additionalFilters = context.props.data.additionalFilters;
|
|
19602
|
+
if(context.props.data.display === 'split'){
|
|
19603
|
+
window.navigate(\`/app/\${appId}/\${objectName}/view/none?side_object=\${objectName}&side_listview_id=\${side_listview_id}&additionalFilters=\${additionalFilters ? encodeURIComponent(additionalFilters) : ''}\`);
|
|
19604
|
+
window.$(".list-view-btn-reload").click();
|
|
19605
|
+
}else{
|
|
19606
|
+
window.navigate(\`/app/\${appId}/\${objectName}/grid/\${side_listview_id}\`);
|
|
19607
|
+
}
|
|
19608
|
+
`,
|
|
19543
19609
|
expression: "${event.data.instanceFormValidate && event.data.approvalFormValidate}"
|
|
19544
19610
|
},
|
|
19545
19611
|
{
|
|
@@ -19968,6 +20034,7 @@ const getArgumentsList = (func)=>{
|
|
|
19968
20034
|
};
|
|
19969
20035
|
|
|
19970
20036
|
const getFieldEditTpl = async (field, label)=>{
|
|
20037
|
+
console.log('field',field);
|
|
19971
20038
|
const tpl = {
|
|
19972
20039
|
label: label === true ? field.name : false,
|
|
19973
20040
|
name: field.code,
|
|
@@ -20175,6 +20242,7 @@ const getFieldEditTpl = async (field, label)=>{
|
|
|
20175
20242
|
break;
|
|
20176
20243
|
case "number":
|
|
20177
20244
|
tpl.type = "input-number";
|
|
20245
|
+
tpl.precision=2;
|
|
20178
20246
|
break;
|
|
20179
20247
|
case "date":
|
|
20180
20248
|
tpl.type = "input-date";
|
|
@@ -20245,7 +20313,6 @@ const getFieldEditTpl = async (field, label)=>{
|
|
|
20245
20313
|
tpl.options = getSelectOptions(field);
|
|
20246
20314
|
break;
|
|
20247
20315
|
case "odata":
|
|
20248
|
-
console.log('odata field', field);
|
|
20249
20316
|
const argsName = getArgumentsList(field.filters);
|
|
20250
20317
|
var labelField = field.formula.substr(1, field.formula.length - 2);
|
|
20251
20318
|
labelField = labelField.substr(labelField.indexOf(".") + 1);
|
|
@@ -20254,9 +20321,7 @@ const getFieldEditTpl = async (field, label)=>{
|
|
|
20254
20321
|
// tpl.labelField = labelField;
|
|
20255
20322
|
// tpl.valueField = "_value";
|
|
20256
20323
|
tpl.source = {
|
|
20257
|
-
url:
|
|
20258
|
-
? field.url
|
|
20259
|
-
: `\${context.rootUrl}${field.url}`,
|
|
20324
|
+
url: field.url,
|
|
20260
20325
|
method: "get",
|
|
20261
20326
|
dataType: "json",
|
|
20262
20327
|
adaptor:`
|
|
@@ -20276,28 +20341,32 @@ const getFieldEditTpl = async (field, label)=>{
|
|
|
20276
20341
|
return payload;
|
|
20277
20342
|
`,
|
|
20278
20343
|
requestAdaptor: `
|
|
20279
|
-
const
|
|
20280
|
-
|
|
20344
|
+
const filters = ${_.replace(field.filters, /_.pluck/g, '_.map')};
|
|
20345
|
+
const url = ${field.url}
|
|
20346
|
+
if(filters){
|
|
20347
|
+
console.log('filters', filters);
|
|
20281
20348
|
const joinKey = field.url.indexOf('?') > 0 ? '&' : '?';
|
|
20282
|
-
if(
|
|
20349
|
+
if(filters.startsWith('function(') || filters.startsWith('function (')){
|
|
20283
20350
|
const argsName = ${JSON.stringify(argsName)};
|
|
20284
|
-
const fun = eval('_fun='+
|
|
20351
|
+
const fun = eval('_fun='+filters);
|
|
20285
20352
|
const funArgs = [];
|
|
20286
20353
|
for(const item of argsName){
|
|
20287
20354
|
funArgs.push(context[item])
|
|
20288
20355
|
}
|
|
20289
|
-
api.url =
|
|
20356
|
+
api.url = url + joinKey + "$filter=" + fun.apply({}, funArgs)
|
|
20290
20357
|
}else{
|
|
20291
|
-
api.url =
|
|
20358
|
+
api.url = url + joinKey + "$filter=" + filters
|
|
20292
20359
|
}
|
|
20360
|
+
}else{
|
|
20361
|
+
api.url = url
|
|
20293
20362
|
}
|
|
20294
20363
|
api.query = {};
|
|
20295
|
-
console.log('api', api);
|
|
20296
20364
|
return api;
|
|
20297
|
-
|
|
20365
|
+
`,
|
|
20366
|
+
trackExpression: _.join(_.map(argsName, (item)=>{return `\${${item}|json}`}), '-')
|
|
20298
20367
|
};
|
|
20299
|
-
|
|
20300
|
-
console.log(
|
|
20368
|
+
tpl.isAmis=true;
|
|
20369
|
+
console.log(`odata`, tpl);
|
|
20301
20370
|
break;
|
|
20302
20371
|
case "html":
|
|
20303
20372
|
if (tpl.disabled) {
|
|
@@ -20374,7 +20443,7 @@ const getFieldReadonlyTpl = async (field, label)=>{
|
|
|
20374
20443
|
map[item.value] = item.label;
|
|
20375
20444
|
});
|
|
20376
20445
|
tpl.type = 'static';
|
|
20377
|
-
tpl.tpl = `<% var options = ${JSON.stringify(map)}; return (options && options[data
|
|
20446
|
+
tpl.tpl = `<% var options = ${JSON.stringify(map)}; return (options && options[data["${field.code}"]]) || ''%>`;
|
|
20378
20447
|
}else if(field.type === 'odata'){
|
|
20379
20448
|
tpl.type = 'static';
|
|
20380
20449
|
tpl.tpl = `<div>\${${field.code}['@label']}</div>`;
|
|
@@ -20525,7 +20594,6 @@ const getFormTrs = async (instance) => {
|
|
|
20525
20594
|
const trs = [];
|
|
20526
20595
|
let tdFields = [];
|
|
20527
20596
|
let fields = [];
|
|
20528
|
-
console.log('getFormTrs===>', instance.fields);
|
|
20529
20597
|
each(instance.fields, (field) => {
|
|
20530
20598
|
fields.push(field);
|
|
20531
20599
|
if (field.type === "section" && field.fields) {
|
|
@@ -20858,7 +20926,6 @@ const getFlowFormSchema = async (instance, box) => {
|
|
|
20858
20926
|
else {
|
|
20859
20927
|
formContentSchema = await getFormTableView(instance);
|
|
20860
20928
|
}
|
|
20861
|
-
console.log(`formContentSchema`, formContentSchema);
|
|
20862
20929
|
const amisSchemaStr = instance.formVersion?.amis_schema;
|
|
20863
20930
|
|
|
20864
20931
|
let initedEvents = [];
|
|
@@ -20882,7 +20949,6 @@ const getFlowFormSchema = async (instance, box) => {
|
|
|
20882
20949
|
});
|
|
20883
20950
|
}
|
|
20884
20951
|
|
|
20885
|
-
console.log('getFlowFormSchema formContentSchema', formContentSchema);
|
|
20886
20952
|
return {
|
|
20887
20953
|
type: "page",
|
|
20888
20954
|
name: "instancePage",
|
|
@@ -21006,10 +21072,6 @@ const getFlowFormSchema = async (instance, box) => {
|
|
|
21006
21072
|
onEvent: {
|
|
21007
21073
|
"@data.@instanceDetail.changed": {
|
|
21008
21074
|
actions: [
|
|
21009
|
-
{
|
|
21010
|
-
actionType: "custom",
|
|
21011
|
-
script:"debugger;",
|
|
21012
|
-
},
|
|
21013
21075
|
{
|
|
21014
21076
|
componentId:"u:instancePage",
|
|
21015
21077
|
actionType: "reload"
|
|
@@ -21018,6 +21080,10 @@ const getFlowFormSchema = async (instance, box) => {
|
|
|
21018
21080
|
},
|
|
21019
21081
|
"inited": {
|
|
21020
21082
|
"actions": [
|
|
21083
|
+
{
|
|
21084
|
+
actionType: 'broadcast',
|
|
21085
|
+
eventName: "recordLoaded"
|
|
21086
|
+
},
|
|
21021
21087
|
{
|
|
21022
21088
|
"actionType": "setValue",
|
|
21023
21089
|
"componentId": "instance_form",
|
|
@@ -21067,6 +21133,9 @@ const getFlowFormSchema = async (instance, box) => {
|
|
|
21067
21133
|
};
|
|
21068
21134
|
};
|
|
21069
21135
|
|
|
21136
|
+
const flowVersionCache = new Map();
|
|
21137
|
+
const formVersionCache = new Map();
|
|
21138
|
+
|
|
21070
21139
|
const getMoment = ()=>{
|
|
21071
21140
|
if(window.amisRequire){
|
|
21072
21141
|
return window.amisRequire("moment");
|
|
@@ -21117,19 +21186,29 @@ const getApproveValues = ({ instance, trace, step, approve, box }) => {
|
|
|
21117
21186
|
};
|
|
21118
21187
|
|
|
21119
21188
|
const getFlowVersion = async (instance) => {
|
|
21120
|
-
const
|
|
21121
|
-
|
|
21122
|
-
|
|
21123
|
-
|
|
21124
|
-
|
|
21189
|
+
const cacheKey = `${instance.flow._id}_${instance.flow_version}`;
|
|
21190
|
+
|
|
21191
|
+
if (!flowVersionCache.has(cacheKey)) {
|
|
21192
|
+
const result = await fetchAPI$1(`/api/workflow/flow/${instance.flow._id}/version/${instance.flow_version}`, {
|
|
21193
|
+
method: "get"
|
|
21194
|
+
});
|
|
21195
|
+
flowVersionCache.set(cacheKey, result);
|
|
21196
|
+
}
|
|
21197
|
+
|
|
21198
|
+
return flowVersionCache.get(cacheKey);
|
|
21125
21199
|
};
|
|
21126
21200
|
|
|
21127
21201
|
const getFormVersion = async (instance) => {
|
|
21128
|
-
const
|
|
21129
|
-
|
|
21130
|
-
|
|
21131
|
-
|
|
21132
|
-
|
|
21202
|
+
const cacheKey = `${instance.form._id}_${instance.form_version}`;
|
|
21203
|
+
|
|
21204
|
+
if (!formVersionCache.has(cacheKey)) {
|
|
21205
|
+
const result = await fetchAPI$1(`/api/workflow/form/${instance.form._id}/version/${instance.form_version}`, {
|
|
21206
|
+
method: "get"
|
|
21207
|
+
});
|
|
21208
|
+
formVersionCache.set(cacheKey, result);
|
|
21209
|
+
}
|
|
21210
|
+
|
|
21211
|
+
return formVersionCache.get(cacheKey);
|
|
21133
21212
|
};
|
|
21134
21213
|
|
|
21135
21214
|
const getStep = ({ flowVersion, stepId }) => {
|
|
@@ -21186,12 +21265,29 @@ const isNeedToShowSignImage = (is_finished, judge, traceShowSignImage) => {
|
|
|
21186
21265
|
return true;
|
|
21187
21266
|
};
|
|
21188
21267
|
|
|
21268
|
+
// 缓存存储
|
|
21269
|
+
const signCache = new Map();
|
|
21189
21270
|
const getSpaceUserSign = async (space, handler) => {
|
|
21271
|
+
// 生成缓存键
|
|
21272
|
+
const cacheKey = `${space}_${handler}`;
|
|
21273
|
+
|
|
21274
|
+
// 检查缓存
|
|
21275
|
+
if (signCache.has(cacheKey)) {
|
|
21276
|
+
return signCache.get(cacheKey);
|
|
21277
|
+
}
|
|
21278
|
+
|
|
21279
|
+
// 调用API
|
|
21190
21280
|
const result = await fetchAPI$1(`/api/v1/space_user_signs?filters=[["space","=","${space}"],["user","=","${handler}"]]&fields=["sign"]`);
|
|
21281
|
+
|
|
21282
|
+
let sign = null;
|
|
21191
21283
|
if (result?.data?.items && result.data.items.length > 0) {
|
|
21192
|
-
|
|
21284
|
+
sign = result.data.items[0].sign;
|
|
21193
21285
|
}
|
|
21194
|
-
|
|
21286
|
+
|
|
21287
|
+
// 写入缓存
|
|
21288
|
+
signCache.set(cacheKey, sign);
|
|
21289
|
+
|
|
21290
|
+
return sign;
|
|
21195
21291
|
};
|
|
21196
21292
|
|
|
21197
21293
|
const getInstanceInfo = async (props) => {
|
|
@@ -21249,7 +21345,6 @@ const getInstanceInfo = async (props) => {
|
|
|
21249
21345
|
if (!instance) {
|
|
21250
21346
|
return undefined;
|
|
21251
21347
|
}
|
|
21252
|
-
console.log(`box====>`, box);
|
|
21253
21348
|
if (box === "inbox" || box === "draft") {
|
|
21254
21349
|
userApprove = getUserApprove({ instance, userId });
|
|
21255
21350
|
}
|
|
@@ -21264,9 +21359,6 @@ const getInstanceInfo = async (props) => {
|
|
|
21264
21359
|
step = getStep({ flowVersion, stepId: trace.step });
|
|
21265
21360
|
}
|
|
21266
21361
|
|
|
21267
|
-
console.log(`userApprove===>`, userApprove);
|
|
21268
|
-
console.log(`step===>`, step);
|
|
21269
|
-
|
|
21270
21362
|
let currentStep = getStep({ flowVersion, stepId: ___default.last(instance.traces).step });
|
|
21271
21363
|
|
|
21272
21364
|
const lastCCStep = getLastCCStep(instance, userId);
|