sdc_client 0.57.14 → 0.57.16

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.
@@ -7,788 +7,816 @@ const MAX_FILE_UPLOAD = 25000;
7
7
 
8
8
  class SubModel {
9
9
 
10
- constructor(pk, model) {
11
- this.pk = pk;
12
- this._model = model;
13
- }
14
-
15
- /**
16
- * SDC Model Name
17
- * @param {string} model
18
- */
19
- set model(model) {
20
- this._model = model;
21
- }
22
-
23
- get model() {
24
- return this._model;
25
- }
26
-
27
- /**
28
- * Load the sub model.
29
- *
30
- * @param {AbstractSDC} controller
31
- * @returns {Model}
32
- */
33
- load(controller) {
34
- if (!this._model) {
35
- throw new TypeError("Model is not set!!");
36
- }
37
- return controller.newModel(this._model, {pk: this.pk});
38
- }
10
+ constructor(pk, model) {
11
+ this.pk = pk;
12
+ this._model = model;
13
+ }
14
+
15
+ /**
16
+ * SDC Model Name
17
+ * @param {string} model
18
+ */
19
+ set model(model) {
20
+ this._model = model;
21
+ }
22
+
23
+ get model() {
24
+ return this._model;
25
+ }
26
+
27
+ /**
28
+ * Load the sub model.
29
+ *
30
+ * @param {AbstractSDC} controller
31
+ * @returns {Model}
32
+ */
33
+ load(controller) {
34
+ if (!this._model) {
35
+ throw new TypeError("Model is not set!!");
36
+ }
37
+ if (this.pk instanceof Array) {
38
+ return controller.newModel(this._model, {pk__in: this.pk});
39
+ }
40
+ return controller.newModel(this._model, {pk: this.pk});
41
+ }
39
42
  }
40
43
 
