diff --git a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js index 741ab92a4d39bc694a37e0ce0b913accdd1cc265..49f6fdde84face75fc6e053c5814c36cd955c6b0 100644 --- a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js +++ b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js @@ -127,20 +127,30 @@ attributes.forEach(function ([attributeId, parentId, simpleName, isActive, ]); }); +var sorter = new AttributeSorter(vars.get("$local.order")); + var resultTable = []; do { var oldSize = resultTable.length; + var layer = []; attributesById.forEach(function (row, id) { - var parentId = row[3]; + if (!row) + { + attributesById["delete"](id); + return; + } + var parentId = row[4]; //rows that are already in the result array are removed from the attributesById Map, so if the parentId is in that Map, //the parent has not been added yet if (!parentId || !attributesById.has(parentId)) { - resultTable.push(row); - attributesById["delete"](id); + layer.push(row); + attributesById.set(id, null); } }); + sorter.sort(layer); + resultTable = resultTable.concat(layer); } while (oldSize != resultTable.length); //stops the loop when no new items were added so that recursive relations between attributes don't cause an infinite loop result.object(resultTable); @@ -217,4 +227,42 @@ function AttributeUsageLoader () return ContextUtils.getTitle(usage, true); }).join(", "); } +} + +function AttributeSorter (pSortOrder) +{ + if (Utils.isNullOrEmpty(pSortOrder)) + { + this.sort = function (pArray) {return pArray;}; + } + else + { + var fieldIndexes = { + "ATTRIBUTE_NAME.value": 1, + "TRANSLATED_NAME.value": 2, + "ATTRIBUTE_TYPE.displayValue": 7, + "ATTRIBUTE_ACTIVE.value": 8, + "SORTING.value": 9, + "USAGELIST.value": 13 + }; + var sortOrder = Utils.objectEntries(vars.get("$local.order")); + if (sortOrder.length === 0) + { + sortOrder = [["ATTRIBUTE_NAME.value", "UP"]] + } + sortOrder = Utils.objectEntries(vars.get("$local.order")).reduce(function (orderMap, [field, direction]) + { + if (field in fieldIndexes) + { + orderMap.set(fieldIndexes[field], direction == "DOWN"); + } + return orderMap; + }, new Map()); + var sortFn = ArrayUtils.getMultiSortCompareFn(sortOrder); + + this.sort = function (pArray) + { + return pArray.sort(sortFn); + } + } } \ No newline at end of file diff --git a/neonContext/WorkflowStartConfig/WorkflowStartConfig.aod b/neonContext/WorkflowStartConfig/WorkflowStartConfig.aod index 5261c781f8746359414b7c3c92f5783050136ff7..7915d25a13f55ec7d8af1a37fad65f7a279ac588 100644 --- a/neonContext/WorkflowStartConfig/WorkflowStartConfig.aod +++ b/neonContext/WorkflowStartConfig/WorkflowStartConfig.aod @@ -2,11 +2,17 @@ <neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.1"> <name>WorkflowStartConfig</name> <majorModelMode>DISTRIBUTED</majorModelMode> + <filterView>WorkflowStartConfigFilter_view</filterView> + <editView>WorkflowStartConfigEdit_view</editView> <entity>WorkflowStartConfig_entity</entity> <references> <neonViewReference> <name>c6e5379e-3df6-4f1d-be39-32fd1ad0852d</name> <view>WorkflowStartConfigFilter_view</view> </neonViewReference> + <neonViewReference> + <name>a8c1e94d-83cb-45c3-afc3-70686705ab82</name> + <view>WorkflowStartConfigEdit_view</view> + </neonViewReference> </references> </neonContext> diff --git a/neonView/WorkflowStartConfigEdit_view/WorkflowStartConfigEdit_view.aod b/neonView/WorkflowStartConfigEdit_view/WorkflowStartConfigEdit_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..90a5234ad36788b21d38e28fc9b9708192a91597 --- /dev/null +++ b/neonView/WorkflowStartConfigEdit_view/WorkflowStartConfigEdit_view.aod @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8"> + <name>WorkflowStartConfigEdit_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <size>SMALL</size> + <layout> + <noneLayout> + <name>layout</name> + </noneLayout> + </layout> + <children> + <genericViewTemplate> + <name>StartConfig</name> + <editMode v="true" /> + <fields> + <entityFieldLink> + <name>48b1dd11-5964-4d46-85eb-3f144ab7b3d2</name> + <entityField>OBJECT_TYPE</entityField> + </entityFieldLink> + </fields> + </genericViewTemplate> + </children> +</neonView> diff --git a/neonView/WorkflowStartConfigFilter_view/WorkflowStartConfigFilter_view.aod b/neonView/WorkflowStartConfigFilter_view/WorkflowStartConfigFilter_view.aod index 2ced9ab248fdce98ea9019cc4442571c4c8c811e..ddee9e3a21a1d14c749fdd5c0a2a2c8644b0ae1b 100644 --- a/neonView/WorkflowStartConfigFilter_view/WorkflowStartConfigFilter_view.aod +++ b/neonView/WorkflowStartConfigFilter_view/WorkflowStartConfigFilter_view.aod @@ -10,8 +10,6 @@ <children> <tableViewTemplate> <name>Table</name> - <inlineEdit v="true" /> - <autoNewRow v="true" /> <entityField>#ENTITY</entityField> <columns> <neonTableColumn> diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index 2a72f327942d4adb6a0472566e15163f23a90256..ecc8f1ed818c8617735dd702a025269dfcfd8fdf 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -1882,7 +1882,9 @@ SqlBuilder.prototype.build = function(pDefaultConditionIfNone) * @param {String[]} pColumns The columns where you want to update. * @param {SQLTYPES[]} [pColumnTypes=null] normally you can set this to null as the types are calculated if not provided * @param {String[]} pValues The values to be updated. - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {Number} the number of rows affected * @throws {Error} if no table is defined */ @@ -2008,7 +2010,9 @@ SqlBuilder.prototype.buildInsertStatement = function (pFieldValues, pTableName, * @param {String[]} pColumns The columns where you want to insert into. * @param {SQLTYPES[]} [pColumnTypes=null] normally you can set this to null as the types are calculated if not provided * @param {String[]} pValues The values to be inserted. - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {Number} the number of rows affected * @throws {Error} if no table is defined */ @@ -2106,7 +2110,9 @@ SqlBuilder._columnsValuesFromObject = function (pFieldValues, pIncludeNullValues * <strong>IMPORTANT: If this is set to false and there is no condition, every row in the table will be deleted!</strong> * @param {String} [pTableName] The table for deleting data. If undefined, the from part of the SqlBuilder will be used. If no from is set, * the table of the first where-condition is used. - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {Number} the number of rows affected * @throws {Error} if no table is defined * @example @@ -2189,8 +2195,12 @@ SqlBuilder.prototype.cell = function(pExecuteOnlyIfConditionExists, pFallbackVal * Note: the default for pExecuteOnlyIfConditionExists is false becausse it is more natural to select all rows if no condition exists. * * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pMaxRows=0] - * @param {Number} [pTimeout=-1] + * @param {Number} [pMaxRows=0] The maximum number of rows to be returned (ORDER BY must be defined in the SQL statement!). + * If you specify maxRows, this restriction might apply to all tables indicated in the JOIN part of the query. + * If you do not want to restrict this value, enter 0. + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[]} the result of the query */ SqlBuilder.prototype.arrayRow = function (pExecuteOnlyIfConditionExists, pMaxRows, pTimeout) @@ -2203,8 +2213,12 @@ SqlBuilder.prototype.arrayRow = function (pExecuteOnlyIfConditionExists, pMaxRow * Note: the default for pExecuteOnlyIfConditionExists is false becausse it is more natural to select all rows if no condition exists. * * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pMaxRows=0] - * @param {Number} [pTimeout=-1] + * @param {Number} [pMaxRows=0] The maximum number of rows to be returned (ORDER BY must be defined in the SQL statement!). + * If you specify maxRows, this restriction might apply to all tables indicated in the JOIN part of the query. + * If you do not want to restrict this value, enter 0. + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[]} the result of the query */ SqlBuilder.prototype.arrayColumn = function (pExecuteOnlyIfConditionExists, pMaxRows, pTimeout) @@ -2218,8 +2232,12 @@ SqlBuilder.prototype.arrayColumn = function (pExecuteOnlyIfConditionExists, pMax * * @param {Number} pType db.ROW or db.COLUMN * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pMaxRows=0] - * @param {Number} [pTimeout=-1] + * @param {Number} [pMaxRows=0] The maximum number of rows to be returned (ORDER BY must be defined in the SQL statement!). + * If you specify maxRows, this restriction might apply to all tables indicated in the JOIN part of the query. + * If you do not want to restrict this value, enter 0. + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[]} the result of the query */ SqlBuilder.prototype.array = function(pType, pExecuteOnlyIfConditionExists, pMaxRows, pTimeout) @@ -2245,7 +2263,9 @@ SqlBuilder.prototype.array = function(pType, pExecuteOnlyIfConditionExists, pMax * @param {Number} pStartIndex * @param {Number} pRowCount * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[]} the result of the query */ SqlBuilder.prototype.arrayPage = function(pType, pStartIndex, pRowCount, pExecuteOnlyIfConditionExists, pTimeout) @@ -2269,8 +2289,12 @@ SqlBuilder.prototype.arrayPage = function(pType, pStartIndex, pRowCount, pExecut * Note: the default for pExecuteOnlyIfConditionExists is false becausse it is more natural to select all rows if no condition exists. * * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pMaxRows=0] - * @param {Number} [pTimeout=-1] + * @param {Number} [pMaxRows=0] The maximum number of rows to be returned (ORDER BY must be defined in the SQL statement!). + * If you specify maxRows, this restriction might apply to all tables indicated in the JOIN part of the query. + * If you do not want to restrict this value, enter 0. + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[][]} the result of the query */ SqlBuilder.prototype.table = function(pExecuteOnlyIfConditionExists, pMaxRows, pTimeout) @@ -2295,7 +2319,9 @@ SqlBuilder.prototype.table = function(pExecuteOnlyIfConditionExists, pMaxRows, p * @param {Number} pStartIndex * @param {Number} pRowCount * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[][]} the result of the query */ SqlBuilder.prototype.tablePage = function(pStartIndex, pRowCount, pExecuteOnlyIfConditionExists, pTimeout) @@ -2343,7 +2369,9 @@ SqlBuilder.prototype.startRow = function (pStartRow) * for iterating over the table pages. You can use SqlBuilder.prototype.hasMoreRows() to check if the end of rows was reached. * * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. * @return {String[][]} the result of the query */ SqlBuilder.prototype.nextTablePage = function (pExecuteOnlyIfConditionExists, pTimeout) @@ -2383,7 +2411,9 @@ SqlBuilder.prototype.hasMoreRows = function () * * @param {Function} pCallBackFn CallBack-Function to execute for every page. If the function returns false, the execution will be stopped. * @param {Boolean} [pExecuteOnlyIfConditionExists=false] if true and there is no condition, [] is returned - * @param {Number} [pTimeout=-1] + * @param {Number} [pTimeout=-1] Specifies the period, in milliseconds, after which the query will be aborted. + * This timeout value overwrites DBSyncTimeout for the SQL command to be executed (this value was predefined in the + * server defaults). If you omit this parameter, DBSyncTimeout will be used. */ SqlBuilder.prototype.forEachPage = function (pCallBackFn, pExecuteOnlyIfConditionExists, pTimeout) { diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js index ada0e3f465462c2959c61f639b5dc3d379cb38e1..5baa6ba7c6517bb00640530ffbcd085e759eaaa0 100644 --- a/process/Util_lib/process.js +++ b/process/Util_lib/process.js @@ -981,23 +981,51 @@ ArrayUtils.sortArrayOfObjects = function(targetArray, key, sortAsc, isNumber) { /** * sorts an array with columns * -* @param {Array} targetArray the array with data -* @param {Array} sortOrder array with the format [columnIndex1, sortDescending1, columnIndex2, sortDescending2, ...], +* @param {Array} pTargetArray the array with data +* @param {Array} pSortOrder array with the format [columnIndex1, sortDescending1, columnIndex2, sortDescending2, ...], * the columnIndex must be an integer, sortDescending must be boolean (true -> descending, just like db.DESCENDING) * @example * ArrayUtils.sortMulti(rows, [1, true, 2, true, 5, false]); * * @return {void} */ -ArrayUtils.sortMulti = function(targetArray, sortOrder) { +ArrayUtils.sortMulti = function(pTargetArray, pSortOrder) +{ + var sortFn = ArrayUtils.getMultiSortCompareFn(ArrayUtils.chunk(pSortOrder, 2)); + + pTargetArray.sort(sortFn); + return pTargetArray; +} + +/** +* makes a sorting function for an array with columns +* +* @param {Map|Array} pSortOrder Map with columnIndex as keys and direction as values, or +* array with the format [[columnIndex1, direction1], [columnIndex2, direction2], ...], +* the columnIndex must be an integer, direction must be boolean (true -> descending, just like db.DESCENDING) +* @example +* var sortFn = ArrayUtils.getMultiSortCompareFn([[1, true], [2, true], [5, false]]); +* rows.sort(sortFn); +* +* @return {void} +*/ +ArrayUtils.getMultiSortCompareFn = function (pSortOrder) +{ + if (Array.isArray(pSortOrder)) + { + pSortOrder = new Map(pSortOrder); + } + /* * @param {String} a req value 1, first compared element * @param {String} b req value 2, sencond compared element * * @return {Integer} -1 - set a below b, 0 - equal, 1 - set b below a */ - var sortFn = function(a, b) { - var stringComparison = function(a, b) { + return function(a, b) + { + var stringComparison = function(a, b) + { a = a.toLowerCase(); a = a.replace(/ä/g,"ae"); a = a.replace(/ö/g,"oe"); @@ -1015,28 +1043,31 @@ ArrayUtils.sortMulti = function(targetArray, sortOrder) { var swap = 0; - for (let i = 0, l = sortOrder.length; i < l; i += 2) + pSortOrder.forEach(function (sortDesc, colIndex) { - let colIndex = sortOrder[i]; - let sortDesc = sortOrder[i+1]; if (swap || colIndex == undefined || sortDesc == undefined) - return swap; + return; if (isNaN(a[colIndex] - b[colIndex])) + { if ((isNaN(a[colIndex])) && (isNaN(b[colIndex]))) - swap = stringComparison(a[colIndex], b[colIndex]); + { + swap = stringComparison(a[colIndex], b[colIndex]); + } else + { swap = (isNaN(a[colIndex]) ? 1 : -1); + } + } else + { swap = (a[colIndex] - b[colIndex]); + } swap *= (sortDesc ? -1 : 1); - } + }); return swap; } - - targetArray.sort(sortFn); - return targetArray; } /**