@carbonorm/carbonreact 4.0.10 → 4.0.12
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/CarbonReact.d.ts +3 -0
- package/dist/index.cjs.js +19 -22
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +19 -22
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/CarbonReact.tsx +40 -57
- package/src/components/Alert/Alert.tsx +4 -6
package/package.json
CHANGED
package/src/CarbonReact.tsx
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {clearCache} from "@carbonorm/carbonnode";
|
|
1
|
+
import { clearCache } from "@carbonorm/carbonnode";
|
|
2
2
|
import changed from "hoc/changed";
|
|
3
|
-
import {GlobalHistory} from "hoc/GlobalHistory";
|
|
3
|
+
import { GlobalHistory } from "hoc/GlobalHistory";
|
|
4
4
|
import hexToRgb from "hoc/hexToRgb";
|
|
5
|
-
import {Component, Context, createContext, ReactElement, ReactNode} from 'react';
|
|
6
|
-
import {ToastContainer} from 'react-toastify';
|
|
5
|
+
import { Component, Context, createContext, ReactElement, ReactNode } from 'react';
|
|
6
|
+
import { ToastContainer } from 'react-toastify';
|
|
7
7
|
import 'react-toastify/dist/ReactToastify.min.css';
|
|
8
8
|
import BackendThrowable from 'components/Errors/BackendThrowable';
|
|
9
9
|
import Nest from 'components/Nest/Nest';
|
|
10
|
-
import {initialRestfulObjectsState, iRestfulObjectArrayTypes} from "variables/C6";
|
|
11
|
-
import CarbonWebSocket, {iCarbonWebSocketProps} from "./components/WebSocket/CarbonWebSocket";
|
|
12
|
-
import updateRestfulObjectArrays, {iUpdateRestfulObjectArrays} from "./hoc/updateRestfulObjectArrays";
|
|
13
|
-
import deleteRestfulObjectArrays, {iDeleteRestfulObjectArrays} from "./hoc/deleteRestfulObjectArrays";
|
|
10
|
+
import { initialRestfulObjectsState, iRestfulObjectArrayTypes } from "variables/C6";
|
|
11
|
+
import CarbonWebSocket, { iCarbonWebSocketProps } from "./components/WebSocket/CarbonWebSocket";
|
|
12
|
+
import updateRestfulObjectArrays, { iUpdateRestfulObjectArrays } from "./hoc/updateRestfulObjectArrays";
|
|
13
|
+
import deleteRestfulObjectArrays, { iDeleteRestfulObjectArrays } from "./hoc/deleteRestfulObjectArrays";
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
export type tStatefulApiData<T extends {
|
|
@@ -46,23 +46,20 @@ export function isJsonString(str: string) {
|
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
return true;
|
|
49
|
-
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactState> extends Component<{
|
|
53
52
|
children?: ReactNode | ReactNode[],
|
|
54
53
|
instanceId?: string,
|
|
55
|
-
websocket?: Omit<iCarbonWebSocketProps<P,S>, "instance"> | false
|
|
54
|
+
websocket?: Omit<iCarbonWebSocketProps<P, S>, "instance"> | false
|
|
56
55
|
} & P, S> {
|
|
57
56
|
|
|
58
57
|
private static persistentStateMap = new Map<string, { [key: string]: any; }>();
|
|
58
|
+
private static activeInstances = new Map<string, CarbonReact<any, any>>();
|
|
59
59
|
|
|
60
|
-
// Context is for functional components to access the state of this class efficiently
|
|
61
60
|
context: Context<S & iCarbonReactState> = createContext(this.state);
|
|
62
|
-
|
|
63
61
|
protected target: typeof CarbonReact;
|
|
64
62
|
|
|
65
|
-
// @link https://stackoverflow.com/questions/55029032/what-is-typescripts-thistype-used-for
|
|
66
63
|
protected static _instance: ThisType<CarbonReact<any, any>>;
|
|
67
64
|
|
|
68
65
|
static getInstance<T extends CarbonReact<any, any>>(): T {
|
|
@@ -75,7 +72,6 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
|
|
|
75
72
|
this._instance = instance;
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
// these are public but the class is abstract
|
|
79
75
|
public updateRestfulObjectArrays = <ObjectType extends { [key: string]: any; } = {}>
|
|
80
76
|
(rest: Omit<iUpdateRestfulObjectArrays<ObjectType, S, P>, "instance">) => updateRestfulObjectArrays<ObjectType, S, P>({
|
|
81
77
|
instance: this,
|
|
@@ -90,70 +86,57 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
|
|
|
90
86
|
|
|
91
87
|
static lastLocation = window.location.pathname;
|
|
92
88
|
|
|
93
|
-
// @link https://github.com/welldone-software/why-did-you-render
|
|
94
|
-
// noinspection JSUnusedGlobalSymbols
|
|
95
89
|
static whyDidYouRender = true;
|
|
96
90
|
|
|
97
|
-
|
|
98
91
|
protected constructor(props: {
|
|
99
92
|
children?: ReactNode | ReactNode[];
|
|
100
93
|
shouldStatePersist?: boolean | undefined;
|
|
101
|
-
websocket?: boolean | iCarbonWebSocketProps<P,S> | undefined;
|
|
94
|
+
websocket?: boolean | iCarbonWebSocketProps<P, S> | undefined;
|
|
95
|
+
instanceId?: string; // Optional instanceId from props
|
|
102
96
|
} & P) {
|
|
103
|
-
|
|
104
97
|
super(props);
|
|
105
98
|
|
|
106
|
-
|
|
99
|
+
const target = new.target as typeof CarbonReact;
|
|
100
|
+
const identifier = props.instanceId || target.name;
|
|
107
101
|
|
|
108
|
-
|
|
102
|
+
if (CarbonReact.activeInstances.has(identifier)) {
|
|
103
|
+
throw new Error(`Instance with ID ${identifier} already exists! CarbonReact extended classes can only be referenced once in DOM with the same identifier.`);
|
|
104
|
+
}
|
|
109
105
|
|
|
110
|
-
|
|
111
|
-
// new.target is a meta-property introduced in ES6 that references the constructor that was directly invoked with the new keyword.
|
|
112
|
-
Object.assign(new.target, {
|
|
113
|
-
_instance: this
|
|
114
|
-
})
|
|
106
|
+
CarbonReact.activeInstances.set(identifier, this);
|
|
115
107
|
|
|
116
|
-
|
|
108
|
+
this.target = target;
|
|
109
|
+
console.log('CarbonORM TSX CONSTRUCTOR');
|
|
117
110
|
|
|
118
|
-
|
|
111
|
+
Object.assign(target, {
|
|
112
|
+
_instance: this
|
|
113
|
+
});
|
|
119
114
|
|
|
115
|
+
if (CarbonReact.persistentStateMap.has(identifier)) {
|
|
116
|
+
this.state = CarbonReact.persistentStateMap.get(identifier) as S & iCarbonReactState;
|
|
120
117
|
} else {
|
|
121
|
-
|
|
122
|
-
// This should only ever be done here, when the full state is being trashed.
|
|
123
|
-
// todo - does this suck in context of multiple instances?
|
|
124
118
|
clearCache({
|
|
125
119
|
ignoreWarning: true
|
|
126
120
|
});
|
|
127
|
-
|
|
128
121
|
this.state = initialCarbonReactState as unknown as S & iCarbonReactState;
|
|
129
|
-
|
|
130
122
|
}
|
|
131
123
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
* Class based components are far easier to manage state in local storage and pass state down to children.
|
|
135
|
-
* Children, if not faced with a local storage or other complexity should be a functional component. Functional
|
|
136
|
-
* components' tend to be shorter syntactically and bonus points if it's stateless.
|
|
137
|
-
**/
|
|
138
|
-
|
|
124
|
+
// Save the initial state to the persistent state map with the identifier
|
|
125
|
+
CarbonReact.persistentStateMap.set(identifier, this.state);
|
|
139
126
|
}
|
|
140
127
|
|
|
141
|
-
|
|
142
128
|
shouldComponentUpdate(
|
|
143
129
|
nextProps: Readonly<P>,
|
|
144
130
|
nextState: Readonly<S>,
|
|
145
131
|
_nextContext: any): boolean {
|
|
146
132
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
133
|
+
const identifier = this.props.instanceId || (this.constructor as typeof CarbonReact).name;
|
|
134
|
+
CarbonReact.persistentStateMap.set(identifier, nextState);
|
|
150
135
|
|
|
151
136
|
changed(this.constructor.name + ' (C6Api)', 'props', this.props, nextProps);
|
|
152
|
-
|
|
153
137
|
changed(this.constructor.name + ' (C6Api)', 'state', this.state, nextState);
|
|
154
138
|
|
|
155
|
-
return true
|
|
156
|
-
|
|
139
|
+
return true;
|
|
157
140
|
}
|
|
158
141
|
|
|
159
142
|
componentDidUpdate(_prevProps: Readonly<P>, _prevState: Readonly<S>, _snapshot?: any) {
|
|
@@ -168,39 +151,39 @@ abstract class CarbonReact<P = {}, S extends iCarbonReactState = iCarbonReactSta
|
|
|
168
151
|
}
|
|
169
152
|
|
|
170
153
|
render(): ReactElement {
|
|
171
|
-
|
|
172
154
|
console.log('CarbonORM TSX RENDER');
|
|
173
155
|
|
|
174
156
|
const colorHex = '#' + Math.random().toString(16).slice(-6);
|
|
175
157
|
|
|
176
158
|
console.log('%c color (' + colorHex + ')', 'color: ' + colorHex);
|
|
177
159
|
|
|
178
|
-
const nest = <Nest position={'fixed'} backgroundColor={''} color={hexToRgb(colorHex)} count={100}/>;
|
|
160
|
+
const nest = <Nest position={'fixed'} backgroundColor={''} color={hexToRgb(colorHex)} count={100} />;
|
|
179
161
|
|
|
180
162
|
if (this.state.backendThrowable.length > 0) {
|
|
181
|
-
|
|
182
163
|
return <>
|
|
183
164
|
{nest}
|
|
184
|
-
<BackendThrowable instance={this}/>
|
|
165
|
+
<BackendThrowable instance={this} />
|
|
185
166
|
</>;
|
|
186
|
-
|
|
187
167
|
}
|
|
188
168
|
|
|
189
169
|
const Context = this.context.Provider;
|
|
190
170
|
|
|
191
171
|
return <>
|
|
192
|
-
<GlobalHistory/>
|
|
172
|
+
<GlobalHistory />
|
|
193
173
|
{this.props.websocket &&
|
|
194
|
-
<CarbonWebSocket<P,S> {...(false !== this.props.websocket ? this.props.websocket : {})}
|
|
195
|
-
|
|
174
|
+
<CarbonWebSocket<P, S> {...(false !== this.props.websocket ? this.props.websocket : {})}
|
|
175
|
+
instance={this} />}
|
|
196
176
|
<Context value={this.state}>
|
|
197
177
|
{this.props.children}
|
|
198
178
|
</Context>
|
|
199
|
-
<ToastContainer/>
|
|
179
|
+
<ToastContainer />
|
|
200
180
|
</>;
|
|
201
|
-
|
|
202
181
|
}
|
|
203
182
|
|
|
183
|
+
componentWillUnmount() {
|
|
184
|
+
const identifier = this.props.instanceId || (this.constructor as typeof CarbonReact).name;
|
|
185
|
+
CarbonReact.activeInstances.delete(identifier);
|
|
186
|
+
}
|
|
204
187
|
}
|
|
205
188
|
|
|
206
189
|
export default CarbonReact;
|
|
@@ -18,10 +18,10 @@ export interface iAlertButtonOptions {
|
|
|
18
18
|
color: "default" | "primary" | "secondary" | "inherit" | "danger" | "info" | "success" | "warning" | undefined,
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export interface iAlert<P,S extends iCarbonReactState> {
|
|
21
|
+
export interface iAlert<P, S extends iCarbonReactState> {
|
|
22
22
|
title: string,
|
|
23
23
|
text: string,
|
|
24
|
-
instance: CarbonReact<P,S>,
|
|
24
|
+
instance: CarbonReact<P, S>,
|
|
25
25
|
component?: ReactNode,
|
|
26
26
|
icon?: "warning" | "error" | "success" | "info" | "question" | null,
|
|
27
27
|
buttons?: (iAlertButtonOptions)[] | undefined, //['No thanks!', 'Yes, Delete it'],
|
|
@@ -41,13 +41,11 @@ export function addAlert<P, S extends iCarbonReactState>(props: iAlert<P, S>) {
|
|
|
41
41
|
}));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export default function Alert<P,S extends iCarbonReactState>({
|
|
45
|
-
instance
|
|
46
|
-
}: { instance: CarbonReact<P,S> }) {
|
|
44
|
+
export default function Alert<P, S extends iCarbonReactState>({instance}: { instance: CarbonReact<P, S> }) {
|
|
47
45
|
|
|
48
46
|
const {alertsWaiting, backendThrowable} = instance.state
|
|
49
47
|
|
|
50
|
-
let alert: iAlert<P,S> | undefined = undefined;
|
|
48
|
+
let alert: iAlert<P, S> | undefined = undefined;
|
|
51
49
|
|
|
52
50
|
const alertWaiting = alertsWaiting.length + backendThrowable.length
|
|
53
51
|
|