neo.mjs 8.7.1 → 8.9.0
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/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/grid/nestedRecordFields/EditUserDialog.mjs +154 -0
- package/examples/grid/nestedRecordFields/MainModel.mjs +54 -0
- package/examples/grid/nestedRecordFields/MainStore.mjs +54 -0
- package/examples/grid/nestedRecordFields/Viewport.mjs +152 -0
- package/examples/grid/nestedRecordFields/ViewportStateProvider.mjs +62 -0
- package/examples/grid/nestedRecordFields/app.mjs +6 -0
- package/examples/grid/nestedRecordFields/index.html +11 -0
- package/examples/grid/nestedRecordFields/neo-config.json +8 -0
- package/examples/table/nestedRecordFields/{MainContainer.mjs → Viewport.mjs} +50 -21
- package/examples/table/nestedRecordFields/{MainContainerStateProvider.mjs → ViewportStateProvider.mjs} +5 -5
- package/examples/table/nestedRecordFields/app.mjs +3 -3
- package/examples/table/nestedRecordFields/neo-config.json +2 -1
- package/package.json +1 -1
- package/resources/scss/src/grid/View.scss +16 -0
- package/resources/scss/src/grid/header/Button.scss +3 -1
- package/resources/scss/src/table/View.scss +2 -2
- package/resources/scss/src/table/header/Button.scss +1 -2
- package/resources/scss/theme-dark/grid/View.scss +2 -0
- package/resources/scss/theme-dark/table/View.scss +2 -0
- package/resources/scss/theme-light/grid/View.scss +2 -0
- package/resources/scss/theme-light/table/View.scss +2 -0
- package/resources/scss/theme-neo-light/grid/View.scss +2 -0
- package/resources/scss/theme-neo-light/table/View.scss +2 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/Neo.mjs +48 -19
- package/src/component/Base.mjs +16 -4
- package/src/container/Base.mjs +16 -0
- package/src/data/RecordFactory.mjs +41 -48
- package/src/grid/View.mjs +23 -5
- package/src/table/View.mjs +1 -1
@@ -5,16 +5,16 @@ import Store from '../../../src/data/Store.mjs';
|
|
5
5
|
const dataSymbol = Symbol.for('data');
|
6
6
|
|
7
7
|
/**
|
8
|
-
* @class Neo.examples.table.nestedRecordFields.
|
8
|
+
* @class Neo.examples.table.nestedRecordFields.ViewportStateProvider
|
9
9
|
* @extends Neo.state.Provider
|
10
10
|
*/
|
11
|
-
class
|
11
|
+
class ViewportStateProvider extends StateProvider {
|
12
12
|
static config = {
|
13
13
|
/**
|
14
|
-
* @member {String} className='Neo.examples.table.nestedRecordFields.
|
14
|
+
* @member {String} className='Neo.examples.table.nestedRecordFields.ViewportStateProvider'
|
15
15
|
* @protected
|
16
16
|
*/
|
17
|
-
className: 'Neo.examples.table.nestedRecordFields.
|
17
|
+
className: 'Neo.examples.table.nestedRecordFields.ViewportStateProvider',
|
18
18
|
/**
|
19
19
|
* @member {Object} stores
|
20
20
|
*/
|
@@ -59,4 +59,4 @@ class MainContainerStateProvider extends StateProvider {
|
|
59
59
|
}
|
60
60
|
}
|
61
61
|
|
62
|
-
export default Neo.setupClass(
|
62
|
+
export default Neo.setupClass(ViewportStateProvider);
|
package/package.json
CHANGED
@@ -22,6 +22,22 @@
|
|
22
22
|
height : 100%;
|
23
23
|
overflow-x: visible;
|
24
24
|
|
25
|
+
.neo-grid-cell {
|
26
|
+
&.neo-is-modified {
|
27
|
+
&:after {
|
28
|
+
border-color: transparent var(--grid-cell-ismodified-color) transparent transparent;
|
29
|
+
border-style: solid;
|
30
|
+
border-width: 0 var(--grid-cell-ismodified-size) var(--grid-cell-ismodified-size) 0;
|
31
|
+
content : '';
|
32
|
+
height : 0;
|
33
|
+
position : absolute;
|
34
|
+
right : 0;
|
35
|
+
top : 0;
|
36
|
+
width : 0;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
25
41
|
&.neo-is-scrolling * {
|
26
42
|
pointer-events: none !important;
|
27
43
|
}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
align-items : center;
|
3
3
|
background-color: var(--grid-header-button-background-color);
|
4
4
|
background-image: var(--grid-header-button-background-image);
|
5
|
+
border-radius : 0;
|
5
6
|
border-width : 0;
|
6
7
|
color : var(--grid-header-button-color);
|
7
8
|
cursor : pointer;
|
@@ -13,7 +14,6 @@
|
|
13
14
|
height : 29px; // Webkit => Safari can not handle 100%
|
14
15
|
justify-content : flex-end;
|
15
16
|
margin : 0;
|
16
|
-
padding : 7px 10px 6px;
|
17
17
|
white-space : nowrap;
|
18
18
|
|
19
19
|
&:not(:last-child) {
|
@@ -69,6 +69,8 @@
|
|
69
69
|
}
|
70
70
|
|
71
71
|
.neo-button-text {
|
72
|
+
color : var(--grid-header-button-color);
|
72
73
|
pointer-events: none;
|
74
|
+
text-transform: none;
|
73
75
|
}
|
74
76
|
}
|
@@ -13,9 +13,9 @@
|
|
13
13
|
|
14
14
|
&.neo-is-modified {
|
15
15
|
&:after {
|
16
|
-
border-color: transparent
|
16
|
+
border-color: transparent var(--table-cell-ismodified-color) transparent transparent;
|
17
17
|
border-style: solid;
|
18
|
-
border-width: 0
|
18
|
+
border-width: 0 var(--table-cell-ismodified-size) var(--table-cell-ismodified-size) 0;
|
19
19
|
content : '';
|
20
20
|
height : 0;
|
21
21
|
position : absolute;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
.neo-table-header-button {
|
2
2
|
align-items : center;
|
3
3
|
background-color: var(--table-header-button-background-color);
|
4
|
+
background-image: var(--table-header-button-background-image);
|
4
5
|
border-width : 0;
|
5
6
|
color : var(--table-header-button-color);
|
6
7
|
cursor : pointer;
|
@@ -15,8 +16,6 @@
|
|
15
16
|
white-space : nowrap;
|
16
17
|
width : 100% !important;
|
17
18
|
|
18
|
-
background-image: var(--table-header-button-background-image);
|
19
|
-
|
20
19
|
&.neo-drag-over {
|
21
20
|
background-image: linear-gradient(green, darkgreen);;
|
22
21
|
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
:root .neo-theme-dark { // .neo-grid-view
|
2
2
|
--grid-cell-background-color-hover : #54595c;
|
3
|
+
--grid-cell-ismodified-color : orange;
|
4
|
+
--grid-cell-ismodified-size : 10px;
|
3
5
|
--grid-cellmodel-selected-cell-background-color : #64B5F6;
|
4
6
|
--grid-cellmodel-selected-cell-color : #2b2b2b;
|
5
7
|
--grid-cellmodel-selected-column-cell-background-color: #4f558a;
|
@@ -1,5 +1,7 @@
|
|
1
1
|
:root .neo-theme-dark { // .neo-table-view
|
2
2
|
--table-cell-background-color-hover : #54595c;
|
3
|
+
--table-cell-ismodified-color : orange;
|
4
|
+
--table-cell-ismodified-size : 10px;
|
3
5
|
--table-cellmodel-selected-cell-background-color : #64B5F6;
|
4
6
|
--table-cellmodel-selected-cell-color : #2b2b2b;
|
5
7
|
--table-cellmodel-selected-column-cell-background-color: #4f558a;
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
:root .neo-theme-light { // .neo-grid-view
|
4
4
|
--grid-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
|
5
|
+
--grid-cell-ismodified-color : orange;
|
6
|
+
--grid-cell-ismodified-size : 10px;
|
5
7
|
--grid-cellmodel-selected-cell-background-color : #{color.adjust(#64B5F6, $lightness: 22%)};
|
6
8
|
--grid-cellmodel-selected-cell-color : #2b2b2b;
|
7
9
|
--grid-cellmodel-selected-column-cell-background-color: #{color.adjust(#4f558a, $lightness: 52%)};
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
:root .neo-theme-light { // .neo-table-view
|
4
4
|
--table-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
|
5
|
+
--table-cell-ismodified-color : orange;
|
6
|
+
--table-cell-ismodified-size : 10px;
|
5
7
|
--table-cellmodel-selected-cell-background-color : #{color.adjust(#64B5F6, $lightness: 22%)};
|
6
8
|
--table-cellmodel-selected-cell-color : #2b2b2b;
|
7
9
|
--table-cellmodel-selected-column-cell-background-color: #{color.adjust(#4f558a, $lightness: 52%)};
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
:root .neo-theme-neo-light { // .neo-grid-view
|
4
4
|
--grid-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
|
5
|
+
--grid-cell-ismodified-color : orange;
|
6
|
+
--grid-cell-ismodified-size : 10px;
|
5
7
|
--grid-cellmodel-selected-cell-background-color : #{color.adjust(#64B5F6, $lightness: 22%)};
|
6
8
|
--grid-cellmodel-selected-cell-color : #2b2b2b;
|
7
9
|
--grid-cellmodel-selected-column-cell-background-color: #{color.adjust(#4f558a, $lightness: 52%)};
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
:root .neo-theme-neo-light { // .neo-table-view
|
4
4
|
--table-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
|
5
|
+
--table-cell-ismodified-color : orange;
|
6
|
+
--table-cell-ismodified-size : 10px;
|
5
7
|
--table-cellmodel-selected-cell-background-color : #{color.adjust(#64B5F6, $lightness: 22%)};
|
6
8
|
--table-cellmodel-selected-cell-color : #2b2b2b;
|
7
9
|
--table-cellmodel-selected-column-cell-background-color: #{color.adjust(#4f558a, $lightness: 52%)};
|
package/src/DefaultConfig.mjs
CHANGED
@@ -262,12 +262,12 @@ const DefaultConfig = {
|
|
262
262
|
useVdomWorker: true,
|
263
263
|
/**
|
264
264
|
* buildScripts/injectPackageVersion.mjs will update this value
|
265
|
-
* @default '8.
|
265
|
+
* @default '8.9.0'
|
266
266
|
* @memberOf! module:Neo
|
267
267
|
* @name config.version
|
268
268
|
* @type String
|
269
269
|
*/
|
270
|
-
version: '8.
|
270
|
+
version: '8.9.0'
|
271
271
|
};
|
272
272
|
|
273
273
|
Object.assign(DefaultConfig, {
|
package/src/Neo.mjs
CHANGED
@@ -66,10 +66,10 @@ Neo = globalThis.Neo = Object.assign({
|
|
66
66
|
*
|
67
67
|
* // e.g. Neo.core.Util.isObject => Neo.isObject
|
68
68
|
* @memberOf module:Neo
|
69
|
-
* @param {Neo|Neo.core.Base} target
|
70
|
-
* @param {Neo.core.Base}
|
71
|
-
* @param {Object}
|
72
|
-
* @param {Boolean}
|
69
|
+
* @param {Neo|Neo.core.Base} target The target class or singleton Instance or Neo
|
70
|
+
* @param {Neo.core.Base} namespace The class containing the methods
|
71
|
+
* @param {Object} config
|
72
|
+
* @param {Boolean} [bind] set this to true in case you want to bind methods to the "from" namespace
|
73
73
|
* @returns {Object} target
|
74
74
|
*/
|
75
75
|
applyFromNs(target, namespace, config, bind) {
|
@@ -104,7 +104,7 @@ Neo = globalThis.Neo = Object.assign({
|
|
104
104
|
/**
|
105
105
|
* Copies all keys of defaults into target, in case they don't already exist
|
106
106
|
* @memberOf module:Neo
|
107
|
-
* @param {Object} target
|
107
|
+
* @param {Object} target The target object
|
108
108
|
* @param {Object} defaults The object containing the keys you want to copy
|
109
109
|
* @returns {Object} target
|
110
110
|
*/
|
@@ -120,6 +120,35 @@ Neo = globalThis.Neo = Object.assign({
|
|
120
120
|
return target
|
121
121
|
},
|
122
122
|
|
123
|
+
/**
|
124
|
+
* Assigns a new value to a given nested objects path.
|
125
|
+
* It will create the path structure or parts of it, in case it does not exist.
|
126
|
+
* @example
|
127
|
+
* Neo.assignToNs('annotations.selected', false, record)
|
128
|
+
*
|
129
|
+
* @memberOf module:Neo
|
130
|
+
* @param {String[]|String} path The path string containing dots or an Array of the string parts
|
131
|
+
* @param {*} value The new value to assign to the leaf node
|
132
|
+
* @param {Object} scope=globalThis Set a different starting point as globalThis
|
133
|
+
* @param {Boolean} force=true false will only assign default values (assign if old value === undefined)
|
134
|
+
*/
|
135
|
+
assignToNs(path, value, scope=globalThis, force=true) {
|
136
|
+
path = Array.isArray(path) ? path : path.split('.');
|
137
|
+
|
138
|
+
let key;
|
139
|
+
|
140
|
+
if (path.length > 1) {
|
141
|
+
key = path.pop();
|
142
|
+
scope = Neo.ns(path, true, scope)
|
143
|
+
} else {
|
144
|
+
key = path
|
145
|
+
}
|
146
|
+
|
147
|
+
if (force || scope[key] === undefined) {
|
148
|
+
scope[key] = value
|
149
|
+
}
|
150
|
+
},
|
151
|
+
|
123
152
|
/**
|
124
153
|
* Converts kebab-case strings into camel-case
|
125
154
|
* @memberOf module:Neo
|
@@ -143,7 +172,7 @@ Neo = globalThis.Neo = Object.assign({
|
|
143
172
|
/**
|
144
173
|
* @memberOf module:Neo
|
145
174
|
* @param {Object|Array|*} obj
|
146
|
-
* @param {Boolean} deep=false
|
175
|
+
* @param {Boolean} deep=false Set this to true in case you want to clone nested objects as well
|
147
176
|
* @param {Boolean} ignoreNeoInstances=false returns existing instances if set to true
|
148
177
|
* @returns {Object|Array|*} the cloned input
|
149
178
|
*/
|
@@ -214,7 +243,7 @@ Neo = globalThis.Neo = Object.assign({
|
|
214
243
|
* });
|
215
244
|
* @memberOf module:Neo
|
216
245
|
* @param {String|Object|Neo.core.Base} className
|
217
|
-
* @param {Object}
|
246
|
+
* @param {Object} [config]
|
218
247
|
* @returns {Neo.core.Base|null} The new class instance
|
219
248
|
* @tutorial 02_ClassSystem
|
220
249
|
*/
|
@@ -263,7 +292,7 @@ Neo = globalThis.Neo = Object.assign({
|
|
263
292
|
* Checks if there is a set method for a given property key inside the prototype chain
|
264
293
|
* @memberOf module:Neo
|
265
294
|
* @param {Neo.core.Base} proto The top level prototype of a class
|
266
|
-
* @param {String}
|
295
|
+
* @param {String} key The property key to test
|
267
296
|
* @returns {Boolean}
|
268
297
|
*/
|
269
298
|
hasPropertySetter(proto, key) {
|
@@ -319,9 +348,9 @@ Neo = globalThis.Neo = Object.assign({
|
|
319
348
|
* // return globalThis.Neo.button.Base;
|
320
349
|
*
|
321
350
|
* @memberOf module:Neo
|
322
|
-
* @param {
|
323
|
-
* @param {Boolean}
|
324
|
-
* @param {Object}
|
351
|
+
* @param {String[]|String} names The class name string containing dots or an Array of the string parts
|
352
|
+
* @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
|
353
|
+
* @param {Object} [scope] Set a different starting point as globalThis
|
325
354
|
* @returns {Object} reference to the toplevel namespace
|
326
355
|
*/
|
327
356
|
ns(names, create=false, scope) {
|
@@ -341,9 +370,9 @@ Neo = globalThis.Neo = Object.assign({
|
|
341
370
|
/**
|
342
371
|
* Extended version of Neo.ns() which supports mapping into arrays.
|
343
372
|
* @memberOf module:Neo
|
344
|
-
* @param {Array|String} names
|
345
|
-
* @param {Boolean}
|
346
|
-
* @param {Object}
|
373
|
+
* @param {Array|String} names The class name string containing dots or an Array of the string parts
|
374
|
+
* @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
|
375
|
+
* @param {Object} [scope] Set a different starting point as globalThis
|
347
376
|
* @returns {Object} reference to the toplevel namespace
|
348
377
|
*/
|
349
378
|
nsWithArrays(names, create=false, scope) {
|
@@ -383,7 +412,7 @@ Neo = globalThis.Neo = Object.assign({
|
|
383
412
|
* });
|
384
413
|
* @memberOf module:Neo
|
385
414
|
* @param {String|Object} ntype
|
386
|
-
* @param {Object}
|
415
|
+
* @param {Object} [config]
|
387
416
|
* @returns {Neo.core.Base}
|
388
417
|
* @see {@link module:Neo.create create}
|
389
418
|
*/
|
@@ -575,7 +604,7 @@ const ignoreMixin = [
|
|
575
604
|
|
576
605
|
/**
|
577
606
|
* @param {Neo.core.Base} cls
|
578
|
-
* @param {Array}
|
607
|
+
* @param {Array} mixins
|
579
608
|
* @private
|
580
609
|
*/
|
581
610
|
function applyMixins(cls, mixins) {
|
@@ -614,7 +643,7 @@ function applyMixins(cls, mixins) {
|
|
614
643
|
/**
|
615
644
|
* Creates get / set methods for class configs ending with an underscore
|
616
645
|
* @param {Neo.core.Base} proto
|
617
|
-
* @param {String}
|
646
|
+
* @param {String} key
|
618
647
|
* @private
|
619
648
|
* @tutorial 02_ClassSystem
|
620
649
|
*/
|
@@ -708,8 +737,8 @@ function autoGenerateGetSet(proto, key) {
|
|
708
737
|
|
709
738
|
/**
|
710
739
|
* @param {Boolean} create
|
711
|
-
* @param {Object}
|
712
|
-
* @param {Object}
|
740
|
+
* @param {Object} current
|
741
|
+
* @param {Object} prev
|
713
742
|
* @returns {Object|undefined}
|
714
743
|
*/
|
715
744
|
function createArrayNs(create, current, prev) {
|
package/src/component/Base.mjs
CHANGED
@@ -970,12 +970,24 @@ class Component extends Base {
|
|
970
970
|
*/
|
971
971
|
afterSetTheme(value, oldValue) {
|
972
972
|
if (value || oldValue !== undefined) {
|
973
|
-
let
|
973
|
+
let me = this,
|
974
|
+
{cls} = me,
|
975
|
+
needsUpdate = false;
|
974
976
|
|
975
|
-
|
976
|
-
|
977
|
+
if (oldValue && cls.includes(oldValue)) {
|
978
|
+
NeoArray.remove(cls, oldValue);
|
979
|
+
needsUpdate = true
|
980
|
+
}
|
977
981
|
|
978
|
-
|
982
|
+
// We do not need to add a DOM based CSS selector, in case the theme is already inherited
|
983
|
+
if (value !== me.parent?.theme) {
|
984
|
+
value && NeoArray.add(cls, value);
|
985
|
+
needsUpdate = true
|
986
|
+
}
|
987
|
+
|
988
|
+
if (needsUpdate) {
|
989
|
+
me.cls = cls
|
990
|
+
}
|
979
991
|
}
|
980
992
|
}
|
981
993
|
|
package/src/container/Base.mjs
CHANGED
@@ -216,6 +216,22 @@ class Container extends Component {
|
|
216
216
|
}
|
217
217
|
}
|
218
218
|
|
219
|
+
/**
|
220
|
+
* Triggered after the theme config got changed
|
221
|
+
* @param {String|null} value
|
222
|
+
* @param {String|null} oldValue
|
223
|
+
* @protected
|
224
|
+
*/
|
225
|
+
afterSetTheme(value, oldValue) {
|
226
|
+
super.afterSetTheme(value, oldValue);
|
227
|
+
|
228
|
+
value && this.items?.forEach(item => {
|
229
|
+
if (!Neo.isString(item)) {
|
230
|
+
item.theme = value
|
231
|
+
}
|
232
|
+
})
|
233
|
+
}
|
234
|
+
|
219
235
|
/**
|
220
236
|
* Triggered after the windowId config got changed
|
221
237
|
* @param {Number|null} value
|
@@ -4,6 +4,7 @@ import Model from './Model.mjs';
|
|
4
4
|
|
5
5
|
const
|
6
6
|
dataSymbol = Symbol.for('data'),
|
7
|
+
isModifiedSymbol = Symbol.for('isModified'),
|
7
8
|
originalDataSymbol = Symbol.for('originalData');
|
8
9
|
|
9
10
|
let instance;
|
@@ -34,27 +35,17 @@ class RecordFactory extends Base {
|
|
34
35
|
/**
|
35
36
|
* Assigns model based default values to a data object
|
36
37
|
* @param {Object} data
|
37
|
-
* @param {Record} record
|
38
38
|
* @param {Neo.data.Model} model
|
39
39
|
* @returns {Object}
|
40
40
|
*/
|
41
|
-
assignDefaultValues(data,
|
42
|
-
let {hasNestedFields} = model,
|
43
|
-
scope;
|
44
|
-
|
41
|
+
assignDefaultValues(data, model) {
|
45
42
|
model.fieldsMap.forEach((field, fieldName) => {
|
46
43
|
if (Object.hasOwn(field, 'defaultValue')) {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
} else {
|
53
|
-
scope = data
|
54
|
-
}
|
55
|
-
|
56
|
-
if (scope[fieldName] === undefined) {
|
57
|
-
scope[fieldName] = field.defaultValue
|
44
|
+
// We could always use Neo.assignToNs() => the check is just for improving the performance
|
45
|
+
if (model.hasNestedFields) {
|
46
|
+
Neo.assignToNs(fieldName, field.defaultValue, data, false)
|
47
|
+
} else if (data[fieldName] === undefined) {
|
48
|
+
data[fieldName] = field.defaultValue
|
58
49
|
}
|
59
50
|
}
|
60
51
|
});
|
@@ -65,18 +56,18 @@ class RecordFactory extends Base {
|
|
65
56
|
/**
|
66
57
|
* @param {Object} data
|
67
58
|
* @param {Object} data.field
|
68
|
-
* @param {Neo.data.RecordFactory} data.me
|
69
59
|
* @param {Neo.data.Model} data.model
|
70
60
|
* @param {String} data.path=''
|
61
|
+
* @param {Object} data.proto
|
71
62
|
*/
|
72
|
-
createField({field,
|
63
|
+
createField({field, model, path='', proto}) {
|
73
64
|
let fieldName = field.name,
|
74
65
|
fieldPath = path === '' ? fieldName : `${path}.${fieldName}`,
|
75
66
|
properties;
|
76
67
|
|
77
68
|
if (field.fields) {
|
78
69
|
field.fields.forEach(childField => {
|
79
|
-
this.createField({field: childField,
|
70
|
+
this.createField({field: childField, model, path: fieldPath, proto})
|
80
71
|
})
|
81
72
|
} else {
|
82
73
|
properties = {
|
@@ -99,7 +90,9 @@ class RecordFactory extends Base {
|
|
99
90
|
if (!Neo.isEqual(value, oldValue)) {
|
100
91
|
instance.setRecordData({fieldName: fieldPath, model, record: me, value});
|
101
92
|
|
102
|
-
|
93
|
+
if (!model.trackModifiedFields) {
|
94
|
+
me[isModifiedSymbol] = true
|
95
|
+
}
|
103
96
|
|
104
97
|
instance.onRecordChange({
|
105
98
|
fields: [{name: fieldPath, oldValue, value}],
|
@@ -111,7 +104,7 @@ class RecordFactory extends Base {
|
|
111
104
|
}
|
112
105
|
};
|
113
106
|
|
114
|
-
Object.defineProperties(
|
107
|
+
Object.defineProperties(proto, properties)
|
115
108
|
}
|
116
109
|
}
|
117
110
|
|
@@ -155,10 +148,10 @@ class RecordFactory extends Base {
|
|
155
148
|
let me = this;
|
156
149
|
|
157
150
|
if (model.trackModifiedFields) {
|
158
|
-
return Neo.isEqual(me[dataSymbol], me[originalDataSymbol])
|
151
|
+
return !Neo.isEqual(me[dataSymbol], me[originalDataSymbol])
|
159
152
|
}
|
160
153
|
|
161
|
-
return me
|
154
|
+
return me[isModifiedSymbol]
|
162
155
|
}
|
163
156
|
|
164
157
|
/**
|
@@ -167,7 +160,7 @@ class RecordFactory extends Base {
|
|
167
160
|
constructor(config) {
|
168
161
|
let me = this;
|
169
162
|
|
170
|
-
config = instance.assignDefaultValues(config,
|
163
|
+
config = instance.assignDefaultValues(config, model);
|
171
164
|
|
172
165
|
if (model.trackModifiedFields) {
|
173
166
|
me[originalDataSymbol] = {};
|
@@ -175,7 +168,7 @@ class RecordFactory extends Base {
|
|
175
168
|
}
|
176
169
|
|
177
170
|
me.setSilent(config); // We do not want to fire change events when constructing
|
178
|
-
me
|
171
|
+
me[isModifiedSymbol] = false
|
179
172
|
}
|
180
173
|
|
181
174
|
/**
|
@@ -186,7 +179,7 @@ class RecordFactory extends Base {
|
|
186
179
|
let me = this;
|
187
180
|
|
188
181
|
// Check if the field getter does exist
|
189
|
-
if (!me.__proto__
|
182
|
+
if (!Object.hasOwn(me.__proto__, fieldName)) {
|
190
183
|
Logger.logError('The record does not contain the field', fieldName, me)
|
191
184
|
}
|
192
185
|
|
@@ -210,6 +203,15 @@ class RecordFactory extends Base {
|
|
210
203
|
return null
|
211
204
|
}
|
212
205
|
|
206
|
+
/**
|
207
|
+
* Bulk-update multiple record fields at once
|
208
|
+
* @param {Object} fields
|
209
|
+
*/
|
210
|
+
reset(fields) {
|
211
|
+
this.setOriginal(fields);
|
212
|
+
this.set(fields)
|
213
|
+
}
|
214
|
+
|
213
215
|
/**
|
214
216
|
* Bulk-update multiple record fields at once
|
215
217
|
* @param {Object} fields
|
@@ -247,7 +249,7 @@ class RecordFactory extends Base {
|
|
247
249
|
|
248
250
|
if (Array.isArray(model.fields)) {
|
249
251
|
model.fields.forEach(field => {
|
250
|
-
instance.createField({field,
|
252
|
+
instance.createField({field, model, proto: cls.prototype})
|
251
253
|
})
|
252
254
|
}
|
253
255
|
|
@@ -261,23 +263,6 @@ class RecordFactory extends Base {
|
|
261
263
|
}
|
262
264
|
}
|
263
265
|
|
264
|
-
/**
|
265
|
-
* @param {Object} record
|
266
|
-
* @returns {Boolean} true in case a change was found
|
267
|
-
*/
|
268
|
-
isModified(record) {
|
269
|
-
return record.isModified
|
270
|
-
}
|
271
|
-
|
272
|
-
/**
|
273
|
-
* @param {Object} record
|
274
|
-
* @param {String} fieldName
|
275
|
-
* @returns {Boolean|null} null in case the model does not use trackModifiedFields, true in case a change was found
|
276
|
-
*/
|
277
|
-
isModifiedField(record, fieldName) {
|
278
|
-
return record.isModifiedField(fieldName)
|
279
|
-
}
|
280
|
-
|
281
266
|
/**
|
282
267
|
* Tests if a given object is an instance of a class created by this factory
|
283
268
|
* @param {Object} record
|
@@ -386,6 +371,10 @@ class RecordFactory extends Base {
|
|
386
371
|
* @protected
|
387
372
|
*/
|
388
373
|
setRecordData({fieldName, model, record, useOriginalData=false, value}) {
|
374
|
+
if (useOriginalData && !model.trackModifiedFields) {
|
375
|
+
return
|
376
|
+
}
|
377
|
+
|
389
378
|
let scope = useOriginalData ? originalDataSymbol : dataSymbol;
|
390
379
|
|
391
380
|
if (model.hasNestedFields && fieldName.includes('.')) {
|
@@ -411,9 +400,13 @@ class RecordFactory extends Base {
|
|
411
400
|
* @param {Boolean} data.useOriginalData=false true will apply changes to the originalData symbol
|
412
401
|
*/
|
413
402
|
setRecordFields({changedFields=[], fields, model, record, silent=false, useOriginalData=false}) {
|
414
|
-
let {fieldsMap} = model,
|
403
|
+
let {fieldsMap, trackModifiedFields} = model,
|
415
404
|
fieldExists, oldValue;
|
416
405
|
|
406
|
+
if (!trackModifiedFields && useOriginalData) {
|
407
|
+
return
|
408
|
+
}
|
409
|
+
|
417
410
|
Object.entries(fields).forEach(([key, value]) => {
|
418
411
|
fieldExists = fieldsMap.has(key);
|
419
412
|
|
@@ -435,8 +428,8 @@ class RecordFactory extends Base {
|
|
435
428
|
if (!Neo.isEqual(oldValue, value)) {
|
436
429
|
instance.setRecordData({fieldName: key, model, record, useOriginalData, value});
|
437
430
|
|
438
|
-
if (!useOriginalData) {
|
439
|
-
record
|
431
|
+
if (!trackModifiedFields && !useOriginalData) {
|
432
|
+
record[isModifiedSymbol] = true
|
440
433
|
}
|
441
434
|
|
442
435
|
changedFields.push({name: key, oldValue, value})
|
@@ -444,7 +437,7 @@ class RecordFactory extends Base {
|
|
444
437
|
}
|
445
438
|
});
|
446
439
|
|
447
|
-
if (!silent && Object.keys(changedFields).length > 0) {
|
440
|
+
if (!silent && !useOriginalData && Object.keys(changedFields).length > 0) {
|
448
441
|
Neo.get(model.storeId)?.onRecordChange({fields: changedFields, model, record})
|
449
442
|
}
|
450
443
|
}
|