@carbonorm/carbonreact 3.6.2 → 4.0.1
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/README.md +1 -1
- package/dist/CarbonReact.d.ts +17 -8
- package/dist/components/Alert/Alert.d.ts +5 -1
- package/dist/components/Errors/BackendThrowable.d.ts +4 -1
- package/dist/components/WebSocket/CarbonWebSocket.d.ts +3 -1
- package/dist/hoc/KeysMatching.d.ts +1 -1
- package/dist/hoc/SubsetMatching.d.ts +4 -0
- package/dist/hoc/deleteRestfulObjectArrays.d.ts +17 -3
- package/dist/hoc/updateRestfulObjectArrays.d.ts +25 -11
- package/dist/index.cjs.js +156 -169
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +157 -170
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/CarbonReact.tsx +36 -21
- package/src/components/Alert/Alert.tsx +32 -29
- package/src/components/Errors/BackendThrowable.tsx +11 -8
- package/src/components/WebSocket/CarbonWebSocket.tsx +21 -15
- package/src/hoc/KeysMatching.ts +4 -2
- package/src/hoc/SubsetMatching.ts +6 -0
- package/src/hoc/deleteRestfulObjectArrays.tsx +51 -52
- package/src/hoc/updateRestfulObjectArrays.tsx +97 -97
- package/src/index.ts +1 -0
- package/src/variables/C6.tsx +1 -1
- package/dist/variables/C6.d.ts +0 -842
package/dist/index.cjs.js
CHANGED
|
@@ -1411,11 +1411,11 @@ function hexToRgb (hex) {
|
|
|
1411
1411
|
|
|
1412
1412
|
var styles = {"maintenance-hero":"C5KSPNF","maintenanceHero":"C5KSPNF","httpStatusCode":"NhyRQts","centeredContainer":"nA4Uno6","errorTextGeneral":"yJAgaUs","errorKeys":"SRIoY4m","error-values":"xQIsoNw","errorValues":"xQIsoNw","error-pre":"C6eWpJ3","errorPre":"C6eWpJ3","line-number":"NFRyo7M","lineNumber":"NFRyo7M","cl":"vR2jbfr","slide":"OO2C-Wp"};
|
|
1413
1413
|
|
|
1414
|
-
var BackendThrowable = () => {
|
|
1415
|
-
const
|
|
1416
|
-
const currentThrowable =
|
|
1417
|
-
console.log([
|
|
1418
|
-
return jsxRuntime_2("div", { className: styles.maintenanceHero, children: [jsxRuntime_1("h1", { className: styles.httpStatusCode, children: currentThrowable?.status || 500 }), jsxRuntime_1(OutsideClickHandler, { onOutsideClick: () =>
|
|
1414
|
+
var BackendThrowable = (props) => {
|
|
1415
|
+
const { instance } = props;
|
|
1416
|
+
const currentThrowable = instance.state.backendThrowable[0];
|
|
1417
|
+
console.log([instance.state.backendThrowable, currentThrowable]);
|
|
1418
|
+
return jsxRuntime_2("div", { className: styles.maintenanceHero, children: [jsxRuntime_1("h1", { className: styles.httpStatusCode, children: currentThrowable?.status || 500 }), jsxRuntime_1(OutsideClickHandler, { onOutsideClick: () => instance.setState(currentState => ({ backendThrowable: currentState.backendThrowable.slice(1) })), children: jsxRuntime_1("div", { className: styles.centeredContainer, children: Object.keys(currentThrowable).map((key, index) => {
|
|
1419
1419
|
const valueIsString = typeof currentThrowable[key] === 'string';
|
|
1420
1420
|
const valueIsCode = 'THROWN NEAR' === key;
|
|
1421
1421
|
return jsxRuntime_2("div", { children: [jsxRuntime_2("div", { className: styles.errorTextGeneral, children: [" > ", jsxRuntime_1("span", { className: styles.errorKeys, children: key }), ":", valueIsString
|
|
@@ -3924,14 +3924,14 @@ function Popup({ open = true, handleClose, children, maxWidth, }) {
|
|
|
3924
3924
|
const isProduction = window.location.host.split(".")[0] === "www";
|
|
3925
3925
|
|
|
3926
3926
|
function addAlert(props) {
|
|
3927
|
-
|
|
3927
|
+
props.instance.setState(previousState => ({
|
|
3928
3928
|
alertsWaiting: previousState.alertsWaiting.length === 0
|
|
3929
3929
|
? [props]
|
|
3930
3930
|
: [...previousState.alertsWaiting, props]
|
|
3931
3931
|
}));
|
|
3932
3932
|
}
|
|
3933
|
-
function Alert() {
|
|
3934
|
-
const { alertsWaiting, backendThrowable } =
|
|
3933
|
+
function Alert({ instance }) {
|
|
3934
|
+
const { alertsWaiting, backendThrowable } = instance.state;
|
|
3935
3935
|
let alert = undefined;
|
|
3936
3936
|
const alertWaiting = alertsWaiting.length + backendThrowable.length;
|
|
3937
3937
|
if (backendThrowable.length !== 0) {
|
|
@@ -3946,8 +3946,9 @@ function Alert() {
|
|
|
3946
3946
|
color: 'primary',
|
|
3947
3947
|
});
|
|
3948
3948
|
}
|
|
3949
|
-
const backendThrowable =
|
|
3949
|
+
const backendThrowable = instance.state.backendThrowable[0];
|
|
3950
3950
|
alert = {
|
|
3951
|
+
instance: instance,
|
|
3951
3952
|
title: "Oh no! An issue occurred!",
|
|
3952
3953
|
text: backendThrowable?.['DropInGaming\\PHP\\Errors\\DropException'] ?? 'An unknown issue occurred. Please try again.',
|
|
3953
3954
|
timeout: 0,
|
|
@@ -3958,7 +3959,7 @@ function Alert() {
|
|
|
3958
3959
|
backendThrowable: backendThrowable,
|
|
3959
3960
|
then: (value) => {
|
|
3960
3961
|
if (value === 'Expand') {
|
|
3961
|
-
|
|
3962
|
+
instance.setState(previousState => {
|
|
3962
3963
|
let backendThrowable = previousState.backendThrowable.pop();
|
|
3963
3964
|
if (backendThrowable === undefined) {
|
|
3964
3965
|
return {
|
|
@@ -3972,7 +3973,7 @@ function Alert() {
|
|
|
3972
3973
|
});
|
|
3973
3974
|
}
|
|
3974
3975
|
else {
|
|
3975
|
-
|
|
3976
|
+
instance.setState(previousState => ({
|
|
3976
3977
|
backendThrowable: previousState.backendThrowable.slice(1)
|
|
3977
3978
|
}));
|
|
3978
3979
|
}
|
|
@@ -3986,15 +3987,14 @@ function Alert() {
|
|
|
3986
3987
|
return null;
|
|
3987
3988
|
}
|
|
3988
3989
|
const timeout = alert?.timeout || 15000;
|
|
3989
|
-
const
|
|
3990
|
-
const dig = getStyles();
|
|
3990
|
+
const styles = getStyles();
|
|
3991
3991
|
let cancelTimeout = null;
|
|
3992
3992
|
const handleClose = () => {
|
|
3993
3993
|
if (null !== cancelTimeout) {
|
|
3994
3994
|
clearTimeout(cancelTimeout);
|
|
3995
3995
|
}
|
|
3996
3996
|
if (alert?.backendThrowable === undefined) {
|
|
3997
|
-
|
|
3997
|
+
instance.setState(previousState => ({
|
|
3998
3998
|
alertsWaiting: previousState.alertsWaiting.slice(1)
|
|
3999
3999
|
}));
|
|
4000
4000
|
}
|
|
@@ -4008,25 +4008,26 @@ function Alert() {
|
|
|
4008
4008
|
handleClose();
|
|
4009
4009
|
}, timeout);
|
|
4010
4010
|
}
|
|
4011
|
-
return jsxRuntime_1(Popup, { handleClose: handleClose, children: jsxRuntime_2("div", { className: classNames("model-content",
|
|
4011
|
+
return jsxRuntime_1(Popup, { handleClose: handleClose, children: jsxRuntime_2("div", { className: classNames("model-content", styles.rounded0, styles.border0), style: {
|
|
4012
4012
|
maxWidth: '75vw',
|
|
4013
4013
|
maxHeight: '75vh',
|
|
4014
|
-
}, children: [jsxRuntime_2("div", { className: classNames(
|
|
4014
|
+
}, children: [jsxRuntime_2("div", { className: classNames(styles.modalHeader, styles.rounded0, styles.border0, {
|
|
4015
4015
|
// icon?: "warning" | "error" | "success" | "info" | "question"
|
|
4016
|
-
[
|
|
4017
|
-
[
|
|
4018
|
-
[
|
|
4019
|
-
[
|
|
4020
|
-
[
|
|
4021
|
-
}), children: [jsxRuntime_2("h3", { className: classNames(
|
|
4022
|
-
jsxRuntime_2("div", { className: classNames(
|
|
4023
|
-
|
|
4016
|
+
[styles.bg_primary]: "info" === alert.icon || alert.icon === undefined || alert.icon === null,
|
|
4017
|
+
[styles.bg_success]: "success" === alert.icon,
|
|
4018
|
+
[styles.bg_warning]: "warning" === alert.icon,
|
|
4019
|
+
[styles.bg_danger]: "error" === alert.icon, // TODO - change to red
|
|
4020
|
+
[styles.bgPrimary]: "question" === alert.icon,
|
|
4021
|
+
}), children: [jsxRuntime_2("h3", { className: classNames(styles.modalTitle, styles.textDark), id: "staticBackdropLabel", children: ["#", alertWaiting, " ", alert.title] }), jsxRuntime_1("div", { onClick: handleClose, children: jsxRuntime_1(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faClose, size: 'xl' }) })] }), jsxRuntime_1("div", { className: classNames(styles.modalBody, styles.border0, styles.textWhite), children: jsxRuntime_2("div", { className: styles.textCenter, children: [alert.text, alert.component] }) }), undefined !== alert.buttons &&
|
|
4022
|
+
jsxRuntime_2("div", { className: classNames(styles.modalFooter, styles.border0, styles.rounded0), children: [alert.footerText &&
|
|
4023
|
+
jsxRuntime_1("div", { className: classNames(styles.textCenter, styles.textWhite), children: alert.footerText }), alert.buttons?.map((button, index) => {
|
|
4024
|
+
return jsxRuntime_1("button", { className: classNames(styles.btn, styles.btnLg, {
|
|
4024
4025
|
// todo - color: "default" | "primary" | "secondary" | "inherit" | "danger" | "info" | "success" | "warning" | undefined,
|
|
4025
|
-
[
|
|
4026
|
-
[
|
|
4027
|
-
[
|
|
4028
|
-
[
|
|
4029
|
-
}, "btn-Yes",
|
|
4026
|
+
[styles.bg_success]: "success" === button.color,
|
|
4027
|
+
[styles.bg_danger]: "danger" === button.color,
|
|
4028
|
+
[styles.bg_primary]: "primary" === button.color,
|
|
4029
|
+
[styles.bg_warning]: "warning" === button.color,
|
|
4030
|
+
}, "btn-Yes", styles.rounded0), onClick: () => {
|
|
4030
4031
|
handleClose();
|
|
4031
4032
|
alert?.then?.(button.value ?? button.text);
|
|
4032
4033
|
}, children: button.text }, index);
|
|
@@ -4064,14 +4065,16 @@ const useEffectOnce = (effect) => {
|
|
|
4064
4065
|
* @function connect
|
|
4065
4066
|
* This function establishes a connection with the websocket and also ensures constant reconnection if connection closes
|
|
4066
4067
|
**/
|
|
4067
|
-
function initiateWebsocket(
|
|
4068
|
-
|
|
4068
|
+
function initiateWebsocket(props) {
|
|
4069
|
+
let { instance, TABLES = undefined, WsLiveUpdates = undefined, url = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + '://' + window.location.host + '/carbonorm/websocket', timeoutSeconds = 250, heartbeatSeconds = 60 } = props;
|
|
4070
|
+
const { websocket } = instance.state;
|
|
4069
4071
|
if (!("WebSocket" in window)) {
|
|
4070
4072
|
// todo - store that this has been shown in the state
|
|
4071
4073
|
addAlert({
|
|
4072
4074
|
title: 'Browser does not support websockets, live updates will fail. You may need to refresh the page to see the newest content.',
|
|
4073
4075
|
text: 'Please use a modern browser.',
|
|
4074
4076
|
icon: 'warning',
|
|
4077
|
+
instance
|
|
4075
4078
|
});
|
|
4076
4079
|
}
|
|
4077
4080
|
if (false === (undefined === websocket || null === websocket)) {
|
|
@@ -4080,14 +4083,14 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
|
|
|
4080
4083
|
let connectInterval;
|
|
4081
4084
|
const connection = new WebSocket(url);
|
|
4082
4085
|
console.log("Connecting websocket url", url);
|
|
4083
|
-
|
|
4086
|
+
instance.setState({
|
|
4084
4087
|
websocket: connection
|
|
4085
4088
|
}, () => {
|
|
4086
4089
|
connection.onopen = () => {
|
|
4087
4090
|
console.log('WebSocket Client Connected To :: ' + url);
|
|
4088
4091
|
clearTimeout(connectInterval); // clear Interval on open of websocket connection
|
|
4089
4092
|
function heartbeat() {
|
|
4090
|
-
const { websocket } =
|
|
4093
|
+
const { websocket } = instance.state;
|
|
4091
4094
|
if (!websocket)
|
|
4092
4095
|
return;
|
|
4093
4096
|
if (websocket.readyState !== 1)
|
|
@@ -4102,7 +4105,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
|
|
|
4102
4105
|
if (message.data === 'pong') {
|
|
4103
4106
|
return;
|
|
4104
4107
|
}
|
|
4105
|
-
|
|
4108
|
+
instance.setState((prevState) => ({
|
|
4106
4109
|
websocketEvents: prevState.websocketEvents.concat(message),
|
|
4107
4110
|
websocketData: prevState.websocketData.concat(parsedData), // JSON.parse no good - base64?
|
|
4108
4111
|
}), () => {
|
|
@@ -4126,7 +4129,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
|
|
|
4126
4129
|
}
|
|
4127
4130
|
console.log('todo - going to impl REST', TABLE_NAME, METHOD, REQUEST_PRIMARY_KEY, parsedData?.REST);
|
|
4128
4131
|
const TABLE_NAME_SHORT = TABLE_NAME.substring(TABLE_PREFIX.length);
|
|
4129
|
-
const currentCache =
|
|
4132
|
+
const currentCache = instance.state[TABLE_NAME_SHORT];
|
|
4130
4133
|
// just because we have a websocket update, doesn't mean we need the update
|
|
4131
4134
|
// check to see if the primary key is in the current cache
|
|
4132
4135
|
const c6Table = TABLES[TABLE_NAME_SHORT] ?? null;
|
|
@@ -4163,7 +4166,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
|
|
|
4163
4166
|
}
|
|
4164
4167
|
});
|
|
4165
4168
|
};
|
|
4166
|
-
window.addEventListener("focus", () => initiateWebsocket());
|
|
4169
|
+
window.addEventListener("focus", () => initiateWebsocket(props));
|
|
4167
4170
|
// websocket onclose event listener
|
|
4168
4171
|
connection.addEventListener('close', event => {
|
|
4169
4172
|
let reason;
|
|
@@ -4172,7 +4175,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
|
|
|
4172
4175
|
const retrySeconds = Math.min(5000, (timeoutSeconds + timeoutSeconds) * 1000);
|
|
4173
4176
|
timeoutSeconds = retrySeconds;
|
|
4174
4177
|
console.log(`WebSocket reconnect will be attempted in ${retrySeconds} second(s).`);
|
|
4175
|
-
connectInterval = setTimeout(() => initiateWebsocket(), retrySeconds);
|
|
4178
|
+
connectInterval = setTimeout(() => initiateWebsocket(props), retrySeconds);
|
|
4176
4179
|
};
|
|
4177
4180
|
// See https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
|
|
4178
4181
|
switch (event.code) {
|
|
@@ -4236,6 +4239,106 @@ function CarbonWebSocket (props) {
|
|
|
4236
4239
|
return null;
|
|
4237
4240
|
}
|
|
4238
4241
|
|
|
4242
|
+
exports.eUpdateInsertMethod = void 0;
|
|
4243
|
+
(function (eUpdateInsertMethod) {
|
|
4244
|
+
eUpdateInsertMethod[eUpdateInsertMethod["REPLACE"] = 0] = "REPLACE";
|
|
4245
|
+
eUpdateInsertMethod[eUpdateInsertMethod["FIRST"] = 1] = "FIRST";
|
|
4246
|
+
eUpdateInsertMethod[eUpdateInsertMethod["LAST"] = 2] = "LAST";
|
|
4247
|
+
})(exports.eUpdateInsertMethod || (exports.eUpdateInsertMethod = {}));
|
|
4248
|
+
/**
|
|
4249
|
+
* Updates or inserts objects in a stateful array, merging new data with existing objects.
|
|
4250
|
+
* @param instance - The React component instance.
|
|
4251
|
+
* @param dataOrCallback - Array of objects or a callback function returning an array of objects.
|
|
4252
|
+
* @param stateKey - The key in the state where the data array is stored.
|
|
4253
|
+
* @param uniqueObjectId - The unique identifier(s) for objects, typically the primary key of the table.
|
|
4254
|
+
* @param insertUpdateOrder - The order in which new data should be inserted/updated.
|
|
4255
|
+
* @param callback - Optional callback function to run after state update.
|
|
4256
|
+
*/
|
|
4257
|
+
function updateRestfulObjectArrays({ instance, dataOrCallback, stateKey, uniqueObjectId, insertUpdateOrder = exports.eUpdateInsertMethod.LAST, callback, }) {
|
|
4258
|
+
const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
|
|
4259
|
+
instance.setState((previousBootstrapState, props) => {
|
|
4260
|
+
let newOrReplacementData = [];
|
|
4261
|
+
if (Array.isArray(dataOrCallback)) {
|
|
4262
|
+
newOrReplacementData = dataOrCallback;
|
|
4263
|
+
}
|
|
4264
|
+
else if (typeof dataOrCallback === "function") {
|
|
4265
|
+
newOrReplacementData = dataOrCallback(previousBootstrapState, props);
|
|
4266
|
+
}
|
|
4267
|
+
else {
|
|
4268
|
+
throw new Error("The dataOrCallback parameter must be an array or function");
|
|
4269
|
+
}
|
|
4270
|
+
if (newOrReplacementData === null) {
|
|
4271
|
+
return null;
|
|
4272
|
+
}
|
|
4273
|
+
const findUniqueObjectIds = (item, value) => {
|
|
4274
|
+
return uniqueObjectIds.every((id) => item[id] === value[id]);
|
|
4275
|
+
};
|
|
4276
|
+
const previousStateProperty = previousBootstrapState[stateKey] ?? [];
|
|
4277
|
+
let updatedData = newOrReplacementData.map((value) => {
|
|
4278
|
+
const existingObject = previousStateProperty?.find((item) => findUniqueObjectIds(item, value)) || {};
|
|
4279
|
+
return { ...existingObject, ...value };
|
|
4280
|
+
});
|
|
4281
|
+
const filterOutUpdated = (array) => {
|
|
4282
|
+
return array?.filter((item) => !updatedData.some((value) => findUniqueObjectIds(item, value))) ?? [];
|
|
4283
|
+
};
|
|
4284
|
+
let newState = {};
|
|
4285
|
+
switch (insertUpdateOrder) {
|
|
4286
|
+
case exports.eUpdateInsertMethod.LAST:
|
|
4287
|
+
newState[stateKey] = [
|
|
4288
|
+
...filterOutUpdated(previousStateProperty),
|
|
4289
|
+
...updatedData,
|
|
4290
|
+
];
|
|
4291
|
+
break;
|
|
4292
|
+
case exports.eUpdateInsertMethod.FIRST:
|
|
4293
|
+
newState[stateKey] = [
|
|
4294
|
+
...updatedData,
|
|
4295
|
+
...filterOutUpdated(previousStateProperty),
|
|
4296
|
+
];
|
|
4297
|
+
break;
|
|
4298
|
+
case exports.eUpdateInsertMethod.REPLACE:
|
|
4299
|
+
newState[stateKey] = [
|
|
4300
|
+
...(previousStateProperty?.map((oldObject) => {
|
|
4301
|
+
const index = updatedData.findIndex((item) => findUniqueObjectIds(item, oldObject));
|
|
4302
|
+
if (index !== -1) {
|
|
4303
|
+
return updatedData.splice(index, 1)[0];
|
|
4304
|
+
}
|
|
4305
|
+
return oldObject;
|
|
4306
|
+
}) ?? []),
|
|
4307
|
+
...updatedData,
|
|
4308
|
+
];
|
|
4309
|
+
break;
|
|
4310
|
+
default:
|
|
4311
|
+
throw new Error("The insertUpdateOrder (eUpdateInsertMethod) was not implemented");
|
|
4312
|
+
}
|
|
4313
|
+
return newState;
|
|
4314
|
+
}, callback);
|
|
4315
|
+
}
|
|
4316
|
+
|
|
4317
|
+
function deleteRestfulObjectArrays({ instance, dataOrCallback, stateKey, uniqueObjectId, callback }) {
|
|
4318
|
+
const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
|
|
4319
|
+
instance.setState((previousBootstrapState, props) => {
|
|
4320
|
+
let newOrReplacementData = [];
|
|
4321
|
+
if (Array.isArray(dataOrCallback)) {
|
|
4322
|
+
newOrReplacementData = dataOrCallback;
|
|
4323
|
+
}
|
|
4324
|
+
else if (typeof dataOrCallback === 'function') {
|
|
4325
|
+
const callbackReturn = dataOrCallback(previousBootstrapState, props);
|
|
4326
|
+
if (callbackReturn === null) {
|
|
4327
|
+
return null; // No updates needed (noop)
|
|
4328
|
+
}
|
|
4329
|
+
newOrReplacementData = callbackReturn;
|
|
4330
|
+
}
|
|
4331
|
+
else {
|
|
4332
|
+
throw new Error('The dataOrCallback parameter was not an array or function');
|
|
4333
|
+
}
|
|
4334
|
+
const previousStateProperty = previousBootstrapState[stateKey];
|
|
4335
|
+
const updatedStateProperty = previousStateProperty?.filter(item => !newOrReplacementData.some(value => uniqueObjectIds.every(uniqueId => value[uniqueId] === item[uniqueId]))) ?? [];
|
|
4336
|
+
return {
|
|
4337
|
+
[stateKey]: updatedStateProperty
|
|
4338
|
+
};
|
|
4339
|
+
}, callback);
|
|
4340
|
+
}
|
|
4341
|
+
|
|
4239
4342
|
const initialRequiredCarbonORMState = {
|
|
4240
4343
|
alertsWaiting: [],
|
|
4241
4344
|
backendThrowable: [],
|
|
@@ -4256,27 +4359,32 @@ function isJsonString(str) {
|
|
|
4256
4359
|
}
|
|
4257
4360
|
return true;
|
|
4258
4361
|
}
|
|
4259
|
-
// Create a context
|
|
4260
4362
|
const persistentStateMap = new Map();
|
|
4261
4363
|
class CarbonReact extends react.Component {
|
|
4262
4364
|
context = react.createContext(this.state);
|
|
4263
4365
|
// Private static member
|
|
4366
|
+
// we actually implement this in the constructor todo - test this
|
|
4264
4367
|
static instance;
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4368
|
+
target;
|
|
4369
|
+
updateRestfulObjectArrays = (rest) => updateRestfulObjectArrays({
|
|
4370
|
+
instance: this,
|
|
4371
|
+
...rest
|
|
4372
|
+
});
|
|
4373
|
+
deleteRestfulObjectArrays = (rest) => deleteRestfulObjectArrays({
|
|
4374
|
+
instance: this,
|
|
4375
|
+
...rest
|
|
4376
|
+
});
|
|
4272
4377
|
static lastLocation = window.location.pathname;
|
|
4273
4378
|
// @link https://github.com/welldone-software/why-did-you-render
|
|
4274
4379
|
// noinspection JSUnusedGlobalSymbols
|
|
4275
4380
|
static whyDidYouRender = true;
|
|
4276
4381
|
constructor(props) {
|
|
4277
4382
|
super(props);
|
|
4383
|
+
this.target = new.target;
|
|
4278
4384
|
console.log('CarbonORM TSX CONSTRUCTOR');
|
|
4279
|
-
|
|
4385
|
+
// this is the magic that allows each class that's extends this to have a static instance - a singleton pattern
|
|
4386
|
+
// new.target is a meta-property introduced in ES6 that references the constructor that was directly invoked with the new keyword.
|
|
4387
|
+
Object.assign(new.target, {
|
|
4280
4388
|
instance: this
|
|
4281
4389
|
});
|
|
4282
4390
|
if (this.props.instanceId && persistentStateMap.has(this.props.instanceId)) {
|
|
@@ -4321,11 +4429,11 @@ class CarbonReact extends react.Component {
|
|
|
4321
4429
|
console.log('%c color (' + colorHex + ')', 'color: ' + colorHex);
|
|
4322
4430
|
const nest = jsxRuntime_1(Nest, { position: 'fixed', backgroundColor: '', color: hexToRgb(colorHex), count: 100 });
|
|
4323
4431
|
if (this.state.backendThrowable.length > 0) {
|
|
4324
|
-
return jsxRuntime_2(jsxRuntime_3, { children: [nest, jsxRuntime_1(BackendThrowable, {})] });
|
|
4432
|
+
return jsxRuntime_2(jsxRuntime_3, { children: [nest, jsxRuntime_1(BackendThrowable, { instance: CarbonReact.instance })] });
|
|
4325
4433
|
}
|
|
4326
4434
|
const Context = this.context.Provider;
|
|
4327
4435
|
return jsxRuntime_2(jsxRuntime_3, { children: [jsxRuntime_1(GlobalHistory, {}), this.props.websocket &&
|
|
4328
|
-
jsxRuntime_1(CarbonWebSocket, { ...(true === this.props.websocket ? {} : this.props.websocket) }), jsxRuntime_1(Context, { value: this.state, children: this.props.children }), jsxRuntime_1(reactToastify.ToastContainer, {})] });
|
|
4436
|
+
jsxRuntime_1(CarbonWebSocket, { ...(true === this.props.websocket ? {} : this.props.websocket), instance: CarbonReact.instance }), jsxRuntime_1(Context, { value: this.state, children: this.props.children }), jsxRuntime_1(reactToastify.ToastContainer, {})] });
|
|
4329
4437
|
}
|
|
4330
4438
|
}
|
|
4331
4439
|
|
|
@@ -4384,44 +4492,6 @@ function addValidSQL$1 (sql) {
|
|
|
4384
4492
|
addValidSQL.push({ [expect.getState().currentTestName.replaceAll(" ", "_").toLowerCase()]: sql });
|
|
4385
4493
|
}
|
|
4386
4494
|
|
|
4387
|
-
//ObjectType, UniqueIdType extends keyof ObjectType
|
|
4388
|
-
// @link https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
|
|
4389
|
-
function deleteRestfulObjectArrays(dataOrCallback, stateKey, uniqueObjectId, callback) {
|
|
4390
|
-
const uniqueObjectIds = uniqueObjectId instanceof Array ? uniqueObjectId : [uniqueObjectId];
|
|
4391
|
-
return CarbonReact.instance.setState((previousBootstrapState, props) => {
|
|
4392
|
-
let newOrReplacementData = [];
|
|
4393
|
-
if (dataOrCallback instanceof Array) {
|
|
4394
|
-
newOrReplacementData = dataOrCallback;
|
|
4395
|
-
}
|
|
4396
|
-
else if (dataOrCallback instanceof Function) {
|
|
4397
|
-
let callbackReturn = dataOrCallback(previousBootstrapState, props);
|
|
4398
|
-
if (null === callbackReturn) {
|
|
4399
|
-
return;
|
|
4400
|
-
}
|
|
4401
|
-
newOrReplacementData = callbackReturn;
|
|
4402
|
-
}
|
|
4403
|
-
else {
|
|
4404
|
-
throw Error('The dataOrCallback parameter was not an array or function');
|
|
4405
|
-
}
|
|
4406
|
-
const previousStateProperty = previousBootstrapState[stateKey];
|
|
4407
|
-
return {
|
|
4408
|
-
[stateKey]: [
|
|
4409
|
-
...previousStateProperty?.filter(item => false === (newOrReplacementData?.find(value => {
|
|
4410
|
-
let isMatch = true;
|
|
4411
|
-
uniqueObjectIds.find(uniqueObjectId => {
|
|
4412
|
-
if (value[uniqueObjectId] !== item[uniqueObjectId]) {
|
|
4413
|
-
isMatch = false;
|
|
4414
|
-
return true;
|
|
4415
|
-
}
|
|
4416
|
-
return false;
|
|
4417
|
-
});
|
|
4418
|
-
return isMatch;
|
|
4419
|
-
}) || false)) || []
|
|
4420
|
-
]
|
|
4421
|
-
};
|
|
4422
|
-
}, callback);
|
|
4423
|
-
}
|
|
4424
|
-
|
|
4425
4495
|
// @link https://stackoverflow.com/questions/31721250/how-to-target-edge-browser-with-javascript
|
|
4426
4496
|
// Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) \
|
|
4427
4497
|
// Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.26
|
|
@@ -4561,89 +4631,6 @@ function setupTests ({ sqlDirectory = './logs/rest/', logsDirectory = './logs/te
|
|
|
4561
4631
|
}, 65000);
|
|
4562
4632
|
}
|
|
4563
4633
|
|
|
4564
|
-
exports.eUpdateInsertMethod = void 0;
|
|
4565
|
-
(function (eUpdateInsertMethod) {
|
|
4566
|
-
eUpdateInsertMethod[eUpdateInsertMethod["REPLACE"] = 0] = "REPLACE";
|
|
4567
|
-
eUpdateInsertMethod[eUpdateInsertMethod["FIRST"] = 1] = "FIRST";
|
|
4568
|
-
eUpdateInsertMethod[eUpdateInsertMethod["LAST"] = 2] = "LAST";
|
|
4569
|
-
})(exports.eUpdateInsertMethod || (exports.eUpdateInsertMethod = {}));
|
|
4570
|
-
/**
|
|
4571
|
-
*
|
|
4572
|
-
* merged with existing objects.uniqueObjectId || {}.
|
|
4573
|
-
* @param dataOrCallback
|
|
4574
|
-
* @param uniqueObjectId - the uniqueObjectId of the object to update; typically the primary key of the table.
|
|
4575
|
-
* @param stateKey -
|
|
4576
|
-
* @param insertUpdateOrder
|
|
4577
|
-
* @param callback - if you want to do something with the updated state, you can pass a callback here. Run as the second
|
|
4578
|
-
* parameter of setState.
|
|
4579
|
-
*/
|
|
4580
|
-
function updateRestfulObjectArrays(dataOrCallback, stateKey, uniqueObjectId, insertUpdateOrder = exports.eUpdateInsertMethod.LAST, callback) {
|
|
4581
|
-
const uniqueObjectIds = uniqueObjectId instanceof Array ? uniqueObjectId : [uniqueObjectId];
|
|
4582
|
-
const bootstrap = CarbonReact.instance;
|
|
4583
|
-
return bootstrap.setState((previousBootstrapState, props) => {
|
|
4584
|
-
let newOrReplacementData = [];
|
|
4585
|
-
if (dataOrCallback instanceof Array) {
|
|
4586
|
-
newOrReplacementData = dataOrCallback;
|
|
4587
|
-
}
|
|
4588
|
-
else if (dataOrCallback instanceof Function) {
|
|
4589
|
-
newOrReplacementData = dataOrCallback(previousBootstrapState, props);
|
|
4590
|
-
}
|
|
4591
|
-
else {
|
|
4592
|
-
throw Error('The dataOrCallback parameter was not an array or function');
|
|
4593
|
-
}
|
|
4594
|
-
const findUniqueObjectIds = (item, value) => {
|
|
4595
|
-
let isMatch = true;
|
|
4596
|
-
uniqueObjectIds.find(uniqueObjectId => {
|
|
4597
|
-
if (value[uniqueObjectId] !== item[uniqueObjectId]) {
|
|
4598
|
-
isMatch = false;
|
|
4599
|
-
return true;
|
|
4600
|
-
}
|
|
4601
|
-
return false;
|
|
4602
|
-
});
|
|
4603
|
-
return isMatch;
|
|
4604
|
-
};
|
|
4605
|
-
const previousStateProperty = previousBootstrapState[stateKey];
|
|
4606
|
-
let updatedData = newOrReplacementData?.map(value => {
|
|
4607
|
-
return {
|
|
4608
|
-
...previousStateProperty?.find(previousValue => findUniqueObjectIds(previousValue, value)) || {},
|
|
4609
|
-
...value
|
|
4610
|
-
};
|
|
4611
|
-
}) ?? [];
|
|
4612
|
-
switch (insertUpdateOrder) {
|
|
4613
|
-
default:
|
|
4614
|
-
throw Error('The insertUpdateOrder (eUpdateInsertMethod) was not implemented');
|
|
4615
|
-
case exports.eUpdateInsertMethod.LAST:
|
|
4616
|
-
return {
|
|
4617
|
-
[stateKey]: null === newOrReplacementData ? null : [
|
|
4618
|
-
...updatedData,
|
|
4619
|
-
...(previousStateProperty?.filter(item => false === (updatedData?.find(value => findUniqueObjectIds(item, value)) || false)) ?? [])
|
|
4620
|
-
]
|
|
4621
|
-
};
|
|
4622
|
-
case exports.eUpdateInsertMethod.FIRST:
|
|
4623
|
-
return {
|
|
4624
|
-
[stateKey]: null === newOrReplacementData ? null : [
|
|
4625
|
-
...(previousStateProperty?.filter(item => false === (updatedData?.find(value => findUniqueObjectIds(item, value)) || false)) ?? []),
|
|
4626
|
-
...updatedData,
|
|
4627
|
-
]
|
|
4628
|
-
};
|
|
4629
|
-
case exports.eUpdateInsertMethod.REPLACE: {
|
|
4630
|
-
return {
|
|
4631
|
-
[stateKey]: [
|
|
4632
|
-
...(previousStateProperty?.map(oldObject => {
|
|
4633
|
-
const index = updatedData.findIndex(item => findUniqueObjectIds(item, oldObject));
|
|
4634
|
-
if (-1 === index) {
|
|
4635
|
-
return oldObject;
|
|
4636
|
-
}
|
|
4637
|
-
return updatedData.splice(index, 1).pop();
|
|
4638
|
-
}) ?? []),
|
|
4639
|
-
...updatedData
|
|
4640
|
-
]
|
|
4641
|
-
};
|
|
4642
|
-
}
|
|
4643
|
-
}
|
|
4644
|
-
}, callback);
|
|
4645
|
-
}
|
|
4646
|
-
|
|
4647
4634
|
// @link https://stackoverflow.com/questions/6735414/php-data-uri-to-file
|
|
4648
4635
|
// @link https://www.tutorialspoint.com/convert-image-to-data-uri-with-javascript
|
|
4649
4636
|
async function toDataURL(src, fileType, callback) {
|