Skip to content

Commit 4c88288

Browse files
authored
Merge pull request #70 from mendix/release/4.3.0
Workflow Commons v4.3.0
2 parents 248c91c + 635a8ae commit 4c88288

File tree

654 files changed

+6772
-4816
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

654 files changed

+6772
-4816
lines changed

ReleaseNotes.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## Release 4.3.0
2+
3+
* We updated Data Widgets module compatibility to v3.5.0
4+
* We updated Atlas Core module compatibility to v4.1.3
5+
* We updated Atlas Web Content module compatibility to v4.1.0
6+
* We fixed an issue where switching between the Minimal, Default and All views did not work correctly for the Audit Trail.
7+
8+
_______
9+
110
## Release 4.2.0
211

312
* We added a conflict resolution feature that allows workflow administrators to resolve incompatible workflows in groups. For more information, refer to the Workflow Commons module documentation.

Releases/WorkflowCommons-4-3-0.mpk

2.88 MB
Binary file not shown.
12 KB
Binary file not shown.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
11+
// BEGIN EXTRA CODE
12+
// END EXTRA CODE
13+
14+
/**
15+
* @param {string} targetName - The name of the widget for which selection should be cleared.
16+
* @returns {Promise.<void>}
17+
*/
18+
export async function Clear_Selection(targetName) {
19+
// BEGIN USER CODE
20+
const plugin = window["com.mendix.widgets.web.plugin.externalEvents"];
21+
if (plugin) {
22+
plugin.emit(targetName, "selection.clear");
23+
}
24+
// END USER CODE
25+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
import AsyncStorage from '@react-native-async-storage/async-storage';
11+
12+
// BEGIN EXTRA CODE
13+
// END EXTRA CODE
14+
15+
/**
16+
* @param {string} key
17+
* @param {string} entity
18+
* @returns {Promise.<MxObject>}
19+
*/
20+
export async function JS_GetFeedbackStorageObject(key, entity) {
21+
// BEGIN USER CODE
22+
if (!key) {
23+
return Promise.reject(new Error("Input parameter 'Key' is required"));
24+
}
25+
if (!entity) {
26+
return Promise.reject(new Error("Input parameter 'Entity' is required"));
27+
}
28+
return getItem(key).then(result => {
29+
if (result === null) {
30+
return Promise.reject(new Error(`Storage item '${key}' does not exist`));
31+
}
32+
const value = JSON.parse(result);
33+
return getOrCreateMxObject(entity, value).then(newObject => {
34+
const newValue = serializeMxObject(newObject);
35+
return setItem(key, JSON.stringify(newValue)).then(() => newObject);
36+
});
37+
});
38+
function getItem(key) {
39+
if (navigator && navigator.product === "ReactNative") {
40+
return AsyncStorage.getItem(key);
41+
}
42+
if (window) {
43+
const value = window.localStorage.getItem(key);
44+
return Promise.resolve(value);
45+
}
46+
return Promise.reject(new Error("No storage API available"));
47+
}
48+
function setItem(key, value) {
49+
if (navigator && navigator.product === "ReactNative") {
50+
return AsyncStorage.setItem(key, value);
51+
}
52+
if (window) {
53+
window.localStorage.setItem(key, value);
54+
return Promise.resolve();
55+
}
56+
return Promise.reject(new Error("No storage API available"));
57+
}
58+
function getOrCreateMxObject(entity, value) {
59+
return getMxObject(value.guid).then(existingObject => {
60+
if (existingObject) {
61+
return existingObject;
62+
}
63+
else {
64+
return createMxObject(entity, value);
65+
}
66+
});
67+
}
68+
function getMxObject(guid) {
69+
return new Promise((resolve, reject) => {
70+
mx.data.get({
71+
guid,
72+
callback: mxObject => resolve(mxObject),
73+
error: error => reject(error)
74+
});
75+
});
76+
}
77+
function createMxObject(entity, value) {
78+
return new Promise((resolve, reject) => {
79+
mx.data.create({
80+
entity,
81+
callback: mxObject => {
82+
Object.keys(value)
83+
.filter(attribute => attribute !== "guid")
84+
.forEach(attributeName => {
85+
const attributeValue = value[attributeName];
86+
mxObject.set(attributeName, attributeValue);
87+
});
88+
resolve(mxObject);
89+
},
90+
error: () => reject(new Error(`Could not create '${entity}' object`))
91+
});
92+
});
93+
}
94+
function serializeMxObject(object) {
95+
return object.getAttributes().reduce((accumulator, attributeName) => {
96+
accumulator[attributeName] = object.get(attributeName);
97+
return accumulator;
98+
}, { guid: object.getGuid() });
99+
}
100+
// END USER CODE
101+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
11+
// BEGIN EXTRA CODE
12+
// END EXTRA CODE
13+
14+
/**
15+
* @param {string} localStorageKey
16+
* @param {string} objectItemKey
17+
* @returns {Promise.<string>}
18+
*/
19+
export async function JS_GetSingleLocalStorageObjectItem(localStorageKey, objectItemKey) {
20+
// BEGIN USER CODE
21+
if (!localStorageKey) {
22+
return Promise.reject(new Error("Input parameter 'localStorageKey' is required"));
23+
}
24+
if (!objectItemKey) {
25+
return Promise.reject(new Error("Input parameter 'objectItemKey' is required"));
26+
}
27+
const localObject = window.localStorage.getItem(localStorageKey);
28+
const parsedObject = JSON.parse(localObject);
29+
const singleItem = parsedObject?.[objectItemKey] ?? "";
30+
31+
return Promise.resolve(singleItem);
32+
// END USER CODE
33+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
import { getUserRoleNames } from "mx-api/session";
11+
import { ui, session } from "mx-api";
12+
13+
// BEGIN EXTRA CODE
14+
const handleUserRoles = async () => {
15+
try {
16+
let userRoles;
17+
18+
if (
19+
typeof mx !== "undefined" &&
20+
typeof mx.session === "object" &&
21+
typeof mx.session.getUserRoleNames === "function"
22+
) {
23+
userRoles = mx.session.getUserRoleNames();
24+
} else if (typeof getUserRoleNames !== "function" || getUserRoleNames === undefined) {
25+
userRoles = getUserRoleNames();
26+
} else {
27+
console.error("Feedback module cannot access a valid user role retrieval function.");
28+
return undefined;
29+
}
30+
31+
if (!Array.isArray(userRoles) || userRoles.length === 0) {
32+
console.error("User roles not available or empty.");
33+
return undefined;
34+
}
35+
36+
return userRoles[0];
37+
} catch (error) {
38+
console.error("Feedback module failed to get the user role name.", error);
39+
return undefined;
40+
}
41+
};
42+
43+
const handlePagePath = async () => {
44+
try {
45+
if (
46+
typeof mx !== "undefined" &&
47+
typeof mx.ui.getContentForm === "function" &&
48+
typeof mx.ui.getContentForm().path !== "undefined"
49+
) {
50+
return mx.ui.getContentForm().path;
51+
} else {
52+
return window.history.state.pageName;
53+
}
54+
} catch(error) {
55+
console.error("Feedback module cannot get the Mendix App page name", error);
56+
return undefined;
57+
}
58+
};
59+
// END EXTRA CODE
60+
61+
/**
62+
* What does this JavaScript action do?
63+
*
64+
* Returns meta data from the clients internet browser.
65+
*
66+
* This includes;
67+
*
68+
* ActiveUserRoles
69+
* PageName
70+
* EnvironmentURL
71+
* Browser
72+
* ScreenWidth
73+
* ScreenHeight
74+
* @param {MxObject} feedback
75+
* @returns {Promise.<MxObject>}
76+
*/
77+
export async function JS_PopulateFeedbackMetadata(feedback) {
78+
// BEGIN USER CODE
79+
try {
80+
const userRoles = await handleUserRoles();
81+
const pagePath = await handlePagePath();
82+
83+
feedback.set("ActiveUserRoles", userRoles || "");
84+
feedback.set("PageName", pagePath || "");
85+
feedback.set("EnvironmentURL", window.location.href || "");
86+
feedback.set("Browser", navigator.userAgent || "");
87+
feedback.set("ScreenWidth", window.screen.width || "");
88+
feedback.set("ScreenHeight", window.screen.height || "");
89+
return feedback;
90+
} catch (error) {
91+
console.error("Feedback Module cannot correctly set meta data.", error);
92+
};
93+
// END USER CODE
94+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
11+
// BEGIN EXTRA CODE
12+
// END EXTRA CODE
13+
14+
/**
15+
* @returns {Promise.<void>}
16+
*/
17+
export async function JS_Recalculate_MendixModal_Error_PopUp_Zindex() {
18+
// BEGIN USER CODE
19+
20+
function setModalZindex(cssSelector, zIndexValue) {
21+
try {
22+
const htmlElement = document.querySelectorAll(cssSelector);
23+
24+
if(!htmlElement.length) {
25+
return;
26+
}
27+
28+
htmlElement.forEach(item => item.style.zIndex = zIndexValue);
29+
30+
} catch(error) {
31+
console.warn("Feedback Module JS Action JS_Recalculate_Modal_Zindex could not execute correctly.", error);
32+
}
33+
};
34+
35+
setTimeout(() => {
36+
setModalZindex(".mx-dialog-info, mx-dialog-warning, .mx-dialog-error", "90");
37+
setModalZindex(".mx-underlay", "80");
38+
},500);
39+
// END USER CODE
40+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
import "mx-global";
9+
import { Big } from "big.js";
10+
11+
// BEGIN EXTRA CODE
12+
// END EXTRA CODE
13+
14+
/**
15+
* What does this JavaScript action do?
16+
*
17+
* After you have uploaded an image it removes locally stored image from memory. This is a custom build action.
18+
*
19+
* Dependency Note:
20+
* This JavaScript action should be used only when you have inserted the Image Upload JavaScript Action called 'JS_UploadAndConvertToFileBlobURL' into your nanoflow.
21+
*
22+
* More detailed explanation: Memory management.
23+
*
24+
* To upload a image we use a custom build Javascript action called 'JS_UploadAndConvertToFileBlobURL'.
25+
* Inside this action we use a JavaScript method called createObjectURL() to upload and store files in local memory. We can access and cosume this in memory image resource via the URL path that is returned from the createObjectURL() method.
26+
*
27+
* However, each time you call createObjectURL(), a new object is created in memory, even if you've already created one for the same object.
28+
* So each of these must be released by calling this action called 'JS_RevokeUploadedFileFromMemory' when you no longer need them.
29+
*
30+
* Browsers will release object URLs automatically when the document is unloaded; however, for optimal performance and memory usage, if there are safe times when you can explicitly unload them, you should do so with the JavaScriptAction called 'JS_RevokeUploadedFileFromMemory'.
31+
* @param {string} fileBlobURL - You have to pass the fileBlobURL that was created using the URL.createObjectURL() in the JS Action called 'JS_UploadAndConvertToFileBlobURL'
32+
* @returns {Promise.<void>}
33+
*/
34+
export async function JS_RevokeUploadedFileFromMemory(fileBlobURL) {
35+
// BEGIN USER CODE
36+
/* We use the URL.createObjectURL() static method which creates a string containing a URL representing the
37+
image uploaded.
38+
The image blob is stored in the clients browser and takes up memory whilst the session is active. So here we
39+
revoke the image when the user deletes the image. Note that the image is automaticlly revoked when the browser refreshes
40+
or closes.
41+
42+
You have to pass the fileBlobURL that was created using the URL.createObjectURL() in the JS Action called 'JS_UploadAndConvertToFileBlobURL'
43+
*/
44+
if(fileBlobURL && typeof fileBlobURL === "string"){
45+
URL.revokeObjectURL(fileBlobURL);
46+
} else {
47+
throw new Error("Image was not removed from browser memory");
48+
}
49+
// END USER CODE
50+
}

0 commit comments

Comments
 (0)