41
44
  const ModelProxyHandler = {
42
- get(target, key) {
43
- const value = target[key] ?? undefined;
44
- if (value instanceof SubModel) {
45
- if (!value.pk && value.pk !== 0) {
46
- return null
47
- }
48
- const newVal = new Number(value.pk);
49
- newVal.load = value.load.bind(value);
50
- return newVal;
51
- }
52
- return value;
53
- },
54
- set(target, key, value) {
55
- if (key in target) {
56
- const oldVal = target[key];
57
- if (oldVal instanceof SubModel) {
58
- if (value.hasOwnProperty('pk')) {
59
- oldVal.pk = value.pk;
60
- } else {
61
- oldVal.pk = value;
62
- }
63
- } else {
64
- target[key] = value;
65
- }
45
+ get(target, key) {
46
+ const value = target[key] ?? undefined;
47
+ if (value instanceof SubModel) {
48
+ if (!value.pk && value.pk !== 0) {
49
+ return null
50
+ }
51
+ let newVal;
52
+ if (value.pk instanceof Array) {
53
+ newVal = value.pk.slice();
54
+ } else {
55
+ newVal = new Number(value.pk);
56
+ }
57
+ newVal.load = value.load.bind(value);
58
+ return newVal;
59
+ }
60
+ return value;
61
+ },
62
+ set(target, key, value) {
63
+ if (key in target) {
64
+ const oldVal = target[key];
65
+ if (oldVal instanceof SubModel) {
66
+ if (value.hasOwnProperty('pk')) {
67
+ oldVal.pk = value.pk;
66
68
  } else {
67
- target[key] = value;
69
+ try {
70
+ oldVal.pk = JSON.parse(value);
71
+ } catch {
72
+ oldVal.pk = value;
73
+ }
74
+
68
75
  }
69
- return true;
70
- }
76
+ } else {
77
+ target[key] = value;
78
+ }
79
+ } else {
80
+ target[key] = value;
81
+ }
82
+ return true;
83
+ }
71
84
  }
72
85
 
73
86
 
74
87
  function parse_hidden_inputs(value) {
75
88
 
76
- let isFloatReg = /^-?\d+\.?\d+$/;
77
- let isIntReg = /^-?\d+$/;
78
- let isBoolReg = /^(true|false)$/;
79
- let isStringReg = /^(['][^']*['])|(["][^"]*["])$/;
80
-
81
-
82
- if (value.toLowerCase().match(isBoolReg)) {
83
- return value.toLowerCase() === 'true';
84
- } else if (value === 'undefined') {
85
- return undefined;
86
- } else if (value.toLowerCase() === 'none') {
87
- return null;
88
- } else if (value.match(isIntReg)) {
89
- return parseInt(value);
90
- } else if (value.match(isFloatReg)) {
91
- return parseFloat(value);
92
- } else if (value.match(isStringReg)) {
93
- return value.substring(1, value.length - 1);
94
- }
95
- return value;
89
+ let isFloatReg = /^-?\d+\.?\d+$/;
90
+ let isIntReg = /^-?\d+$/;
91
+ let isBoolReg = /^(true|false)$/;
92
+ let isStringReg = /^(['][^']*['])|(["][^"]*["])$/;
93
+
94
+
95
+ if (value.toLowerCase().match(isBoolReg)) {
96
+ return value.toLowerCase() === 'true';
97
+ } else if (value === 'undefined') {
98
+ return undefined;
99
+ } else if (value.toLowerCase() === 'none') {
100
+ return null;
101
+ } else if (value.match(isIntReg)) {
102
+ return parseInt(value);
103
+ } else if (value.match(isFloatReg)) {
104
+ return parseFloat(value);
105
+ } else if (value.match(isStringReg)) {
106
+ return value.substring(1, value.length - 1);
107
+ }
108
+ return value;
96
109
  }
97
110
 
98
111
 
99
112
  export class Model {
100
- /**
101
- *
102
- * @param model_name {string}
103
- * @param model_query {json}
104
- */
105
- constructor(model_name, model_query = {}) {
106
- this._onNoOpenRequests = [];
107
- this.values_list = [];
108
- this.values = {};
109
- this.model_name = model_name;
110
- this.model_query = model_query;
111
- this._is_connected = false;
112
- this._is_conneting_process = false;
113
- this._auto_reconnect = true;
114
- this.socket = null;
115
- this.open_request = {};
116
- this.on_update = () => {
117
- };
118
- this.on_create = () => {
119
- };
120
-
121
- this.form_id = uuidv4();
122
- }
123
-
124
- [Symbol.iterator]() {
125
- let idx = -1;
126
- return {
127
- next: () => {
128
- ++idx;
129
- if (idx < this.values_list.length) {
130
- return {value: this.values_list[idx], done: false};
131
- }
132
- return {value: null, done: true};
133
- }
134
- };
135
- }
136
-
137
- length() {
138
- return this.values_list.length;
139
- }
140
-
141
- byPk(pk) {
142
- if (pk !== null) {
143
- pk = parseInt(pk);
144
- if (isNaN(pk)) {
145
- pk = -1;
146
- }
147
- let elem = this.values_list.find(elm => elm.pk === pk);
148
- if (!elem) {
149
- elem = new Proxy({pk: pk}, ModelProxyHandler);
150
- this.values_list.push(elem);
151
- }
152
- return elem;
153
- }
154
- return {pk: pk};
155
-
156
- }
157
-
158
- filter(model_query) {
159
- this.model_query = Object.assign({}, this.model_query, model_query);
160
- return this;
161
- }
162
-
163
- load() {
164
- return this.isConnected().then(() => {
165
- const id = uuidv4();
166
- return new Promise((resolve, reject) => {
167
- this.socket.send(JSON.stringify({
168
- event: 'model',
169
- event_type: 'load',
170
- event_id: id,
171
- args: {
172
- model_name: this.model_name,
173
- model_query: this.model_query
174
- }
175
- }));
176
-
177
- this.open_request[id] = [resolve, reject];
178
- });
179
- });
180
- }
181
-
182
- listView(filter = {}, cb_resolve = null, cb_reject = null, template_context = {}) {
183
- let $div_list = $('<div class="container-fluid">');
184
- this.isConnected().then(() => {
185
- const id = uuidv4();
186
- this.socket.send(JSON.stringify({
187
- event: 'model',
188
- event_type: 'list_view',
189
- event_id: id,
190
- args: {
191
- model_name: this.model_name,
192
- model_query: this.model_query,
193
- filter,
194
- template_context
195
- }
196
- }));
197
-
198
- this.open_request[id] = [(data) => {
199
- $div_list.append(data.html);
200
- app.refresh($div_list);
201
- cb_resolve && cb_resolve(data);
202
- }, (res) => {
203
- cb_reject && cb_reject(res);
204
- }];
205
-
206
- });
207
-
208
- return $div_list;
209
- }
210
-
211
- detailView(pk = null, cb_resolve = null, cb_reject = null, template_context = {}) {
212
- pk = pk ?? -1;
213
- pk = parseInt(pk);
214
- if (isNaN(pk)) {
215
- pk = -1;
113
+ /**
114
+ *
115
+ * @param model_name {string}
116
+ * @param model_query {json}
117
+ */
118
+ constructor(model_name, model_query = {}) {
119
+ this._onNoOpenRequests = [];
120
+ this.values_list = [];
121
+ this.values = {};
122
+ this.model_name = model_name;
123
+ this.model_query = model_query;
124
+ this._is_connected = false;
125
+ this._is_conneting_process = false;
126
+ this._auto_reconnect = true;
127
+ this.socket = null;
128
+ this.open_request = {};
129
+ this.on_update = () => {
130
+ };
131
+ this.on_create = () => {
132
+ };
133
+
134
+ this.form_id = uuidv4();
135
+ }
136
+
137
+ [Symbol.iterator]() {
138
+ let idx = -1;
139
+ return {
140
+ next: () => {
141
+ ++idx;
142
+ if (idx < this.values_list.length) {
143
+ return {value: this.values_list[idx], done: false};
216
144
  }
217
- let $div_list = $('<div class="container-fluid">');
218
-
219
- let load_promise;
220
- if (this.values_list.length !== 0) {
221
- load_promise = this.isConnected();
222
- } else {
223
- load_promise = this.load();
224
- }
225
-
226
- load_promise.then(() => {
227
- if (pk === -1) {
228
- pk = this.values_list[0].pk
229
- }
230
- const id = uuidv4();
231
- this.socket.send(JSON.stringify({
232
- event: 'model',
233
- event_type: 'detail_view',
234
- event_id: id,
235
- args: {
236
- model_name: this.model_name,
237
- model_query: this.model_query,
238
- pk,
239
- template_context
240
- }
241
- }));
242
-
243
- this.open_request[id] = [(data) => {
244
- $div_list.append(data.html);
245
- app.refresh($div_list);
246
- cb_resolve && cb_resolve(data);
247
- }, (res) => {
248
- cb_reject && cb_reject(res);
249
- }];
250
-
251
- });
252
-
253
- return $div_list;
254
- }
255
-
256
- syncFormToModel($forms) {
257
- return this.syncForm($forms);
258
- }
259
-
260
- syncModelToForm($forms) {
261
- if (!$forms || !$forms.hasClass(this.form_id)) {
262
- $forms = $(`.${this.form_id}`);
263
- }
264
-
265
- let self = this;
266
- $forms.each(function () {
267
- if (!this.hasAttribute('data-model_pk')) {
268
- return;
269
- }
270
- let pk = $(this).data('model_pk');
271
- let instance = self.byPk(pk);
272
- for (let form_item of this.elements) {
273
- let name = form_item.name;
274
- if (name && name !== '') {
275
- if (form_item.type === 'checkbox') {
276
- form_item.checked = instance[name];
277
- } else if (form_item.type === 'file' && instance[name] instanceof File) {
278
- let container = new DataTransfer();
279
- container.items.add(instance[name]);
280
- form_item.files = container;
281
- } else {
282
- $(form_item).val(instance[name]);
283
- }
284
- }
285
- }
286
- });
287
-
288
- }
145
+ return {value: null, done: true};
146
+ }
147
+ };
148
+ }
149
+
150
+ length() {
151
+ return this.values_list.length;
152
+ }
153
+
154
+ byPk(pk) {
155
+ if (pk !== null) {
156
+ pk = parseInt(pk);
157
+ if (isNaN(pk)) {
158
+ pk = -1;
159
+ }
160
+ let elem = this.values_list.find(elm => elm.pk === pk);
161
+ if (!elem) {
162
+ elem = new Proxy({pk: pk}, ModelProxyHandler);
163
+ this.values_list.push(elem);
164
+ }
165
+ return elem;
166
+ }
167
+ return {pk: pk};
168
+
169
+ }
170
+
171
+ filter(model_query) {
172
+ this.model_query = Object.assign({}, this.model_query, model_query);
173
+ return this;
174
+ }
175
+
176
+ load() {
177
+ return this.isConnected().then(() => {
178
+ const id = uuidv4();
179
+ return new Promise((resolve, reject) => {
180
+ this.socket.send(JSON.stringify({
181
+ event: 'model',
182
+ event_type: 'load',
183
+ event_id: id,
184
+ args: {
185
+ model_name: this.model_name,
186
+ model_query: this.model_query
187
+ }
188
+ }));
289
189
 
290
- syncForm($forms) {
291
- if (!$forms || !$forms.hasClass(this.form_id)) {
292
- $forms = $(`.${this.form_id}`);
190
+ this.open_request[id] = [resolve, reject];
191
+ });
192
+ });
193
+ }
194
+
195
+ listView(filter = {}, cbResolve = null, cbReject = null, templateContext = {}) {
196
+ return this.view({filter, cbResolve, cbReject, templateContext})
197
+ }
198
+
199
+ view({viewName = 'html_list_template', filter = {}, cbResolve = null, cbReject = null, templateContext = {}}) {
200
+ let $div_list = $('<div class="container-fluid">');
201
+ this.isConnected().then(() => {
202
+ const id = uuidv4();
203
+ this.socket.send(JSON.stringify({
204
+ event: 'model',
205
+ event_type: 'named_view',
206
+ event_id: id,
207
+ args: {
208
+ view_name: viewName,
209
+ model_name: this.model_name,
210
+ model_query: this.model_query,
211
+ filter,
212
+ template_context: templateContext
293
213
  }
294
-
295
- const self = this;
296
- let instances = [];
297
-
298
- $forms.each(function () {
299
- let $form = $(this);
300
- let pk = $form.data('model_pk');
301
- let instance = self.byPk(pk);
302
- for (let form_item of this.elements) {
303
- let name = form_item.name;
304
- if (name && name !== '') {
305
- if (form_item.type === 'hidden') {
306
- instance[name] = parse_hidden_inputs($(form_item).val());
307
- } else if (form_item.type === 'checkbox') {
308
- instance[name] = form_item.checked;
309
- } else if (form_item.type === 'file') {
310
- instance[name] = form_item.files[0];
311
- } else {
312
- instance[name] = $(form_item).val();
313
- }
314
- }
315
- }
316
-
317
- instances.push(instance);
318
- return instance;
319
- });
320
-
321
- if (this.values_list.length <= 1 && instances.length > 0) {
322
- this.values = instances.at(-1);
214
+ }));
215
+
216
+ this.open_request[id] = [(data) => {
217
+ $div_list.append(data.html);
218
+ app.refresh($div_list);
219
+ cbResolve && cbResolve(data);
220
+ }, (res) => {
221
+ cbReject && cbReject(res);
222
+ }];
223
+
224
+ });
225
+
226
+ return $div_list;
227
+ }
228
+
229
+ detailView(pk = null, cb_resolve = null, cb_reject = null, template_context = {}) {
230
+ pk = pk ?? -1;
231
+ pk = parseInt(pk);
232
+ if (isNaN(pk)) {
233
+ pk = -1;
234
+ }
235
+ let $div_list = $('<div class="container-fluid">');
236
+
237
+ let load_promise;
238
+ if (this.values_list.length !== 0) {
239
+ load_promise = this.isConnected();
240
+ } else {
241
+ load_promise = this.load();
242
+ }
243
+
244
+ load_promise.then(() => {
245
+ if (pk === -1) {
246
+ pk = this.values_list[0].pk
247
+ }
248
+ const id = uuidv4();
249
+ this.socket.send(JSON.stringify({
250
+ event: 'model',
251
+ event_type: 'detail_view',
252
+ event_id: id,
253
+ args: {
254
+ model_name: this.model_name,
255
+ model_query: this.model_query,
256
+ pk,
257
+ template_context
323
258
  }
324
-
325
- return instances;
326
-
327
- }
328
-
329
- createForm(cb_resolve = null, cb_reject = null) {
330
- let $div_form = $('<div class="container-fluid">');
331
- this.isConnected().then(() => {
332
- this._getForm(null, 'create_form', null, $div_form, cb_resolve, cb_reject);
333
- });
334
-
335
- return $div_form;
336
- }
337
-
338
- editForm(pk = -1, cb_resolve = null, cb_reject = null) {
339
- pk = parseInt(pk);
340
- if (isNaN(pk)) {
341
- pk = -1;
259
+ }));
260
+
261
+ this.open_request[id] = [(data) => {
262
+ $div_list.append(data.html);
263
+ app.refresh($div_list);
264
+ cb_resolve && cb_resolve(data);
265
+ }, (res) => {
266
+ cb_reject && cb_reject(res);
267
+ }];
268
+
269
+ });
270
+
271
+ return $div_list;
272
+ }
273
+
274
+ syncFormToModel($forms) {
275
+ return this.syncForm($forms);
276
+ }
277
+
278
+ syncModelToForm($forms) {
279
+ if (!$forms || !$forms.hasClass(this.form_id)) {
280
+ $forms = $(`.${this.form_id}`);
281
+ }
282
+
283
+ let self = this;
284
+ $forms.each(function () {
285
+ if (!this.hasAttribute('data-model_pk')) {
286
+ return;
287
+ }
288
+ let pk = $(this).data('model_pk');
289
+ let instance = self.byPk(pk);
290
+ for (let form_item of this.elements) {
291
+ let name = form_item.name;
292
+ if (name && name !== '') {
293
+ if (form_item.type === 'checkbox') {
294
+ form_item.checked = instance[name];
295
+ } else if (form_item.type === 'file' && instance[name] instanceof File) {
296
+ let container = new DataTransfer();
297
+ container.items.add(instance[name]);
298
+ form_item.files = container;
299
+ } else {
300
+ $(form_item).val(instance[name]);
301
+ }
342
302
  }
343
- let load_promise;
344
- if (this.values_list.length !== 0) {
345
- load_promise = this.isConnected();
346
- } else {
347
- load_promise = this.load();
303
+ }
304
+ });
305
+
306
+ }
307
+
308
+ syncForm($forms) {
309
+ if (!$forms || !$forms.hasClass(this.form_id)) {
310
+ $forms = $(`.${this.form_id}`);
311
+ }
312
+
313
+ const self = this;
314
+ let instances = [];
315
+
316
+ $forms.each(function () {
317
+ let $form = $(this);
318
+ let pk = $form.data('model_pk');
319
+ let instance = self.byPk(pk);
320
+ for (let form_item of this.elements) {
321
+ let name = form_item.name;
322
+ if (name && name !== '') {
323
+ if (form_item.type === 'hidden') {
324
+ instance[name] = parse_hidden_inputs($(form_item).val());
325
+ } else if (form_item.type === 'checkbox') {
326
+ instance[name] = form_item.checked;
327
+ } else if (form_item.type === 'file') {
328
+ instance[name] = form_item.files[0];
329
+ } else {
330
+ instance[name] = $(form_item).val();
331
+ }
348
332
  }
333
+ }
349
334
 
350
- let $div_form = $('<div class="container-fluid">');
335
+ instances.push(instance);
336
+ return instance;
337
+ });
351
338
 
352
- load_promise.then(() => {
353
- if (pk <= -1) {
354
- pk = this.values_list.at(pk).pk;
355
- }
356
-
357
- this._getForm(pk, 'edit_form', null, $div_form, cb_resolve, cb_reject);
358
- });
359
-
360
- return $div_form;
339
+ if (this.values_list.length <= 1 && instances.length > 0) {
340
+ this.values = instances.at(-1);
361
341
  }
362
342
 
363
- namedForm(pk = -1, formName, cb_resolve = null, cb_reject = null) {
364
- pk = parseInt(pk);
365
- if (isNaN(pk)) {
366
- pk = -1;
367
- }
368
- let load_promise;
369
- if (this.values_list.length !== 0) {
370
- load_promise = this.isConnected();
371
- } else {
372
- load_promise = this.load();
373
- }
343
+ return instances;
374
344
 
375
- let $div_form = $('<div class="container-fluid">');
376
-
377
- load_promise.then(() => {
378
- if (pk <= -1) {
379
- pk = this.values_list.at(pk).pk;
380
- }
381
-
382
- this._getForm(pk, 'named_form', formName, $div_form, cb_resolve, cb_reject);
383
- });
384
-
385
- return $div_form;
386
- }
345
+ }
387
346
 
388
-
389
- _getForm(pk, event_type, formName, $div_form, cb_resolve, cb_reject) {
390
- pk = parseInt(pk);
391
- if (isNaN(pk)) {
392
- pk = -1;
393
- }
347
+ createForm(cb_resolve = null, cb_reject = null) {
348
+ let $div_form = $('<div>');
349
+ this.isConnected().then(() => {
350
+ this._getForm(null, 'create_form', null, $div_form, cb_resolve, cb_reject);
351
+ });
352
+
353
+ return $div_form;
354
+ }
355
+
356
+ editForm(pk = -1, cb_resolve = null, cb_reject = null) {
357
+ pk = parseInt(pk);
358
+ if (isNaN(pk)) {
359
+ pk = -1;
360
+ }
361
+ let load_promise;
362
+ if (this.values_list.length !== 0) {
363
+ load_promise = this.isConnected();
364
+ } else {
365
+ load_promise = this.load();
366
+ }
367
+
368
+ let $div_form = $('<div>');
369
+
370
+ load_promise.then(() => {
371
+ if (pk <= -1) {
372
+ pk = this.values_list.at(pk).pk;
373
+ }
374
+
375
+ this._getForm(pk, 'edit_form', null, $div_form, cb_resolve, cb_reject);
376
+ });
377
+
378
+ return $div_form;
379
+ }
380
+
381
+ namedForm(pk = -1, formName, cb_resolve = null, cb_reject = null) {
382
+ pk = parseInt(pk);
383
+ if (isNaN(pk)) {
384
+ pk = -1;
385
+ }
386
+ let load_promise;
387
+ if (this.values_list.length !== 0) {
388
+ load_promise = this.isConnected();
389
+ } else {
390
+ load_promise = this.load();
391
+ }
392
+
393
+ let $div_form = $('<div class="container-fluid">');
394
+
395
+ load_promise.then(() => {
396
+ if (pk <= -1) {
397
+ pk = this.values_list.at(pk).pk;
398
+ }
399
+
400
+ this._getForm(pk, 'named_form', formName, $div_form, cb_resolve, cb_reject);
401
+ });
402
+
403
+ return $div_form;
404
+ }
405
+
406
+
407
+ _getForm(pk, event_type, formName, $div_form, cb_resolve, cb_reject) {
408
+ pk = parseInt(pk);
409
+ if (isNaN(pk)) {
410
+ pk = -1;
411
+ }
412
+ const id = uuidv4();
413
+ this.socket.send(JSON.stringify({
414
+ event: 'model',
415
+ event_type: event_type,
416
+ event_id: id,
417
+ args: {
418
+ model_name: this.model_name,
419
+ model_query: this.model_query,
420
+ pk: pk,
421
+ form_name: formName
422
+ }
423
+ }));
424
+
425
+ const className = pk === null || pk === -1 ? 'create' : 'edit';
426
+
427
+ this.open_request[id] = [(data) => {
428
+ $div_form.append(data.html);
429
+ let $form = $div_form.closest('form')
430
+ .addClass(`sdc-model-${className}-form sdc-model-form ${this.form_id}`)
431
+ .data('model', this)
432
+ .data('model_pk', pk)
433
+ .data('form_name', formName);
434
+ if ($form.length > 0 && !$form[0].hasAttribute('sdc_submit')) {
435
+ $form.attr('sdc_submit', 'submitModelFormDistributor')
436
+ }
437
+
438
+ app.refresh($div_form);
439
+ cb_resolve && cb_resolve(data);
440
+ }, (res) => {
441
+ cb_reject && cb_reject(res);
442
+ }];
443
+ }
444
+
445
+ new() {
446
+ return new Promise((resolve, reject) => {
447
+ const $form = $('<form>').append(this.createForm(() => {
448
+ this.syncFormToModel($form);
449
+ resolve();
450
+ }, reject));
451
+ })
452
+ }
453
+
454
+ save(pk = -1, fromName = 'edit_form') {
455
+ pk = parseInt(pk);
456
+ if (isNaN(pk)) {
457
+ pk = -1;
458
+ }
459
+ return this.isConnected().then(() => {
460
+ let elem_list;
461
+ if (pk > -1) {
462
+ elem_list = [this.byPk(pk)];
463
+ } else {
464
+ elem_list = this.values_list;
465
+ }
466
+ let p_list = []
467
+ elem_list.forEach((elem) => {
394
468
  const id = uuidv4();
395
- this.socket.send(JSON.stringify({
469
+ p_list.push(new Promise((resolve, reject) => {
470
+ this._readFiles(elem).then((files) => {
471
+ this.socket.send(JSON.stringify({
472
+ event: 'model',
473
+ event_type: 'save',
474
+ event_id: id,
475
+ args: {
476
+ form_name: fromName,
477
+ model_name: this.model_name,
478
+ model_query: this.model_query,
479
+ data: elem,
480
+ files: files
481
+ }
482
+ }));
483
+
484
+ this.open_request[id] = [(res) => {
485
+ let data = typeof res.data.instance === 'string' ? JSON.parse(res.data.instance) : res.data.instance;
486
+ res.data.instance = this._parseServerRes(data);
487
+ resolve(res);
488
+ }, reject];
489
+ });
490
+ }));
491
+ });
492
+
493
+ return Promise.all(p_list);
494
+ });
495
+ }
496
+
497
+ create(values = this.values) {
498
+ const id = uuidv4();
499
+ return this.isConnected().then(() => {
500
+ return new Promise((resolve, reject) => {
501
+ this._readFiles(values).then((files) => {
502
+ this.socket.send(JSON.stringify({
396
503
  event: 'model',
397
- event_type: event_type,
504
+ event_type: 'create',
398
505
  event_id: id,
399
506
  args: {
400
- model_name: this.model_name,
401
- model_query: this.model_query,
402
- pk: pk,
403
- form_name: formName
507
+ model_name: this.model_name,
508
+ model_query: this.model_query,
509
+ data: values,
510
+ files: files
404
511
  }
405
- }));
406
-
407
- const className = pk === null || pk === -1 ? 'create' : 'edit';
512
+ }));
408
513
 
409
- this.open_request[id] = [(data) => {
410
- $div_form.append(data.html);
411
- let $form = $div_form.closest('form').addClass(`sdc-model-${className}-form sdc-model-form ${this.form_id}`).data('model', this).data('model_pk', pk);
412
- if ($form.length > 0 && !$form[0].hasAttribute('sdc_submit')) {
413
- $form.attr('sdc_submit', 'submitModelFormDistributor')
514
+ this.open_request[id] = [(res) => {
515
+ let data = typeof res.data.instance === 'string' ? JSON.parse(res.data.instance) : res.data.instance;
516
+ if (this.values?.pk === -1) {
517
+ this.values_list = [];
518
+ this.values = null;
414
519
  }
415
-
416
- app.refresh($div_form);
417
- cb_resolve && cb_resolve(data);
418
- }, (res) => {
419
- cb_reject && cb_reject(res);
420
- }];
421
- }
422
-
423
- new() {
424
- return new Promise((resolve, reject) => {
425
- const $form = $('<form>').append(this.createForm(() => {
426
- this.syncFormToModel($form);
427
- resolve();
428
- }, reject));
520
+ res.data.instance = this._parseServerRes(data)[0];
521
+ resolve(res);
522
+ }, reject];
429
523
  })
430
- }
431
-
432
- save(pk = -1) {
433
- pk = parseInt(pk);
434
- if (isNaN(pk)) {
435
- pk = -1;
436
- }
437
- return this.isConnected().then(() => {
438
- let elem_list;
439
- if (pk > -1) {
440
- elem_list = [this.byPk(pk)];
441
- } else {
442
- elem_list = this.values_list;
443
- }
444
- let p_list = []
445
- elem_list.forEach((elem) => {
446
- const id = uuidv4();
447
- p_list.push(new Promise((resolve, reject) => {
448
- this._readFiles(elem).then((files) => {
449
- this.socket.send(JSON.stringify({
450
- event: 'model',
451
- event_type: 'save',
452
- event_id: id,
453
- args: {
454
- model_name: this.model_name,
455
- model_query: this.model_query,
456
- data: elem,
457
- files: files
458
- }
459
- }));
460
-
461
- this.open_request[id] = [(res) => {
462
- let data = typeof res.data.instance === 'string' ? JSON.parse(res.data.instance) : res.data.instance;
463
- res.data.instance = this._parseServerRes(data);
464
- resolve(res);
465
- }, reject];
466
- });
467
- }));
468
- });
469
-
470
- return Promise.all(p_list);
471
- });
472
- }
524
+ });
525
+ });
526
+ }
527
+
528
+ delete(pk = -1) {
529
+ pk = parseInt(pk);
530
+ if (isNaN(pk)) {
531
+ pk = -1;
532
+ }
533
+ if (pk === -1) pk = this.values?.pk;
534
+ const id = uuidv4();
535
+ return this.isConnected().then(() => {
536
+ return new Promise((resolve, reject) => {
537
+ this.socket.send(JSON.stringify({
538
+ event: 'model',
539
+ event_type: 'delete',
540
+ event_id: id,
541
+ args: {
542
+ model_name: this.model_name,
543
+ model_query: this.model_query,
544
+ pk: pk
545
+ }
546
+ }));
473
547
 
474
- create(values = this.values) {
475
- const id = uuidv4();
476
- return this.isConnected().then(() => {
477
- return new Promise((resolve, reject) => {
478
- this._readFiles(values).then((files) => {
479
- this.socket.send(JSON.stringify({
480
- event: 'model',
481
- event_type: 'create',
482
- event_id: id,
483
- args: {
484
- model_name: this.model_name,
485
- model_query: this.model_query,
486
- data: values,
487
- files: files
488
- }
489
- }));
490
-
491
- this.open_request[id] = [(res) => {
492
- let data = typeof res.data.instance === 'string' ? JSON.parse(res.data.instance) : res.data.instance;
493
- res.data.instance = this._parseServerRes(data)[0];
494
- resolve(res);
495
- }, reject];
496
- })
497
- });
548
+ this.open_request[id] = [resolve, reject];
549
+ });
550
+ });
551
+ }
552
+
553
+ isConnected() {
554
+ return new Promise((resolve, reject) => {
555
+ if (this._is_connected) {
556
+ resolve();
557
+ } else if (!this._is_conneting_process) {
558
+ this._is_conneting_process = true;
559
+ this.open_request['_connecting_process'] = [() => {
560
+ }, () => {
561
+ }]
562
+ this._connectToServer().then(() => {
563
+ resolve(this._checkConnection());
498
564
  });
499
- }
500
-
501
- delete(pk = -1) {
502
- pk = parseInt(pk);
503
- if (isNaN(pk)) {
504
- pk = -1;
505
- }
506
- if (pk === -1) pk = this.values?.pk;
507
- const id = uuidv4();
508
- return this.isConnected().then(() => {
509
- return new Promise((resolve, reject) => {
565
+ } else {
566
+ const [resolve_origin, reject_origin] = this.open_request['_connecting_process'];
567
+ this.open_request['_connecting_process'] = [
568
+ () => {
569
+ resolve_origin();
570
+ resolve();
571
+ },
572
+ () => {
573
+ reject_origin();
574
+ reject();
575
+ }
576
+ ]
577
+ }
578
+ });
579
+ }
580
+
581
+ close() {
582
+ if (this.socket) {
583
+ this._auto_reconnect = false;
584
+ this.socket.onclose = () => {
585
+ };
586
+ this.socket.close();
587
+ delete this['socket'];
588
+ }
589
+ }
590
+
591
+ clean() {
592
+ this.values_list = [];
593
+ this.values = {};
594
+ return this;
595
+ }
596
+
597
+ _readFiles(elem) {
598
+ let to_solve = [];
599
+ 100
600
+ let files = {}
601
+ for (const [key, value] of Object.entries(elem)) {
602
+ if (value instanceof File) {
603
+ to_solve.push(new Promise((resolve, reject) => {
604
+ ((key, value) => {
605
+ let reader = new FileReader();
606
+ reader.onload = e => {
607
+ const id = uuidv4();
608
+ this.open_request[id] = [resolve, reject];
609
+
610
+ let result = e.target.result;
611
+ let number_of_chunks = parseInt(Math.ceil(result.length / MAX_FILE_UPLOAD));
612
+ files[key] = {
613
+ id: id,
614
+ file_name: value.name,
615
+ field_name: key,
616
+ content_length: value.size,
617
+ };
618
+ for (let i = 0; i < number_of_chunks; ++i) {
510
619
  this.socket.send(JSON.stringify({
511
- event: 'model',
512
- event_type: 'delete',
513
- event_id: id,
514
- args: {
515
- model_name: this.model_name,
516
- model_query: this.model_query,
517
- pk: pk
518
- }
620
+ event: 'model',
621
+ event_type: 'upload',
622
+ event_id: id,
623
+ args: {
624
+ chunk: result.slice(MAX_FILE_UPLOAD * i, MAX_FILE_UPLOAD * (i + 1)),
625
+ idx: i,
626
+ number_of_chunks: number_of_chunks,
627
+ file_name: value.name,
628
+ field_name: key,
629
+ content_length: value.size,
630
+ content_type: value.type,
631
+ model_name: this.model_name,
632
+ model_query: this.model_query
633
+ }
519
634
  }));
520
-
521
- this.open_request[id] = [resolve, reject];
522
- });
523
- });
524
- }
525
-
526
- isConnected() {
527
- return new Promise((resolve, reject) => {
528
- if (this._is_connected) {
529
- resolve();
530
- } else if (!this._is_conneting_process) {
531
- this._is_conneting_process = true;
532
- this.open_request['_connecting_process'] = [() => {
533
- }, () => {
534
- }]
535
- this._connectToServer().then(() => {
536
- resolve(this._checkConnection());
537
- });
538
- } else {
539
- const [resolve_origin, reject_origin] = this.open_request['_connecting_process'];
540
- this.open_request['_connecting_process'] = [
541
- () => {
542
- resolve_origin();
543
- resolve();
544
- },
545
- () => {
546
- reject_origin();
547
- reject();
548
- }
549
- ]
635
+ }
550
636
  }
551
- });
552
- }
553
-
554
- close() {
555
- if (this.socket) {
556
- this._auto_reconnect = false;
557
- this.socket.onclose = () => {
637
+ reader.onerror = () => {
638
+ reject()
558
639
  };
559
- this.socket.close();
560
- delete this['socket'];
561
- }
562
- }
563
-
564
- clean() {
640
+ reader.readAsBinaryString(value);
641
+ })(key, value);
642
+ }))
643
+ }
644
+ }
645
+
646
+ return Promise.all(to_solve).then(() => {
647
+ return files
648
+ });
649
+ }
650
+
651
+ _onMessage(e) {
652
+ let data = JSON.parse(e.data);
653
+ if (data.is_error) {
654
+ if (this.open_request.hasOwnProperty(data.event_id)) {
655
+ this.open_request[data.event_id][1](data);
656
+ this._closeOpenRequest(data.event_id);
657
+ }
658
+ if (data.msg || data.header) {
659
+ trigger('pushErrorMsg', data.header || '', data.msg || '');
660
+ }
661
+
662
+ if (data.type === 'connect') {
663
+ this.open_request['_connecting_process'][1](data);
664
+ this._closeOpenRequest('_connecting_process');
665
+ this._auto_reconnect = false;
666
+ this.socket.close();
667
+ }
668
+ } else {
669
+
670
+ if (data.msg || data.header) {
671
+ trigger('pushMsg', data.header || '', data.msg || '');
672
+ }
673
+
674
+ if (data.type === 'connect') {
675
+ this._is_connected = true;
676
+ this._is_conneting_process = false;
677
+ this.open_request['_connecting_process'][0](data);
678
+ this._closeOpenRequest('_connecting_process');
679
+ } else if (['load', 'named_view', 'detail_view'].includes(data.type)) {
680
+ const json_res = JSON.parse(data.args.data);
565
681
  this.values_list = [];
566
- this.values = {};
567
- return this;
568
- }
569
-
570
- _readFiles(elem) {
571
- let to_solve = [];
572
- let files = {}
573
- for (const [key, value] of Object.entries(elem)) {
574
- if (value instanceof File) {
575
- to_solve.push(new Promise((resolve, reject) => {
576
- ((key, value) => {
577
- let reader = new FileReader();
578
- reader.onload = e => {
579
- const id = uuidv4();
580
- this.open_request[id] = [resolve, reject];
581
-
582
- let result = e.target.result;
583
- let number_of_chunks = parseInt(Math.ceil(result.length / MAX_FILE_UPLOAD));
584
- files[key] = {
585
- id: id,
586
- file_name: value.name,
587
- field_name: key,
588
- content_length: value.size,
589
- };
590
- for (let i = 0; i < number_of_chunks; ++i) {
591
- this.socket.send(JSON.stringify({
592
- event: 'model',
593
- event_type: 'upload',
594
- event_id: id,
595
- args: {
596
- chunk: result.slice(MAX_FILE_UPLOAD * i, MAX_FILE_UPLOAD * (i + 1)),
597
- idx: i,
598
- number_of_chunks: number_of_chunks,
599
- file_name: value.name,
600
- field_name: key,
601
- content_length: value.size,
602
- content_type: value.type,
603
- model_name: this.model_name,
604
- model_query: this.model_query
605
- }
606
- }));
607
- }
608
- }
609
- reader.onerror = () => {
610
- reject()
611
- };
612
- reader.readAsBinaryString(value);
613
- })(key, value);
614
- }))
615
- }
616
- }
682
+ data.args.data = this._parseServerRes(json_res);
617
683
 
618
- return Promise.all(to_solve).then(() => {
619
- return files
620
- });
621
- }
684
+ } else if (data.type === 'on_update' || data.type === 'on_create') {
685
+ const json_res = JSON.parse(data.args.data);
622
686
 
623
- _onMessage(e) {
624
- let data = JSON.parse(e.data);
625
- if (data.is_error) {
626
- if (this.open_request.hasOwnProperty(data.event_id)) {
627
- this.open_request[data.event_id][1](data);
628
- this._closeOpenRequest(data.event_id);
629
- }
630
- if (data.msg || data.header) {
631
- trigger('pushErrorMsg', data.header || '', data.msg || '');
632
- }
687
+ let obj = this._parseServerRes(json_res);
688
+ let cb;
633
689
 
634
- if (data.type === 'connect') {
635
- this.open_request['_connecting_process'][1](data);
636
- this._closeOpenRequest('_connecting_process');
637
- this._auto_reconnect = false;
638
- this.socket.close();
639
- }
690
+ if (data.type === 'on_create') {
691
+ cb = this.on_create;
640
692
  } else {
641
-
642
- if (data.msg || data.header) {
643
- trigger('pushMsg', data.header || '', data.msg || '');
644
- }
645
-
646
- if (data.type === 'connect') {
647
- this._is_connected = true;
648
- this._is_conneting_process = false;
649
- this.open_request['_connecting_process'][0](data);
650
- this._closeOpenRequest('_connecting_process');
651
- } else if (data.type === 'load') {
652
- const json_res = JSON.parse(data.args.data);
653
- this.values_list = [];
654
- data.args.data = this._parseServerRes(json_res);
655
-
656
- } else if (data.type === 'on_update' || data.type === 'on_create') {
657
- const json_res = JSON.parse(data.args.data);
658
-
659
- let obj = this._parseServerRes(json_res);
660
- let cb;
661
-
662
- if (data.type === 'on_create') {
663
- cb = this.on_create;
664
- } else {
665
- cb = this.on_update;
666
- }
667
-
668
- cb(obj);
669
- data.args.data = obj;
670
-
671
- }
672
-
673
- let instance = data.data?.instance
674
- if (instance) {
675
- data.data.instance = JSON.parse(data.data.instance);
676
- }
677
-
678
- if (this.open_request.hasOwnProperty(data.event_id)) {
679
- this.open_request[data.event_id][0](data);
680
- this._closeOpenRequest(data.event_id);
681
- }
693
+ cb = this.on_update;
682
694
  }
683
- }
684
695
 
685
- noOpenRequests() {
686
- return new Promise(resolve => {
687
- if (Object.keys(this.open_request).length === 0) {
688
- return resolve();
689
- }
696
+ cb(obj);
697
+ data.args.data = obj;
690
698
 
691
- this._onNoOpenRequests.push(resolve);
692
- });
693
- }
699
+ }
694
700
 
695
- _closeOpenRequest(event_id) {
696
- delete this.open_request[event_id];
697
- if (Object.keys(this.open_request).length === 0) {
698
- this._onNoOpenRequests.forEach(x => x());
699
- this._onNoOpenRequests = [];
700
- }
701
+ let instance = data.data?.instance
702
+ if (instance) {
703
+ data.data.instance = JSON.parse(data.data.instance);
704
+ }
701
705
 
706
+ if (this.open_request.hasOwnProperty(data.event_id)) {
707
+ this.open_request[data.event_id][0](data);
708
+ this._closeOpenRequest(data.event_id);
709
+ }
702
710
  }
711
+ }
703
712
 
704
- _connectToServer() {
705
- return new Promise((resolve) => {
706
-
707
- const model_identifier = `${this.model_name}` + (this.model_id > 0 ? `/${this.model_id}` : '');
708
- if (window.location.protocol === "https:") {
709
- this.socket = new WebSocket(`wss://${window.location.host}/sdc_ws/model/${model_identifier}`);
710
- } else {
711
- this.socket = new WebSocket(`ws://${window.location.host}/sdc_ws/model/${model_identifier}`);
712
- }
713
-
713
+ noOpenRequests() {
714
+ return new Promise(resolve => {
715
+ if (Object.keys(this.open_request).length === 0) {
716
+ return resolve();
717
+ }
714
718
 
715
- this.socket.onmessage = this._onMessage.bind(this);
719
+ this._onNoOpenRequests.push(resolve);
720
+ });
721
+ }
716
722
 
717
- this.socket.onclose = (e) => {
718
- console.error(`SDC Model (${this.model_name}, ${this.model_id}) Socket closed unexpectedly`);
719
- this._is_connected = false;
720
- for (const [_key, value] of Object.entries(this.open_request)) {
721
- value[1](e);
722
- }
723
- this.open_request = {};
723
+ _closeOpenRequest(event_id) {
724
+ delete this.open_request[event_id];
725
+ if (Object.keys(this.open_request).length === 0) {
726
+ this._onNoOpenRequests.forEach(x => x());
727
+ this._onNoOpenRequests = [];
728
+ }
724
729
 
725
- setTimeout(() => {
726
- if (this._auto_reconnect) {
727
- this._connectToServer().then(() => {
728
- });
729
- }
730
- }, 1000);
731
- };
730
+ }
732
731
 
733
- this.socket.onerror = (err) => {
734
- console.error(`Model Socket encountered error: ${err} Closing socket`);
735
- if (this._is_connected) {
736
- try {
737
- this.socket.close();
738
- } catch (e) {
732
+ _connectToServer() {
733
+ return new Promise((resolve) => {
739
734
 
740
- }
741
- }
742
- };
735
+ const model_identifier = `${this.model_name}` + (this.model_id > 0 ? `/${this.model_id}` : '');
736
+ if (window.location.protocol === "https:") {
737
+ this.socket = new WebSocket(`wss://${window.location.host}/sdc_ws/model/${model_identifier}`);
738
+ } else {
739
+ this.socket = new WebSocket(`ws://${window.location.host}/sdc_ws/model/${model_identifier}`);
740
+ }
743
741
 
744
742
 
745
- this.socket.onopen = () => {
746
- resolve();
747
- }
748
- });
749
-
750
- }
751
-
752
- _checkConnection() {
753
- const id = uuidv4();
754
- return new Promise((resolve, reject) => {
755
- this.socket.send(JSON.stringify({
756
- event: 'model',
757
- event_type: 'connect',
758
- event_id: id,
759
- args: {
760
- model_name: this.model_name,
761
- model_query: this.model_query
762
- }
763
- }));
743
+ this.socket.onmessage = this._onMessage.bind(this);
764
744
 
765
- this.open_request[id] = [resolve, reject];
766
- });
767
- }
745
+ this.socket.onclose = (e) => {
746
+ console.error(`SDC Model (${this.model_name}, ${this.model_id}) Socket closed unexpectedly`);
747
+ this._is_connected = false;
748
+ for (const [_key, value] of Object.entries(this.open_request)) {
749
+ value[1](e);
750
+ }
751
+ this.open_request = {};
768
752
 
769
- _parseServerRes(res) {
770
- let updated = [];
771
- for (let json_data of res) {
772
- const pk = json_data.pk;
773
- const obj = this.byPk(pk);
774
- for (const [k, v] of Object.entries(json_data.fields)) {
775
- if (v && typeof v === 'object' && v['__is_sdc_model__']) {
776
- obj[k] = new SubModel(v['pk'], v['model'])
777
- } else {
778
- obj[k] = v;
779
- }
780
- }
753
+ setTimeout(() => {
754
+ if (this._auto_reconnect) {
755
+ this._connectToServer().then(() => {
756
+ });
757
+ }
758
+ }, 1000);
759
+ };
760
+
761
+ this.socket.onerror = (err) => {
762
+ console.error(`Model Socket encountered error: ${err} Closing socket`);
763
+ if (this._is_connected) {
764
+ try {
765
+ this.socket.close();
766
+ } catch (e) {
781
767
 
782
- updated.push(obj);
768
+ }
783
769
  }
784
-
785
- if (this.values_list.length === 1) {
786
- this.values = this.values_list.at(-1);
770
+ };
771
+
772
+
773
+ this.socket.onopen = () => {
774
+ resolve();
775
+ }
776
+ });
777
+
778
+ }
779
+
780
+ _checkConnection() {
781
+ const id = uuidv4();
782
+ return new Promise((resolve, reject) => {
783
+ this.socket.send(JSON.stringify({
784
+ event: 'model',
785
+ event_type: 'connect',
786
+ event_id: id,
787
+ args: {
788
+ model_name: this.model_name,
789
+ model_query: this.model_query
790
+ }
791
+ }));
792
+
793
+ this.open_request[id] = [resolve, reject];
794
+ });
795
+ }
796
+
797
+ _parseServerRes(res) {
798
+ let updated = [];
799
+ for (let json_data of res) {
800
+ const pk = json_data.pk;
801
+ const obj = this.byPk(pk);
802
+ for (const [k, v] of Object.entries(json_data.fields)) {
803
+ if (v && typeof v === 'object' && v['__is_sdc_model__']) {
804
+ obj[k] = new SubModel(v['pk'], v['model'])
787
805
  } else {
788
- this.values = {};
806
+ obj[k] = v;
789
807
  }
808
+ }
790
809
 
791
- return updated;
810
+ updated.push(obj);
811
+ }
792
812
 
813
+ if (this.values_list.length === 1) {
814
+ this.values = this.values_list.at(-1);
815
+ } else {
816
+ this.values = {};
793
817
  }
818
+
819
+ return updated;
820
+
821
+ }
794
822
  }