complexqa_frontend_core 1.0.7 → 1.0.9

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.
@@ -1,3411 +0,0 @@
1
-
2
- /**
3
- * Прототип идеи, пока не уверен, что именно так надо
4
- *
5
- * @version v.0.1 (25/06/2024)
6
- */
7
- export class App
8
- {
9
-
10
- init_options = false;
11
-
12
- /**
13
- *
14
- * @version v.0.1 (25/06/2024)
15
- */
16
- constructor(init_options)
17
- {
18
-
19
- if (this.constructor._instance)
20
- {
21
- return this.constructor._instance;
22
- }
23
-
24
- this.init_options = init_options;
25
- this.constructor._instance = this;
26
-
27
- this.#bootstrap();
28
-
29
- return this.constructor._instance;
30
- }
31
-
32
- /**
33
- *
34
- * @version v.0.1 (25/06/2024)
35
- */
36
- #bootstrap()
37
- {
38
- this.service = {};
39
- this.service.translate = new serviceTranslate();
40
- }
41
- }
42
-
43
-
44
- /**
45
- * Общие методы для всех типизированных элементов
46
- *
47
- * @version v.2.0 (24/11/2024)
48
- */
49
- export class ApiAbstractElementClass
50
- {
51
-
52
- init_options;
53
- element_class_instance;
54
- dev_stage_config;
55
- parent_app;
56
- host_api;
57
- stage = 'production';
58
- module_prefix = false;
59
- api_prefix = 'web_api';
60
- method;
61
- headers;
62
-
63
-
64
- /**
65
- *
66
- * @version v.0.1 (27/06/2024)
67
- * @param options
68
- */
69
- constructor(options)
70
- {
71
- if (options?.init_options)
72
- {
73
- this.init_options = options?.init_options;
74
- }
75
- if (options?.stage)
76
- {
77
- this.stage = options?.stage;
78
- }
79
- if (options?.dev_stage_config)
80
- {
81
- this.dev_stage_config = options?.dev_stage_config;
82
- }
83
- if (options?.parent_app)
84
- {
85
- this.parent_app = options?.parent_app;
86
- }
87
- if (options?.host_api)
88
- {
89
- this.host_api = options?.host_api;
90
- }
91
- }
92
-
93
-
94
- set_element_class_instance(element_class_instance)
95
- {
96
- this.element_class_instance = element_class_instance;
97
- }
98
-
99
-
100
- /**
101
- *
102
- * @version v.0.1 (26/05/2024)
103
- * @param {object|typeFOR} payload
104
- * @param {array} payload.filter
105
- * @param {?object|undefined} payload.object
106
- * @param {?object|undefined} payload.response
107
- */
108
- async search(payload)
109
- {
110
- if (!this.module_prefix)
111
- {
112
- throw new Error('Error #10-1152 in ApiAbstractClass');
113
- }
114
-
115
- if (this.stage === 'development')
116
- {
117
- let response = await this.#mock_search(payload);
118
- return {
119
- response: response,
120
- payload : payload
121
- };
122
- }
123
-
124
- let url = `/${ this.api_prefix }/${ this.module_prefix }/search`;
125
-
126
- payload = this.#handle_request_payload(payload);
127
- let response = this.#api_request(url, payload);
128
- response = this.#handle_response(response);
129
-
130
- return {
131
- response: response,
132
- payload : payload
133
- };
134
- }
135
-
136
-
137
- /**
138
- *
139
- * @version v.0.1 (27/06/2024)
140
- * @param payload
141
- * @returns {Promise<array>}
142
- */
143
- async #mock_search(payload)
144
- {
145
- // @todo - дописать
146
- if (this.dev_stage_config.api_response_search_element_count > 0 && this.dev_stage_config.api_response_search_element_count < 999)
147
- {
148
-
149
- }
150
- else
151
- {
152
- throw new Error('Error #100-154');
153
- }
154
-
155
- let model = new this.element_class_instance();
156
- let response = model.get_random_demo_data(this.dev_stage_config.api_response_search_element_count)
157
-
158
- return response;
159
-
160
- }
161
-
162
-
163
- /**
164
- *
165
- * @version v.0.1 (26/05/2024)
166
- * @param payload
167
- */
168
- async find(payload)
169
- {
170
- if (!this.module_prefix)
171
- {
172
- throw new Error('Error #10-1152 in ApiAbstractClass');
173
- }
174
- }
175
-
176
-
177
- /**
178
- *
179
- * @version v.0.1 (26/05/2024)
180
- * @param payload
181
- */
182
- async create(payload)
183
- {
184
- if (!this.module_prefix)
185
- {
186
- throw new Error('Error #10-1152 in ApiAbstractClass');
187
- }
188
-
189
- if (this.stage === 'development')
190
- {
191
- return {
192
- response: payload,
193
- payload : payload
194
- };
195
- }
196
-
197
- let url = `/${ this.api_prefix }/${ this.module_prefix }/create`;
198
-
199
- payload = this.#handle_request_payload(payload);
200
- let response = this.#api_request(url, payload);
201
- response = this.#handle_response(response);
202
-
203
- return {
204
- response: response,
205
- payload : payload
206
- };
207
- }
208
-
209
-
210
- /**
211
- *
212
- * @version v.0.1 (26/05/2024)
213
- * @param payload
214
- */
215
- async update(payload)
216
- {
217
- if (!this.module_prefix)
218
- {
219
- throw new Error('Error #10-1152 in ApiAbstractClass');
220
- }
221
-
222
- }
223
-
224
-
225
- /**
226
- *
227
- * @version v.0.1 (26/05/2024)
228
- * @param payload
229
- */
230
- async update_property(payload)
231
- {
232
- if (!this.module_prefix)
233
- {
234
- throw new Error('Error #10-1152 in ApiAbstractClass');
235
- }
236
-
237
- if (this.stage === 'development')
238
- {
239
- return {
240
- response: payload,
241
- payload : payload
242
- };
243
- }
244
-
245
- let url = `/${ this.api_prefix }/${ this.module_prefix }/update_property`;
246
-
247
- payload = this.#handle_request_payload(payload);
248
- let response = this.#api_request(url, payload);
249
- response = this.#handle_response(response);
250
-
251
- return {
252
- response: response,
253
- payload : payload
254
- };
255
- }
256
-
257
-
258
- /**
259
- *
260
- * @version v.0.1 (26/05/2024)
261
- * @param payload
262
- */
263
- async delete(payload)
264
- {
265
- if (!this.module_prefix)
266
- {
267
- throw new Error('Error #10-1152 in ApiAbstractClass');
268
- }
269
-
270
- if (this.stage === 'development')
271
- {
272
- return {
273
- response: payload,
274
- payload : payload
275
- };
276
- }
277
-
278
- let url = `/${ this.api_prefix }/${ this.module_prefix }/delete`;
279
-
280
- payload = this.#handle_request_payload(payload);
281
- let response = this.#api_request(url, payload);
282
- response = this.#handle_response(response);
283
-
284
- return {
285
- response: response,
286
- payload : payload
287
- };
288
- }
289
-
290
-
291
- /******************************************************************************************/
292
- /******************************************************************************************/
293
-
294
- /******************************************************************************************/
295
-
296
- #handle_request_payload(payload)
297
- {
298
- return this.#object_replace_null_recursively(payload);
299
- }
300
-
301
- #object_replace_null_recursively(object)
302
- {
303
- let result = clone_object(object);
304
- for (let key in result)
305
- {
306
- if (result[ key ] === null)
307
- {
308
- result[ key ] = 'NULL';
309
- }
310
- else if (( result[ key ]?.constructor === Object ) || ( result[ key ]?.constructor === Array ))
311
- {
312
- result[ key ] = this.#object_replace_null_recursively(result[ key ]);
313
- }
314
- }
315
-
316
- return result;
317
- }
318
-
319
-
320
- /**
321
- *
322
- * @param url
323
- * @param payload
324
- * @param method
325
- * @returns {Promise<Promise<axios.AxiosResponse<any>> | *>}
326
- * @version v.0.2 (26/01/2025)
327
- */
328
- async #api_request(url, payload, method = 'POST')
329
- {
330
- let request_params;
331
- if (!payload)
332
- {
333
- request_params = {};
334
- }
335
- else
336
- {
337
- request_params = clone_object(payload)
338
- }
339
-
340
- request_params = this.#mixin_service_params(request_params);
341
-
342
- console.log({payload, request_params});
343
-
344
-
345
- if (this.host_api)
346
- {
347
- url = 'https://' + this.host_api + url;
348
- }
349
-
350
- let request_options = {
351
- method : method,
352
- headers: this.headers,
353
- url : url
354
- };
355
-
356
- if (this.method === 'get')
357
- {
358
- request_options.paramsSerializer = this.object_to_string;
359
- request_options.params = request_params;
360
- }
361
- else
362
- {
363
- request_options.data = (request_params);
364
- }
365
-
366
- let config = {};
367
-
368
- return axios(request_options, config);
369
- }
370
-
371
-
372
- /**
373
- *
374
- * @param object
375
- * @returns {string}
376
- */
377
- object_to_string(object)
378
- {
379
- let result = qs.stringify(object, { array_format: 'indices' });
380
-
381
- return result;
382
- }
383
-
384
-
385
- #mixin_service_params(params)
386
- {
387
- params.client = 'webapp';
388
- return params;
389
- }
390
-
391
-
392
- /**
393
- *
394
- * @param {} response
395
- * @returns {Promise<any>}
396
- * @version v.0.1 (01/06/2024)
397
- */
398
- #handle_response(response)
399
- {
400
- response = response.then((api_response) =>
401
- {
402
- let error_payload = {
403
- api_response: api_response?.data?.api_response,
404
- api_code : api_response?.data?.api_code,
405
- api_result : api_response?.data?.api_result,
406
- api_error : api_response?.data?.api_error
407
- };
408
-
409
- if (api_response?.data?.api_error?.adapted_message)
410
- {
411
- error_payload.message = api_response.data.api_error.adapted_message
412
- throw new ApiException(error_payload);
413
- }
414
- else if (api_response?.data?.api_code)
415
- {
416
- let api_code = api_response.data.api_code;
417
-
418
- if (( api_code >= 200 ) && ( api_code <= 299 ))
419
- {
420
- if (is_array(api_response?.data) && this.element_class_instance)
421
- {
422
- let result = api_response?.data.map((row) =>
423
- {
424
- return new this.element_class_instance(row);
425
- });
426
-
427
- return result;
428
- }
429
- else
430
- {
431
- return api_response?.data;
432
- }
433
- }
434
- else if (api_response?.data?.api_result === false)
435
- {
436
- throw new ApiException(error_payload);
437
- }
438
- else
439
- {
440
- throw new ApiException(error_payload);
441
- }
442
- }
443
- else
444
- {
445
- return api_response?.data;
446
- }
447
- })
448
- .catch((error) =>
449
- {
450
-
451
- echo({ app: this });
452
- console.error(error);
453
- if (error instanceof ApiException)
454
- {
455
- throw error;
456
- }
457
-
458
-
459
- throw new ApiException({ error: error });
460
- });
461
-
462
- return response;
463
- }
464
- }
465
-
466
-
467
- /**
468
- *
469
- * @version v.0.1 (24/11/2024)
470
- */
471
- export class FunctionalApi extends ApiAbstractElementClass
472
- {
473
- module_prefix = 'functional';
474
-
475
- constructor(options)
476
- {
477
- super(options);
478
- this.set_element_class_instance(typeFunctional);
479
- }
480
- }
481
-
482
- /**
483
- * Обертка над axios
484
- * @version v.0.3 (26/01/2025)
485
- */
486
- export class Api
487
- {
488
- /**
489
- * Режим работы
490
- *
491
- * @type {string} development || production || tests
492
- */
493
- stage = 'development';
494
- dev_stage_config = {
495
- generate_error : false,
496
- api_response_delay : 3500,
497
- api_response_search_element_count: 8,
498
- };
499
-
500
- init_options;
501
-
502
- test_plan;
503
- /**
504
- * {ProjectApi} project
505
- */
506
- project;
507
- service;
508
-
509
- host_api = false;
510
-
511
-
512
- /**
513
- *
514
- * @version v.0.3 (26/01/2025)
515
- */
516
- constructor(init_options)
517
- {
518
-
519
- if (this.constructor._instance)
520
- {
521
- return this.constructor._instance;
522
- }
523
-
524
-
525
- if (init_options.host_api)
526
- {
527
- // @todo validate
528
- this.host_api = init_options.host_api;
529
- }
530
- else
531
- {
532
- // подумать
533
- this.host_api = 'complexqa.localhost';
534
- }
535
-
536
- if (init_options.stage)
537
- {
538
- // @todo validate
539
- this.stage = init_options.stage;
540
- }
541
-
542
- if (init_options.dev_stage_config)
543
- {
544
- // @todo validate
545
- this.dev_stage_config = init_options.dev_stage_config;
546
- }
547
-
548
- this.init_options = init_options;
549
- this.constructor._instance = this;
550
-
551
-
552
- this.#bootstrap();
553
- return this.constructor._instance;
554
- }
555
-
556
-
557
- /**
558
- *
559
- * @param stage
560
- */
561
- set_stage(stage)
562
- {
563
- this.stage = stage;
564
- }
565
-
566
-
567
- /**
568
- *
569
- * @version v.0.1 (25/06/2024)
570
- */
571
- #bootstrap()
572
- {
573
- let payload = {
574
- init_options : this.init_options,
575
- stage : this.stage,
576
- dev_stage_config: this.dev_stage_config,
577
- host_api: this.host_api,
578
- parent_app : this
579
- };
580
-
581
- //echo({payload});
582
-
583
- this.test_plan = new TestPlanApi(payload);
584
- this.project = new ProjectApi(payload);
585
- this.service = new ServiceApi(payload);
586
- this.test_case = new TestCaseApi(payload);
587
- this.test_suite = new TestSuiteApi(payload);
588
- }
589
- }
590
-
591
- /**
592
- *
593
- * @version v.0.1 (15/06/2024)
594
- */
595
- export class ProjectApi extends ApiAbstractElementClass
596
- {
597
- module_prefix = 'project';
598
-
599
- constructor(options)
600
- {
601
- super(options);
602
- this.set_element_class_instance(typeProject);
603
- }
604
- }
605
-
606
- // тут нужен свой класс, не для типов
607
- export class ServiceApi
608
- {
609
- module_prefix = '--';
610
-
611
- constructor(options)
612
- {
613
- }
614
-
615
-
616
- /**
617
- *
618
- * @returns {Promise<*[]>}
619
- */
620
- async translate_get_dictionaries()
621
- {
622
- return [];
623
- }
624
- }
625
-
626
-
627
- /**
628
- *
629
- * @version v.0.1 (24/11/2024)
630
- */
631
- export class TeamMemberApi extends ApiAbstractElementClass
632
- {
633
- module_prefix = 'team_member';
634
-
635
- constructor(options)
636
- {
637
- super(options);
638
- this.set_element_class_instance(typeTeamMember);
639
- }
640
- }
641
-
642
-
643
- /**
644
- *
645
- * @version v.0.1 (24/11/2024)
646
- */
647
- export class TestCaseApi extends ApiAbstractElementClass
648
- {
649
- module_prefix = 'test_case';
650
-
651
- constructor(options)
652
- {
653
- super(options);
654
- this.set_element_class_instance(typeTestCase);
655
- }
656
- }
657
-
658
-
659
- /**
660
- *
661
- * @version v.0.1 (24/11/2024)
662
- */
663
- export class TestCaseStepApi extends ApiAbstractElementClass
664
- {
665
- module_prefix = 'test_case_step';
666
-
667
- constructor(options)
668
- {
669
- super(options);
670
- this.set_element_class_instance(typeTestCaseStep);
671
- }
672
- }
673
-
674
-
675
- /**
676
- *
677
- * @version v.0.1 (26/05/2024)
678
- */
679
- export class TestPlanApi extends ApiAbstractElementClass
680
- {
681
- module_prefix = 'test_plan';
682
-
683
- constructor(options)
684
- {
685
- super(options);
686
- this.set_element_class_instance(typeTestPlan);
687
- }
688
- }
689
-
690
- export class TestRunApi extends ApiAbstractElementClass
691
- {
692
- module_prefix = 'test_run';
693
-
694
- constructor(options)
695
- {
696
- super(options);
697
- this.set_element_class_instance(typeTestRun);
698
- }
699
- }
700
-
701
-
702
- /**
703
- *
704
- * @version v.0.1 (24/11/2024)
705
- */
706
- export class TestRunResultApi extends ApiAbstractElementClass
707
- {
708
- module_prefix = 'test_run_result';
709
-
710
- constructor(options)
711
- {
712
- super(options);
713
- this.set_element_class_instance(typeTestRunResult);
714
- }
715
- }
716
-
717
-
718
- /**
719
- *
720
- * @version v.0.1 (24/11/2024)
721
- */
722
- export class TestSuiteApi extends ApiAbstractElementClass
723
- {
724
- module_prefix = 'test_suite';
725
-
726
- constructor(options)
727
- {
728
- super(options);
729
- this.set_element_class_instance(typeTestSuite);
730
- }
731
- }
732
- export class ApiException extends Error
733
- {
734
- /**
735
- * Сообщение об ошибке
736
- * @type {string}
737
- */
738
- #message = '';
739
- /**
740
- * Нативная ошибка
741
- * @type {null|Error}
742
- */
743
- #error = null;
744
-
745
-
746
- api_response = null;
747
- api_code = null;
748
- api_result = null;
749
- api_error = null;
750
-
751
-
752
- constructor(options)
753
- {
754
- super();
755
-
756
- if (options.message)
757
- {
758
- this.#message = options.message;
759
- }
760
-
761
- if (options.error instanceof Error)
762
- {
763
- this.#error = options.error;
764
- }
765
-
766
-
767
- if (options?.api_response)
768
- {
769
- this.api_response = options?.api_response;
770
- }
771
-
772
- if (options?.api_code)
773
- {
774
- this.api_code = options?.api_code;
775
- }
776
-
777
- if (options?.api_result)
778
- {
779
- this.api_result = options?.api_result;
780
- }
781
-
782
- if (options?.api_error)
783
- {
784
- this.api_error = options?.api_error;
785
- }
786
- }
787
-
788
-
789
- get_message()
790
- {
791
- if (this.#error instanceof Error)
792
- {
793
- return this.#error.message;
794
- }
795
- else
796
- {
797
- return this.#message;
798
- }
799
- }
800
- }
801
- /**
802
- *
803
- * @version v.0.1 (25/06/2024)
804
- */
805
- export class abstractService
806
- {
807
- init_options = false;
808
-
809
-
810
- /**
811
- *
812
- * @param init_options
813
- */
814
- constructor(init_options = false)
815
- {
816
- /*if (this.constructor._instance)
817
- {
818
- return this.constructor._instance;
819
- }
820
-
821
- this.init_options = init_options;
822
-
823
- this.constructor._instance = this;*/
824
- }
825
-
826
-
827
- static mock()
828
- {
829
-
830
- }
831
-
832
- /*#bootstrap()
833
- {
834
-
835
- }*/
836
- }
837
-
838
- /**
839
- *
840
- * @version v.0.1 (25/06/2024)
841
- */
842
- export class serviceTranslate extends abstractService
843
- {
844
- #language = 'en';
845
- #available_language = [ 'ru', 'en' ];
846
- #dictionary = false; // может сделать сторадж отдельно и static ?
847
- #vendor_instance;
848
-
849
-
850
- /**
851
- *
852
- * @version v.0.1 (25/06/2024)
853
- * @param {?object} init_options
854
- * @returns {serviceTranslate}
855
- */
856
- constructor(init_options = false)
857
- {
858
- super(init_options);
859
-
860
- if (init_options?.language)
861
- {
862
- if (in_array(init_options?.language, this.#available_language))
863
- {
864
- this.#language = init_options?.language;
865
- }
866
- else
867
- {
868
- echo({ init_options });
869
- throw new Error('Unsupported language');
870
- }
871
- }
872
-
873
- if (this.constructor._instance)
874
- {
875
- return this.constructor._instance;
876
- }
877
-
878
- this.init_options = init_options;
879
- this.constructor._instance = this;
880
-
881
- this.#bootstrap();
882
-
883
- return this.constructor._instance;
884
- }
885
-
886
-
887
- /**
888
- *
889
- * @version v.0.1 (25/06/2024)
890
- * @param api_response
891
- */
892
- #api_response_parser(api_response)
893
- {
894
-
895
- // заготовка
896
- return api_response;
897
- }
898
-
899
-
900
- /**
901
- *
902
- * @version v.0.1 (25/06/2024)
903
- */
904
- async #bootstrap()
905
- {
906
- this.#dictionary = await Api.service.translate_get_dictionaries();
907
-
908
- let normalize_response = this.#api_response_parser(this.#dictionary);
909
-
910
-
911
- await i18next.init({
912
- lng : this.#language,
913
- debug : false,
914
- resources: normalize_response
915
- });
916
-
917
- this.#vendor_instance = i18next;
918
- }
919
-
920
-
921
- /**
922
- *
923
- * @version v.0.1 (25/06/2024)
924
- * @param group
925
- * @param key
926
- */
927
- get(group, key)
928
- {
929
- return this.#vendor_instance.t(group + '.' + key);
930
- }
931
- }
932
-
933
- /**
934
- *
935
- * @version v.1.0 (18/11/2024)
936
- */
937
- export class UserService extends abstractService
938
- {
939
-
940
- static current_user_id = false;
941
- static user_name = false;
942
- static current_team_id = false;
943
- static current_team_slug = false;
944
- static user_teams = false;
945
- static roles = [ 'guest' ];
946
- static current_language = 'en';
947
- static csrf_token = false;
948
-
949
-
950
- /**
951
- *
952
- *
953
- * @version v.1.0 (18/11/2024)
954
- *
955
- * @param init_options
956
- * @returns {*}
957
- */
958
- constructor(init_options = false)
959
- {
960
- super();
961
- if (this.constructor._instance)
962
- {
963
- return this.constructor._instance;
964
- }
965
-
966
- this.init_options = init_options;
967
-
968
- this.constructor._instance = this;
969
- }
970
-
971
- static mock()
972
- {
973
- MockUserService.mock_attributes.map((row) =>
974
- {
975
- UserService[ row.key ] = row.value;
976
- });
977
- }
978
-
979
- static get_csrf_token()
980
- {
981
- return UserService.csrf_token;
982
- }
983
-
984
- static set_csrf_token(csrf_token)
985
- {
986
- UserService.csrf_token = csrf_token;
987
- }
988
-
989
- static get_current_user_id()
990
- {
991
- return UserService.current_user_id;
992
- }
993
-
994
- static set_current_user_id(current_user_id)
995
- {
996
- UserService.current_user_id = current_user_id;
997
- }
998
-
999
- static get_current_team_slug()
1000
- {
1001
- return UserService.current_team_slug;
1002
- }
1003
-
1004
- static set_current_team_slug(current_team_slug)
1005
- {
1006
- UserService.current_team_slug = current_team_slug;
1007
- }
1008
-
1009
- static get_user_name()
1010
- {
1011
- return UserService.user_name;
1012
- }
1013
-
1014
- static set_user_name(user_name)
1015
- {
1016
- UserService.user_name = user_name;
1017
- }
1018
-
1019
- static get_current_team_id()
1020
- {
1021
- return UserService.current_team_id;
1022
- }
1023
-
1024
- static set_current_team_id(current_team_id)
1025
- {
1026
- UserService.current_team_id = current_team_id;
1027
- }
1028
-
1029
- static get_user_teams()
1030
- {
1031
- return UserService.user_teams;
1032
- }
1033
-
1034
- static set_user_teams(user_teams)
1035
- {
1036
- UserService.user_teams = user_teams;
1037
- }
1038
-
1039
- static get_roles()
1040
- {
1041
- return UserService.roles;
1042
- }
1043
-
1044
- static get_roles(roles)
1045
- {
1046
- UserService.roles = roles;
1047
- }
1048
-
1049
- static get_current_language()
1050
- {
1051
- return UserService.current_language;
1052
- }
1053
-
1054
- static set_current_language(current_language)
1055
- {
1056
- UserService.current_language = current_language;
1057
- }
1058
- }
1059
-
1060
- /**
1061
- *
1062
- * @param {object} object
1063
- * @returns {object}
1064
- */
1065
- export function clone_object(object)
1066
- {
1067
- // @todo use deep clone
1068
- // @todo add validation
1069
- return JSON.parse(JSON.stringify(object));
1070
- }
1071
-
1072
- /**
1073
- *
1074
- * @param {string|number|array|object} text
1075
- */
1076
- export function echo(text)
1077
- {
1078
- console.log(text);
1079
- }
1080
-
1081
-
1082
- /**
1083
- *
1084
- * @param {string|number|array|object} data
1085
- */
1086
- export function echo_table(...data)
1087
- {
1088
- if (is_array(data))
1089
- {
1090
- data.map((row) =>
1091
- {
1092
- console.table(row);
1093
- });
1094
- }
1095
- else
1096
- {
1097
- echo(data);
1098
- }
1099
- }
1100
-
1101
- /**
1102
- *
1103
- *
1104
- * @param {*} data
1105
- * @param {boolean} strict_mode
1106
- * @returns {boolean}
1107
- */
1108
- export function is_array(data, strict_mode = false)
1109
- {
1110
- if (strict_mode)
1111
- {
1112
- if (data instanceof Array)
1113
- {
1114
- return true;
1115
- }
1116
- else
1117
- {
1118
- return false;
1119
- }
1120
- }
1121
- else
1122
- {
1123
- if (data instanceof Array && data?.length > 0)
1124
- {
1125
- return true;
1126
- }
1127
- else
1128
- {
1129
- return false;
1130
- }
1131
- }
1132
- }
1133
-
1134
-
1135
- /**
1136
- *
1137
- *
1138
- * @param {*} value
1139
- * @returns {boolean}
1140
- */
1141
- export function is_object(value)
1142
- {
1143
- return _.isObject(value);
1144
- }
1145
-
1146
-
1147
- /**
1148
- *
1149
- *
1150
- * @param {*} value
1151
- * @returns {boolean}
1152
- */
1153
- export function is_string(value)
1154
- {
1155
- let response = false;
1156
- if (typeof value === 'string')
1157
- {
1158
- response = true;
1159
- }
1160
-
1161
- return response;
1162
- }
1163
-
1164
-
1165
- /**
1166
- * Проверяем на число, не строго (!)
1167
- * @param {*} value
1168
- * @returns {boolean}
1169
- */
1170
- export function is_number(value)
1171
- {
1172
- let response = false;
1173
-
1174
- if (typeof ( value ) === 'number')
1175
- {
1176
- response = true;
1177
- }
1178
- else if (value === false)
1179
- {
1180
- response = false;
1181
- }
1182
- else if (typeof ( value ) === "string" && (!isNaN( value )))
1183
- {
1184
- response = true;
1185
- }
1186
-
1187
- return response
1188
- }
1189
-
1190
-
1191
- /**
1192
- * Возвращает количество элементов массива или false, если передан не массив
1193
- *
1194
- * @param {array} array массив
1195
- * @returns {number|false} количество элементов массива
1196
- */
1197
- export function count(array)
1198
- {
1199
- let response = false;
1200
- if (array instanceof Array)
1201
- {
1202
- response = array?.length;
1203
- }
1204
- else
1205
- {
1206
- response = false;
1207
- }
1208
-
1209
- return response;
1210
- }
1211
-
1212
-
1213
- /**
1214
- *
1215
- * @param {string|number} value
1216
- * @param {array} array
1217
- * @param {boolean} strict
1218
- * @returns {boolean}
1219
- */
1220
- export function in_array(value, array, strict = false)
1221
- {
1222
- if (!is_array(array))
1223
- {
1224
- return false;
1225
- }
1226
- let response = false;
1227
-
1228
- if (strict)
1229
- {
1230
- response = array.find(element =>
1231
- {
1232
- return element === value;
1233
- });
1234
- }
1235
- else
1236
- {
1237
- response = array.find(element =>
1238
- {
1239
- return element == value;
1240
- });
1241
- }
1242
-
1243
- return Boolean(response);
1244
- }
1245
-
1246
- export function cls()
1247
- {
1248
- console.clear();
1249
- }
1250
- export class MockUserService
1251
- {
1252
- static mock_attributes = [ {
1253
- key : 'current_user_id',
1254
- value: 999999
1255
- }, {
1256
- key : 'user_name',
1257
- value: 'Local User Name'
1258
- }, {
1259
- key : 'current_team_id',
1260
- value: 99999999
1261
- }, {
1262
- key : 'current_team_slug',
1263
- value: 'mock_team'
1264
- }, {
1265
- key : 'user_teams',
1266
- value: [ 'mock_team' ]
1267
- }, {
1268
- key : 'roles',
1269
- value: [ 'guest' ]
1270
- }, {
1271
- key : 'current_language',
1272
- value: 'en'
1273
- }, {
1274
- key : 'csrf_token',
1275
- value: 'as89as98asd098asd98'
1276
- },
1277
- ];
1278
-
1279
- }
1280
-
1281
- /**
1282
- * Базовый абстрактный класс для всех типов
1283
- *
1284
- * @version v.0.2 (12/06/2025)
1285
- */
1286
- export class familyGeneralElement
1287
- {
1288
- primary_key = false;
1289
- create_scheme = false;
1290
- structure_scheme = false;
1291
- available_enum_values = false;
1292
- api_key = false;
1293
-
1294
-
1295
- /***********************************************/
1296
- /***********************************************/
1297
-
1298
- /***********************************************/
1299
-
1300
- /**
1301
- *
1302
- * @version v.0.1 (26/05/2024)
1303
- * @return {string|false}
1304
- */
1305
- get_primary_key()
1306
- {
1307
- if (this.primary_key)
1308
- {
1309
- return this.primary_key;
1310
- }
1311
- else
1312
- {
1313
- throw new Error('familyGeneralElement has no primary_key. Error #01-01');
1314
- }
1315
- }
1316
-
1317
-
1318
- /**
1319
- *
1320
- * @version v.0.1 (27/06/2024)
1321
- * @returns {array<familyGeneralElement>}
1322
- * @param {number} count
1323
- */
1324
- get_random_demo_data(count)
1325
- {
1326
- // @todo validations
1327
- let response = [];
1328
- for (let i = 0; i < count; i++)
1329
- {
1330
- response.push(this.get_demo_row());
1331
- }
1332
- // получаем массив сгенерированных элементов,
1333
- // в том числе - с незаполненными данными (корректная обработка)
1334
-
1335
- // контроль пересечения primary key
1336
- // прототип идеи
1337
- // @todo - дописать
1338
- return response;
1339
- }
1340
-
1341
- /**
1342
- *
1343
- * @returns {familyGeneralElement}
1344
- */
1345
- get_demo_row()
1346
- {
1347
- return this;
1348
- }
1349
-
1350
- /**
1351
- *
1352
- * @version v.0.2 (15/06/2024)
1353
- * @param {string} attribute
1354
- */
1355
- get_available_enum_values(attribute)
1356
- {
1357
- let response = false;
1358
- if (this.structure_scheme?.[ attribute ])
1359
- {
1360
- // выбрасывать исключения?
1361
- return false;
1362
- }
1363
-
1364
- let rules = this.get_attribute_structure_scheme(attribute);
1365
- if (!rules)
1366
- {
1367
- return false;
1368
- }
1369
- if (!in_array('enum', rules))
1370
- {
1371
- return false;
1372
- }
1373
-
1374
- if (this.available_enum_values?.[ attribute ])
1375
- {
1376
- response = this.available_enum_values?.[ attribute ];
1377
- }
1378
-
1379
- return response;
1380
- }
1381
-
1382
-
1383
- /**
1384
- *
1385
- * @param attribute
1386
- * @returns {array|false}
1387
- */
1388
- get_attribute_structure_scheme(attribute)
1389
- {
1390
- let response = false;
1391
- if (this.structure_scheme[ attribute ])
1392
- {
1393
- let scheme = clone_object(this.structure_scheme[ attribute ]);
1394
-
1395
- if (scheme)
1396
- {
1397
- scheme = scheme.split('|');
1398
- if (is_array(scheme))
1399
- {
1400
- response = [];
1401
- scheme.map((row) =>
1402
- {
1403
- response.push(row.trim());
1404
- });
1405
- }
1406
- }
1407
- }
1408
-
1409
- return response;
1410
- }
1411
-
1412
-
1413
- /**
1414
- *
1415
- * @version v.0.1 (26/05/2024)
1416
- */
1417
- get_data()
1418
- {
1419
- return this.get_pure_data();
1420
- }
1421
-
1422
-
1423
- /**
1424
- *
1425
- * @version v.0.1 (26/05/2024)
1426
- */
1427
- get_pure_data()
1428
- {
1429
- let response = false;
1430
- if (this.structure_scheme)
1431
- {
1432
- response = {};
1433
- _.mapObject(this.structure_scheme, (value, attribute) =>
1434
- {
1435
- if (this[ attribute ])
1436
- {
1437
- response [ attribute ] = this[ attribute ];
1438
- }
1439
- });
1440
- }
1441
-
1442
- return response;
1443
- }
1444
-
1445
-
1446
- /**
1447
- * @todo - сделать нормализация по create scheme с валидацией
1448
- *
1449
- * @version v.0.1 (26/01/2025)
1450
- *
1451
- * @param payload
1452
- * @returns {*}
1453
- */
1454
- normalize_payload(payload)
1455
- {
1456
-
1457
- return payload;
1458
- }
1459
-
1460
-
1461
- get_editable_attributes() {}
1462
-
1463
- is_editable_attribute(attribute) {}
1464
-
1465
-
1466
- /**
1467
- *
1468
- * @version v.0.1 (26/05/2024)
1469
- * @param {string} attribute_name
1470
- * @return {string}
1471
- */
1472
- get_attribute_name_translate(attribute_name)
1473
- {
1474
- return attribute_name;
1475
- }
1476
-
1477
- /***********************************************/
1478
-
1479
- /**
1480
- * Возвращаем "имя", то есть значение атрибута, который является именем
1481
- *
1482
- * @version v.0.1 (05/06/2025)
1483
- */
1484
- get_element_name()
1485
- {
1486
- alert('Error #205-001 Not implemented method');
1487
- }
1488
-
1489
- /***********************************************/
1490
- /***********************************************/
1491
-
1492
- /***********************************************/
1493
-
1494
- /**
1495
- *
1496
- * @version v.0.1 (26/05/2024)
1497
- * @param id
1498
- */
1499
- async find(id = false)
1500
- {
1501
- // или передаем ID, или используем вложенный
1502
- // возвращаем инстанс себя же
1503
- alert('Error #267-001 Not implemented method');
1504
- }
1505
-
1506
-
1507
- /**
1508
- *
1509
- * @param {familyGeneralElement|object} payload
1510
- *
1511
- * @param {typeFunctionCallback|object|false} callback
1512
- *
1513
- * @param {?function} callback.before
1514
- * @param {?function} callback.success
1515
- * @param {?function} callback.error
1516
- * @param {?function} callback.final
1517
- *
1518
- * @version v.2.0 (12/06/2025)
1519
- */
1520
- async create(payload, callback)
1521
- {
1522
- if (!this.api_key)
1523
- {
1524
- throw new Error('element has not api_key');
1525
- }
1526
-
1527
- if (typeof callback?.before === 'function')
1528
- {
1529
- callback?.before({ payload });
1530
- }
1531
-
1532
- payload = this.normalize_payload(payload);
1533
-
1534
-
1535
- /**
1536
- * {Api} ApiService
1537
- */
1538
- return ApiService[this.api_key].create(payload).then((response) =>
1539
- {
1540
- if (typeof callback?.success === 'function')
1541
- {
1542
- callback?.success({ response, payload })
1543
- }
1544
- }).catch((error) =>
1545
- {
1546
- echo({ error });
1547
- if (typeof callback?.error === 'function')
1548
- {
1549
- callback?.error({ error, payload })
1550
- }
1551
- }).finally((response) =>
1552
- {
1553
- if (typeof callback?.final === 'function')
1554
- {
1555
- callback?.final({ response, payload })
1556
- }
1557
- });
1558
- }
1559
-
1560
-
1561
-
1562
- /**
1563
- *
1564
- * @version v.2.0 (12/06/2025)
1565
- */
1566
- async update(payload, callback)
1567
- {
1568
- if (!this.api_key)
1569
- {
1570
- throw new Error('element has not api_key');
1571
- }
1572
-
1573
- if (typeof callback?.before === 'function')
1574
- {
1575
- callback?.before({ payload });
1576
- }
1577
-
1578
- payload = this.normalize_payload(payload);
1579
-
1580
-
1581
- /**
1582
- * {Api} ApiService
1583
- */
1584
- return ApiService[this.api_key].update(payload).then((response) =>
1585
- {
1586
- if (typeof callback?.success === 'function')
1587
- {
1588
- callback?.success({ response, payload })
1589
- }
1590
- }).catch((error) =>
1591
- {
1592
- echo({ error });
1593
- if (typeof callback?.error === 'function')
1594
- {
1595
- callback?.error({ error, payload })
1596
- }
1597
- }).finally((response) =>
1598
- {
1599
- if (typeof callback?.final === 'function')
1600
- {
1601
- callback?.final({ response, payload })
1602
- }
1603
- });
1604
- }
1605
-
1606
-
1607
-
1608
- /**
1609
- *
1610
- * @version v.2.0 (12/06/2025)
1611
- * @param key
1612
- * @param value
1613
- * @param callback
1614
- * @returns {Promise<>}
1615
- */
1616
- async update_property(key, value, callback)
1617
- {
1618
- if (!this.api_key)
1619
- {
1620
- throw new Error('element has not api_key');
1621
- }
1622
-
1623
- let payload = {
1624
- key : key,
1625
- value : value,
1626
- };
1627
- payload[this.get_primary_key()] = this[this.get_primary_key()];
1628
-
1629
- if (typeof callback?.before === 'function')
1630
- {
1631
- callback?.before({ payload });
1632
- }
1633
-
1634
- /**
1635
- * {Api} ApiService
1636
- */
1637
- return ApiService[this.api_key].update_property(payload).then((response) =>
1638
- {
1639
- if (typeof callback?.success === 'function')
1640
- {
1641
- callback?.success({ response, payload })
1642
- }
1643
- }).catch((error) =>
1644
- {
1645
- echo({ error });
1646
- if (typeof callback?.error === 'function')
1647
- {
1648
- callback?.error({ error, payload })
1649
- }
1650
- }).finally((response) =>
1651
- {
1652
- if (typeof callback?.final === 'function')
1653
- {
1654
- callback?.final({ response, payload })
1655
- }
1656
- });
1657
- }
1658
-
1659
-
1660
- /**
1661
- *
1662
- * @version v.0.1 (26/05/2024)
1663
- */
1664
- async update_properties()
1665
- {
1666
- alert('Error #272-001 Not implemented method');
1667
- }
1668
-
1669
-
1670
-
1671
- /**
1672
- *
1673
- * @version v.2.0 (12/06/2025)
1674
- */
1675
- async delete(element = false, callback = {})
1676
- {
1677
- if (!this.api_key)
1678
- {
1679
- throw new Error('element has not api_key');
1680
- }
1681
-
1682
- if (!element)
1683
- {
1684
- element = this;
1685
- }
1686
-
1687
- let payload = {};
1688
-
1689
- payload[this.get_primary_key()] = element[this.get_primary_key()];
1690
-
1691
- if (typeof callback?.before === 'function')
1692
- {
1693
- callback?.before({ payload });
1694
- }
1695
-
1696
- return ApiService[this.api_key].delete(payload).then((response) =>
1697
- {
1698
- if (typeof callback?.success === 'function')
1699
- {
1700
- callback?.success({ response, payload })
1701
- }
1702
- }).catch((error) =>
1703
- {
1704
- echo({ error });
1705
- if (typeof callback?.error === 'function')
1706
- {
1707
- callback?.error({ error, payload })
1708
- }
1709
- }).finally((response) =>
1710
- {
1711
- if (typeof callback?.final === 'function')
1712
- {
1713
- callback?.final({ response, payload })
1714
- }
1715
- });
1716
- }
1717
- }
1718
- /**
1719
- * Заготовка - логи действий
1720
- *
1721
- * @version v.0.1 (15/10/2024)
1722
- */
1723
- export class typeActionLog
1724
- {
1725
-
1726
- }
1727
-
1728
-
1729
- /**
1730
- *
1731
- * @version v.0.1 (23/06/2024)
1732
- */
1733
- export class typeFunctional extends familyGeneralElement
1734
- {
1735
- functional_id;
1736
- project_id; // foreign key
1737
- functional_group_id; // foreign key
1738
- team_id; // foreign key
1739
- functional_name;
1740
- functional_description;
1741
- reference_document_ids; // IDS документов по функционалу (к примеру confluence)
1742
- created_at;
1743
- updated_at;
1744
-
1745
- primary_key = 'functional_id';
1746
-
1747
- structure_scheme = {
1748
- functional_id : 'integer | require',
1749
- project_id : 'integer | require',
1750
- functional_group_id : 'integer | require',
1751
- team_id : 'integer | require',
1752
- functional_name : 'string | max:90 | require',
1753
- functional_description: 'string | max:2500 | optional',
1754
- reference_document_ids: 'array | reference | optional',
1755
- created_at : 'timestamp | require',
1756
- updated_at : 'timestamp | optional',
1757
- };
1758
-
1759
- available_enum_values = {
1760
- functional_status: [ 'не идей. нужен ли тут статус' ]
1761
- };
1762
-
1763
-
1764
- /**
1765
- *
1766
- * @param {object|false|undefined} data
1767
- */
1768
- constructor(data = false)
1769
- {
1770
- super();
1771
-
1772
- if (data && is_object(data))
1773
- {
1774
- _.mapObject(data, (value, key) =>
1775
- {
1776
- if (this.hasOwnProperty(key))
1777
- {
1778
- this [ key ] = value;
1779
- }
1780
- });
1781
- }
1782
-
1783
- return this;
1784
- }
1785
-
1786
-
1787
- /******************************************************************************************/
1788
- /*********************************** general **********************************************/
1789
-
1790
- /******************************************************************************************/
1791
-
1792
- /**
1793
- *
1794
- * @version v.0.1 (07/07/2024)
1795
- */
1796
- async create()
1797
- {}
1798
-
1799
-
1800
- /**
1801
- *
1802
- * @version v.0.1 (07/07/2024)
1803
- */
1804
- async update()
1805
- {
1806
-
1807
- }
1808
-
1809
-
1810
- /**
1811
- *
1812
- * @version v.0.1 (07/07/2024)
1813
- */
1814
- async delete()
1815
- {
1816
-
1817
- }
1818
-
1819
-
1820
- }
1821
-
1822
-
1823
- /**
1824
- * @version v.0.2 (25/01/2025)
1825
- */
1826
- export class typeFunctionalGroup extends familyGeneralElement
1827
- {
1828
- functional_group_id;
1829
- project_id; // foreign key
1830
- team_id; // foreign key
1831
- parent_id; // для организации вложенности
1832
- functional_group_name;
1833
- functional_group_description;
1834
- //functional_group_status; // enum (active + archive ??)
1835
- created_at;
1836
- updated_at;
1837
-
1838
- primary_key = 'functional_group_id';
1839
-
1840
- structure_scheme = {
1841
- functional_group_id : 'integer | require',
1842
- functional_group_name : 'string | max:90 | require',
1843
- functional_group_description: 'string | max:250 | optional',
1844
- project_id : 'integer | require',
1845
- team_id : 'integer | require',
1846
- parent_id : 'integer | optional',
1847
- functional_group_status : 'integer | enum | require',
1848
- created_at : 'timestamp | require',
1849
- updated_at : 'timestamp | optional',
1850
- };
1851
-
1852
- available_enum_values = {
1853
- functional_group_status: [ 'не идей. нужен ли тут статус' ]
1854
- };
1855
-
1856
-
1857
- /**
1858
- *
1859
- * @param {object|false|undefined} data
1860
- */
1861
- constructor(data = false)
1862
- {
1863
- super();
1864
-
1865
- if (data && is_object(data))
1866
- {
1867
- _.mapObject(data, (value, key) =>
1868
- {
1869
- if (this.hasOwnProperty(key))
1870
- {
1871
- this [ key ] = value;
1872
- }
1873
- });
1874
- }
1875
-
1876
- return this;
1877
- }
1878
-
1879
-
1880
- /******************************************************************************************/
1881
- /*********************************** general **********************************************/
1882
-
1883
- /******************************************************************************************/
1884
-
1885
- /**
1886
- *
1887
- * @version v.0.1 (07/07/2024)
1888
- */
1889
- async create()
1890
- {}
1891
-
1892
-
1893
- /**
1894
- *
1895
- * @version v.0.1 (07/07/2024)
1896
- */
1897
- async update()
1898
- {
1899
-
1900
- }
1901
-
1902
-
1903
- /**
1904
- *
1905
- * @version v.0.1 (07/07/2024)
1906
- */
1907
- async delete()
1908
- {
1909
-
1910
- }
1911
-
1912
-
1913
- }
1914
-
1915
- /**
1916
- *
1917
- * @version v.0.2 (15/06/2024)
1918
- */
1919
- export class typeMilestone extends familyGeneralElement
1920
- {
1921
- milestone_id; // primary AI
1922
- milestone_name;
1923
- milestone_description;
1924
- milestone_status; // enum
1925
- milestone_start_date;
1926
- milestone_end_date;
1927
- team_id; // foreign key
1928
- project_id; // foreign key
1929
-
1930
-
1931
- primary_key = 'milestone_id';
1932
-
1933
- structure_scheme = {
1934
- milestone_id : 'integer | require',
1935
- milestone_name : 'string | require',
1936
- milestone_description: 'string | optional',
1937
- milestone_status : 'string | enum | require',
1938
- company_id : 'integer | require',
1939
- milestone_start_date : 'date | require',
1940
- milestone_end_date : 'date | optional',
1941
- project_id : 'integer | require',
1942
- };
1943
-
1944
- available_enum_values = {
1945
- milestone_status: [ 'ACTUAL', 'COMPLETED', 'PLANNED' ]
1946
- };
1947
-
1948
- /**
1949
- *
1950
- * @param {object|false|undefined} data
1951
- */
1952
- constructor(data = false)
1953
- {
1954
- super();
1955
-
1956
- if (data && is_object(data))
1957
- {
1958
- _.mapObject(data, (value, key) =>
1959
- {
1960
- if (this.hasOwnProperty(key))
1961
- {
1962
- this [ key ] = value;
1963
- }
1964
- });
1965
- }
1966
-
1967
- return this;
1968
- }
1969
-
1970
-
1971
- /******************************************************************************************/
1972
- /*********************************** general **********************************************/
1973
-
1974
- /******************************************************************************************/
1975
-
1976
- /**
1977
- *
1978
- * @version v.0.1 (07/07/2024)
1979
- */
1980
- async create()
1981
- {}
1982
-
1983
-
1984
- /**
1985
- *
1986
- * @version v.0.1 (07/07/2024)
1987
- */
1988
- async update()
1989
- {
1990
-
1991
- }
1992
-
1993
-
1994
- /**
1995
- *
1996
- * @version v.0.1 (07/07/2024)
1997
- */
1998
- async delete()
1999
- {
2000
-
2001
- }
2002
-
2003
-
2004
- }
2005
-
2006
-
2007
- /**
2008
- *
2009
- * @version v.0.2 (15/06/2024)
2010
- */
2011
- export class typeProject extends familyGeneralElement
2012
- {
2013
- project_id; // primary
2014
- project_name;
2015
- project_description; // some comment
2016
- project_status; // enum
2017
- team_id; // foreign key + owner
2018
- reference_document_ids; // IDS документов по функционалу (к примеру confluence)
2019
- // хосты/домены будут отдельно храниться, их может быть множество
2020
-
2021
- primary_key = 'project_id';
2022
- api_key = 'project';
2023
-
2024
- structure_scheme = {
2025
- project_id : 'integer | require',
2026
- project_name : 'string | require',
2027
- project_description : 'string | optional',
2028
- project_status : 'string | enum | require',
2029
- company_id : 'integer | require',
2030
- reference_document_ids: 'array | reference | optional',
2031
- };
2032
-
2033
- available_enum_values = {
2034
- project_status: [ 'OPEN', 'CLOSED', 'PLANNED' ]
2035
- };
2036
-
2037
-
2038
- /**
2039
- *
2040
- * @param {object|false|undefined} data
2041
- */
2042
- constructor(data = false)
2043
- {
2044
- super();
2045
-
2046
- if (data && is_object(data))
2047
- {
2048
- _.mapObject(data, (value, key) =>
2049
- {
2050
- if (this.hasOwnProperty(key))
2051
- {
2052
- this [ key ] = value;
2053
- }
2054
- });
2055
- }
2056
-
2057
- return this;
2058
- }
2059
-
2060
-
2061
- /**
2062
- *
2063
- * @version v.0.1 (02/07/2024)
2064
- * @returns {array<typeProject>}
2065
- * @param {number} count
2066
- */
2067
- get_random_demo_data(count)
2068
- {
2069
- // @todo validations
2070
- let response = [];
2071
-
2072
- for (let i = 0; i < count; i++)
2073
- {
2074
- response.push(new MockDataTypeProject());
2075
- }
2076
-
2077
-
2078
- return response;
2079
- }
2080
-
2081
-
2082
- /******************************************************************************************/
2083
- /******************************************************************************************/
2084
-
2085
- /******************************************************************************************/
2086
-
2087
-
2088
- /**
2089
- *
2090
- * @version v.0.1 (05/06/2025)
2091
- *
2092
- * @returns {string}
2093
- */
2094
- get_element_name()
2095
- {
2096
- return this.project_name;
2097
- }
2098
-
2099
-
2100
- /******************************************************************************************/
2101
- /**************************** работа с участниками проекта ********************************/
2102
- /******************************************************************************************/
2103
-
2104
- // member = user + role
2105
-
2106
- member_add() {}
2107
-
2108
- member_update() {}
2109
-
2110
- member_delete() {}
2111
-
2112
- member_get() {}
2113
-
2114
-
2115
- }
2116
-
2117
- /**
2118
- * (идея) - у проекта должна быть тестовая документация
2119
- *
2120
- * @see https://vladislaveremeev.gitbook.io/qa_bible/testovaya-dokumentaciya-i-artefakty-test-deliverablestest-artifacts/vidy-testovoi-dokumentacii
2121
- *
2122
- * @version v.0.2 (07/07/2024)
2123
- */
2124
- export class typeProjectDocument extends familyGeneralElement
2125
- {
2126
- project_document_id;
2127
- project_id;
2128
- project_document_type;
2129
- // где и как храним файлы?
2130
- // nextcloud integration?
2131
-
2132
-
2133
-
2134
- available_enum_values = {
2135
- project_document_type: [ 'QUALITY_POLICY', 'TEST_POLICY', 'PROJECT_DESCRIPTION', 'TEST_PLAN', 'DOCUMENT' ],
2136
- };
2137
-
2138
-
2139
- /**
2140
- *
2141
- * @param {object|false|undefined} data
2142
- */
2143
- constructor(data = false)
2144
- {
2145
- super();
2146
-
2147
- if (data && is_object(data))
2148
- {
2149
- _.mapObject(data, (value, key) =>
2150
- {
2151
- if (this.hasOwnProperty(key))
2152
- {
2153
- this [ key ] = value;
2154
- }
2155
- });
2156
- }
2157
-
2158
- return this;
2159
- }
2160
-
2161
-
2162
- /******************************************************************************************/
2163
- /*********************************** general **********************************************/
2164
-
2165
- /******************************************************************************************/
2166
-
2167
- /**
2168
- *
2169
- * @version v.0.1 (07/07/2024)
2170
- */
2171
- async create()
2172
- {}
2173
-
2174
-
2175
- /**
2176
- *
2177
- * @version v.0.1 (07/07/2024)
2178
- */
2179
- async update()
2180
- {
2181
-
2182
- }
2183
-
2184
-
2185
- /**
2186
- *
2187
- * @version v.0.1 (07/07/2024)
2188
- */
2189
- async delete()
2190
- {
2191
-
2192
- }
2193
- }
2194
-
2195
- /**
2196
- * Тестовые аккаунты
2197
- *
2198
- * У каждого проекта свои коллекции
2199
- * (идея)
2200
- *
2201
- * @version v.0.1 (30/06/2024)
2202
- */
2203
- export class typeProjectTestAccount extends familyGeneralElement
2204
- {
2205
- test_account_id;
2206
- project_id;
2207
- site;
2208
- authentication_type;
2209
- login;
2210
- password; // как будем хранить?
2211
- comment;
2212
-
2213
- primary_key = 'test_account_id';
2214
-
2215
- structure_scheme = {
2216
- test_account_id : 'integer | require',
2217
- project_id : 'integer | require',
2218
- authentication_type: 'enum | require',
2219
- site : 'string | require',
2220
- login : 'string | require',
2221
- password : 'string | optional',
2222
- comment : 'string | optional',
2223
- };
2224
-
2225
- available_enum_values = {
2226
- authentication_type: [ 'FORMS' ] // другие пока нет автоматизации не особо нужны
2227
- };
2228
-
2229
- /**
2230
- *
2231
- * @param {object|false|undefined} data
2232
- */
2233
- constructor(data = false)
2234
- {
2235
- super();
2236
-
2237
- if (data && is_object(data))
2238
- {
2239
- _.mapObject(data, (value, key) =>
2240
- {
2241
- if (this.hasOwnProperty(key))
2242
- {
2243
- this [ key ] = value;
2244
- }
2245
- });
2246
- }
2247
-
2248
- return this;
2249
- }
2250
- }
2251
-
2252
- /**
2253
- * Тестовые данные
2254
- * Какая-то коллекция, созданная для тестирования и ввода
2255
- *
2256
- * У каждого проекта свои коллекции
2257
- *
2258
- * (идея)
2259
- * @version v.0.1 (30/06/2024)
2260
- */
2261
- export class typeProjectTestData extends familyGeneralElement
2262
- {
2263
- // как храним? json или какие-то структуры? [key->value] ?
2264
- test_data_id;
2265
- project_id;
2266
-
2267
-
2268
- primary_key = 'test_data_id';
2269
-
2270
- /**
2271
- *
2272
- * @param {object|false|undefined} data
2273
- */
2274
- constructor(data = false)
2275
- {
2276
- super();
2277
-
2278
- if (data && is_object(data))
2279
- {
2280
- _.mapObject(data, (value, key) =>
2281
- {
2282
- if (this.hasOwnProperty(key))
2283
- {
2284
- this [ key ] = value;
2285
- }
2286
- });
2287
- }
2288
-
2289
- return this;
2290
- }
2291
- }
2292
-
2293
- /**
2294
- * Роли в проекте
2295
- * @version v.0.1 (07/07/2024)
2296
- */
2297
- export class typeProjectUserRole extends familyGeneralElement
2298
- {
2299
- // строго определенный список
2300
- // без возможности создания иных
2301
- // если роль не указана - то ADMINISTRATOR
2302
-
2303
- role_slug;
2304
- role_description;
2305
- project_id;
2306
- user_id;
2307
-
2308
- primary_key = 'role_slug';
2309
-
2310
- structure_scheme = {
2311
- role_slug : 'string | require',
2312
- role_description: 'string | optional',
2313
- project_id : 'integer | require',
2314
- user_id : 'integer | require',
2315
- };
2316
-
2317
- available_enum_values = {
2318
- role_slug: [ 'ROOT', 'ADMINISTRATOR', 'LEAD', 'QA_ENGINEER' ]
2319
- // ?? Системные администраторы, Разработчики, Тестировщики
2320
- };
2321
-
2322
-
2323
- /**
2324
- *
2325
- * @param {object|false|undefined} data
2326
- */
2327
- constructor(data = false)
2328
- {
2329
- super();
2330
-
2331
- if (data && is_object(data))
2332
- {
2333
- _.mapObject(data, (value, key) =>
2334
- {
2335
- if (this.hasOwnProperty(key))
2336
- {
2337
- this [ key ] = value;
2338
- }
2339
- });
2340
- }
2341
-
2342
- return this;
2343
- }
2344
- }
2345
-
2346
-
2347
- /**
2348
- * @version v.2.0 (07/07/2024)
2349
- */
2350
- export class typeTask extends familyGeneralElement
2351
- {
2352
- task_id;
2353
- team_id; // foreign key
2354
- task_performer_id; // foreign key // @todo переименовать с общепринятой практикой
2355
- task_initiator_id; // foreign key // @todo переименовать с общепринятой практикой
2356
- task_type; // enum => сделать тест, выполнить тест, итд (!не дублирует предмет задания - тут тип + действие)
2357
- task_status; // enum
2358
- project_id; // foreign key (денормализация) (а надо ли)
2359
- task_subject_element_type; // предмет задания
2360
- task_subject_id; // ID предмета задания (изначально его может не быть)
2361
-
2362
-
2363
- primary_key = 'task_id';
2364
-
2365
- structure_scheme = {
2366
- task_id : 'integer | require',
2367
- team_id : 'integer | require',
2368
- task_performer_id : 'integer | require',
2369
- task_initiator_id : 'integer | require',
2370
- task_type : 'string | enum | require',
2371
- task_status : 'string | enum | require',
2372
- project_id : 'integer | require',
2373
- task_subject_element_type: 'string | enum | require',
2374
- task_subject_id : 'integer | optional',
2375
- };
2376
-
2377
- available_enum_values = {
2378
- task_status: [ 'OPEN', 'IN_PROGRESS', 'DONE', 'CANCELLED' ],
2379
- // тут будет много, все надо перечислить, чтобы просто по каждой описать свой код
2380
- // и не все комбинации action + element доступны и могут существовать
2381
- task_type : [
2382
- 'CREATE_PROJECT_DOCUMENT',
2383
- 'CREATE_FUNCTIONAL',
2384
- 'CREATE_TESTCASE',
2385
- 'CREATE_TEST_RUN',
2386
- 'RUN_TEST_RUN'
2387
- ],
2388
- task_subject_element_type: [
2389
- 'PROJECT',
2390
- 'PROJECT_DOCUMENT',
2391
- 'TEST_SUITE',
2392
- 'TEST_CASE',
2393
- 'TEST_RUN',
2394
- 'TEST_RESULT',
2395
- ],
2396
- };
2397
-
2398
-
2399
- /**
2400
- *
2401
- * @param {object|false|undefined} data
2402
- */
2403
- constructor(data = false)
2404
- {
2405
- super();
2406
-
2407
- if (data && is_object(data))
2408
- {
2409
- _.mapObject(data, (value, key) =>
2410
- {
2411
- if (this.hasOwnProperty(key))
2412
- {
2413
- this [ key ] = value;
2414
- }
2415
- });
2416
- }
2417
-
2418
- return this;
2419
- }
2420
- }
2421
-
2422
-
2423
- /**
2424
- * @version v.0.1 (23/06/2024)
2425
- */
2426
- export class typeTeam extends familyGeneralElement
2427
- {
2428
- team_id; //
2429
- team_status; // enum
2430
- team_type; // enum
2431
- team_country_code; // (закон о перс данных и иные) как минимум статистика
2432
- team_name;
2433
- _team_price_id // foreign key (тариф)
2434
- team_root_user_id; // foreign key
2435
- created_at;
2436
- updated_at;
2437
- // тут где-то могут быть тарифы
2438
-
2439
-
2440
- primary_key = 'team_id';
2441
-
2442
- structure_scheme = {
2443
- team_id : 'integer | require',
2444
- team_status : 'string | enum | require',
2445
- team_type : 'string | enum | require',
2446
- team_country_code: 'string | country_code | require',
2447
- team_name : 'string | require',
2448
- team_price_id : 'integer | require',
2449
- team_root_user_id: 'integer | require',
2450
- created_at : 'timestamp | require',
2451
- updated_at : 'timestamp | optional',
2452
- };
2453
-
2454
-
2455
- available_enum_values = {
2456
- team_status: [ 'PENDING', 'APPROVED', 'BANNED', 'FROZEN', 'TRIAL' ],
2457
- team_type : [ 'PERSONAL', 'ORGANIZATION', 'SCHOOL' ],
2458
- };
2459
-
2460
-
2461
- /**
2462
- *
2463
- * @param {object|false|undefined} data
2464
- */
2465
- constructor(data = false)
2466
- {
2467
- super();
2468
-
2469
- if (data && is_object(data))
2470
- {
2471
- _.mapObject(data, (value, key) =>
2472
- {
2473
- if (this.hasOwnProperty(key))
2474
- {
2475
- this [ key ] = value;
2476
- }
2477
- });
2478
- }
2479
-
2480
- return this;
2481
- }
2482
-
2483
-
2484
- /******************************************************************************************/
2485
- /*********************************** general **********************************************/
2486
-
2487
- /******************************************************************************************/
2488
-
2489
- /**
2490
- *
2491
- * @version v.0.1 (07/07/2024)
2492
- */
2493
- async create()
2494
- {}
2495
-
2496
-
2497
- /******************************************************************************************/
2498
- /*********************** работа с администраторами компании *******************************/
2499
-
2500
- /******************************************************************************************/
2501
-
2502
- adminstator_add() {}
2503
-
2504
- adminstator_update() {}
2505
-
2506
- adminstator_delete() {}
2507
-
2508
- adminstators_get() {}
2509
-
2510
-
2511
- /******************************************************************************************/
2512
- /************************* работа с сотрудниками компании *********************************/
2513
-
2514
- /******************************************************************************************/
2515
-
2516
- user_add() {}
2517
-
2518
- user_update() {}
2519
-
2520
- user_delete() {}
2521
-
2522
- users_get() {}
2523
- }
2524
-
2525
-
2526
- /**
2527
- * @version v.0.2 (11/11/2024)
2528
- */
2529
- export class typeTeamMember extends familyGeneralElement
2530
- {
2531
- team_member_id;
2532
- team_id;
2533
- user_id;
2534
- team_member_status;
2535
- member_role;
2536
- created_at;
2537
- updated_at;
2538
-
2539
-
2540
- primary_key = 'team_member_id';
2541
-
2542
- structure_scheme = {
2543
- team_member_id : 'integer | require',
2544
- team_id : 'integer | require',
2545
- user_id : 'integer | require',
2546
- team_member_status: 'string | enum | require',
2547
- member_role: 'string | enum | require',
2548
- created_at : 'timestamp | require',
2549
- updated_at : 'timestamp | optional',
2550
- };
2551
-
2552
- available_enum_values = {
2553
- team_member_status: [ 'PENDING', 'ACCEPTED', 'BANNED', 'REJECTED' ],
2554
- member_role : [ 'ROOT', 'ADMINISTRATOR', 'MEMBER' ]
2555
- };
2556
-
2557
-
2558
- /**
2559
- *
2560
- * @param {object|false|undefined} data
2561
- */
2562
- constructor(data = false)
2563
- {
2564
- super();
2565
-
2566
- if (data && is_object(data))
2567
- {
2568
- _.mapObject(data, (value, key) =>
2569
- {
2570
- if (this.hasOwnProperty(key))
2571
- {
2572
- this [ key ] = value;
2573
- }
2574
- });
2575
- }
2576
-
2577
- return this;
2578
- }
2579
- }
2580
-
2581
- /**
2582
- * Роль пользователя в команде
2583
- * Должно стать часть team management
2584
- *
2585
- * Один пользователь может иметь много ролей (разработчик, тестировщик, ...)
2586
- *
2587
- * @version v.0.1 (07/07/2024)
2588
- */
2589
- export class typeTeamUserRole extends familyGeneralElement
2590
- {
2591
- // @todo - все не актуально, поменять
2592
- role_slug;
2593
- role_description;
2594
- team_id;
2595
- user_id;
2596
-
2597
- primary_key = 'role_slug';
2598
-
2599
- structure_scheme = {
2600
- role_slug : 'string | require',
2601
- role_description: 'string | optional',
2602
- team_id : 'integer | require',
2603
- user_id : 'integer | require',
2604
- };
2605
-
2606
- /*available_enum_values = {
2607
- // эти роли вынесены
2608
- role_slug: [ 'ROOT', 'ADMINISTRATOR', 'MEMBER' ]
2609
- };
2610
- */
2611
-
2612
- /**
2613
- *
2614
- * @param {object|false|undefined} data
2615
- */
2616
- constructor(data = false)
2617
- {
2618
- super();
2619
-
2620
- if (data && is_object(data))
2621
- {
2622
- _.mapObject(data, (value, key) =>
2623
- {
2624
- if (this.hasOwnProperty(key))
2625
- {
2626
- this [ key ] = value;
2627
- }
2628
- });
2629
- }
2630
-
2631
- return this;
2632
- }
2633
- }
2634
-
2635
-
2636
- /**
2637
- *
2638
- * @version v.0.2 (10/12/2024)
2639
- */
2640
- export class typeTestCase extends familyGeneralElement
2641
- {
2642
- test_case_id;
2643
- test_suite_id; // foreign key
2644
- project_id; // foreign key
2645
- team_id; // foreign key // secure - access
2646
- functional_id; // foreign key
2647
- test_case_title; // text 90
2648
- test_case_preconditions; // text (взято у рельсов)
2649
- test_case_mission; // text (взято у рельсов)
2650
- test_case_goals; // text (взято у рельсов)
2651
- test_case_description; // text 250
2652
- test_case_time_to_execute; // время выполнения (в секундах) (оценочное) (для планирования работ)
2653
- test_case_complexity; // enum (для планирования работ)
2654
- test_case_importance; // enum (для планирования работ)
2655
- test_case_steps; // pseudo // foreign key - relations
2656
- test_case_presteps; // pseudo // foreign key - relations
2657
- _attachments; // typeAttachments - <relations>
2658
- preconditions; // text
2659
- excepted_result; // text // ?? <goals>
2660
- created_at;
2661
- updated_at;
2662
-
2663
-
2664
- primary_key = 'test_case_id';
2665
- api_key = 'test_case';
2666
-
2667
- // @todo - довнести
2668
- structure_scheme = {
2669
- test_case_id : 'integer | require',
2670
- test_suite_id : 'integer | require',
2671
- project_id : 'integer | require',
2672
- team_id : 'integer | require',
2673
- functional_id : 'integer | optional',
2674
- test_case_title : 'string | require',
2675
- test_case_descriptions : 'string | require',
2676
- test_case_time_to_execute: 'integer | optional',
2677
- test_case_complexity : 'string | enum | optional',
2678
- test_case_importance : 'string | enum | optional',
2679
- created_at : 'timestamp | require',
2680
- updated_at : 'timestamp | optional',
2681
- };
2682
-
2683
- available_enum_values = {
2684
- test_case_complexity: [ 'LOW', 'NORMAL', 'HIGH' ],
2685
- test_case_importance: [ 'LOW', 'NORMAL', 'HIGH' ],
2686
- };
2687
-
2688
-
2689
- /**
2690
- *
2691
- * @param {object|false|undefined} data
2692
- */
2693
- constructor(data = false)
2694
- {
2695
- super();
2696
-
2697
- if (data && is_object(data))
2698
- {
2699
- _.mapObject(data, (value, key) =>
2700
- {
2701
- if (this.hasOwnProperty(key))
2702
- {
2703
- this [ key ] = value;
2704
- }
2705
- });
2706
- }
2707
-
2708
- return this;
2709
- }
2710
-
2711
-
2712
- /******************************************************************************************/
2713
- /*********************************** general **********************************************/
2714
-
2715
- /******************************************************************************************/
2716
-
2717
- /**
2718
- *
2719
- * @version v.0.1 (05/06/2025)
2720
- *
2721
- * @returns {string}
2722
- */
2723
- get_element_name()
2724
- {
2725
- return this.test_case_title;
2726
- }
2727
-
2728
-
2729
- }
2730
-
2731
-
2732
- /**
2733
- *
2734
- * @version v.0.1 (26/05/2024)
2735
- */
2736
- export class typeTestCaseStep extends familyGeneralElement
2737
- {
2738
- test_case_step_id;
2739
- test_case_step_type;
2740
- team_id; // foreign key
2741
- test_case_id; // relations
2742
- step_text;
2743
-
2744
- primary_key = 'test_case_step_id';
2745
-
2746
- available_enum_values = {
2747
- test_case_step_type: [ 'TEST_CASE_STEP', 'TEST_CASE_PRESTEP' ],
2748
- };
2749
- }
2750
-
2751
-
2752
- /**
2753
- * Нужен ли этот тип?
2754
- *
2755
- * @version v.0.1 (26/05/2024)
2756
- */
2757
- export class typeTestPlan extends familyGeneralElement
2758
- {
2759
-
2760
-
2761
- /**
2762
- *
2763
- * @param {object|false|undefined} data
2764
- */
2765
- constructor(data = false)
2766
- {
2767
- super();
2768
-
2769
- if (data && is_object(data))
2770
- {
2771
- _.mapObject(data, (value, key) =>
2772
- {
2773
- if (this.hasOwnProperty(key))
2774
- {
2775
- this [ key ] = value;
2776
- }
2777
- });
2778
- }
2779
-
2780
- return this;
2781
- }
2782
- }
2783
-
2784
- /**
2785
- * Коллекция тестов для работы, она же parent для typeTestRunResult
2786
- *
2787
- * Содержит ссылки на коллекцию тест кейсов
2788
- *
2789
- * @version v.0.2 (21/01/2025)
2790
- */
2791
- export class typeTestRun extends familyGeneralElement
2792
- {
2793
- test_run_id;
2794
- test_run_name;
2795
- test_run_description;
2796
- milestone_id; /// ??
2797
- assigned_to;
2798
- test_case_ids; // массив тестов на запуск
2799
- test_run_status;
2800
- test_case_summary_statistic; // массив [key->value] по статусам вложенных тест-кейсов для визуализации
2801
- // typeTestRunResult.test_result_status : 'PASSED', 'FAILED', 'SKIPPED', 'BLOCKED', 'RETEST'
2802
-
2803
-
2804
- created_at;
2805
- updated_at;
2806
- completed_at;
2807
-
2808
- // логи запуска, окончания - отдельно
2809
- primary_key = 'test_run_id';
2810
-
2811
- available_enum_values = {
2812
- test_run_status: [ 'PENDING', 'IN_PROGRESS', 'COMPLETED', 'CLOSED' ],
2813
- };
2814
-
2815
- /**
2816
- *
2817
- * @param {object|false|undefined} data
2818
- */
2819
- constructor(data = false)
2820
- {
2821
- super();
2822
-
2823
- if (data && is_object(data))
2824
- {
2825
- _.mapObject(data, (value, key) =>
2826
- {
2827
- if (this.hasOwnProperty(key))
2828
- {
2829
- this [ key ] = value;
2830
- }
2831
- });
2832
- }
2833
-
2834
- return this;
2835
- }
2836
- }
2837
-
2838
- /**
2839
- * 1 результат по каждому тест кейсу
2840
- *
2841
- * отчет смотрим по testRuns
2842
- *
2843
- * @version v.0.4 (10/12/2024)
2844
- */
2845
- export class typeTestRunResult extends familyGeneralElement
2846
- {
2847
- test_run_result_id;
2848
- test_case_id;
2849
- test_run_id;
2850
- test_result_status;
2851
- task_id; // надо ли?
2852
- project_id;
2853
- functional_id; // надо ли?
2854
- milestone_id;
2855
- elapsed_time; // фактическое время выполнения
2856
- reference_defects_ids; // list of IDs in user bug tracker / include sentry ids
2857
-
2858
- created_at;
2859
- updated_at;
2860
- completed_at;
2861
-
2862
-
2863
- // тут нужен ещё контекст выполнения (банально список браузеров)
2864
-
2865
- primary_key = 'test_run_result_id';
2866
-
2867
- structure_scheme = {
2868
- test_result_id : 'integer | require',
2869
- test_case_id : 'integer | require',
2870
- test_run_id : 'integer | require',
2871
- test_result_status : 'string | enum | require',
2872
- task_id : 'integer | require',
2873
- project_id : 'integer | require',
2874
- functional_id : 'integer | optional',
2875
- milestone_id : 'integer | optional',
2876
- test_run_result_to_execute: 'time | optional',
2877
- reference_defects_ids : 'array | reference | optional',
2878
- };
2879
-
2880
- available_enum_values = {
2881
- test_result_status: [ 'PASSED', 'FAILED', 'SKIPPED', 'BLOCKED', 'RETEST' ]
2882
- };
2883
-
2884
-
2885
- /**
2886
- *
2887
- * @param {object|false|undefined} data
2888
- */
2889
- constructor(data = false)
2890
- {
2891
- super();
2892
-
2893
- if (data && is_object(data))
2894
- {
2895
- _.mapObject(data, (value, key) =>
2896
- {
2897
- if (this.hasOwnProperty(key))
2898
- {
2899
- this [ key ] = value;
2900
- }
2901
- });
2902
- }
2903
-
2904
- return this;
2905
- }
2906
- }
2907
-
2908
- /**
2909
- * Структурная коллекция тестов
2910
- *
2911
- * @version v.0.1 (23/06/2024)
2912
- */
2913
- export class typeTestSuite extends familyGeneralElement
2914
- {
2915
- test_suite_id;
2916
- project_id;
2917
- functional_id;
2918
- test_suite_name;
2919
- test_suite_description;
2920
- team_id;
2921
-
2922
- primary_key = 'test_suite_id';
2923
- api_key = 'test_suite';
2924
-
2925
- structure_scheme = {
2926
- test_suite_id : 'integer | require',
2927
- project_id : 'integer | require',
2928
- functional_id : 'integer | optional',
2929
- test_suite_name : 'string | protected | require',
2930
- test_suite_description: 'string | require',
2931
- team_id : 'integer | require',
2932
- };
2933
-
2934
-
2935
- /**
2936
- *
2937
- * @param {object|false|undefined} data
2938
- */
2939
- constructor(data = false)
2940
- {
2941
- super();
2942
-
2943
- if (data && is_object(data))
2944
- {
2945
- _.mapObject(data, (value, key) =>
2946
- {
2947
- if (this.hasOwnProperty(key))
2948
- {
2949
- this [ key ] = value;
2950
- }
2951
- });
2952
- }
2953
-
2954
- return this;
2955
- }
2956
-
2957
-
2958
-
2959
- /******************************************************************************************/
2960
- /******************************************************************************************/
2961
- /******************************************************************************************/
2962
-
2963
-
2964
-
2965
- /**
2966
- *
2967
- * @version v.0.1 (05/06/2025)
2968
- *
2969
- * @returns {string}
2970
- */
2971
- get_element_name()
2972
- {
2973
- return this.test_suite_name;
2974
- }
2975
-
2976
- }
2977
-
2978
-
2979
- /**
2980
- * @version v.0.1 (23/06/2024)
2981
- */
2982
- export class typeUser extends familyGeneralElement
2983
- {
2984
- user_id;
2985
- country;
2986
- user_name;
2987
- user_password; // не доступно на фронте
2988
- user_status;
2989
- user_email;
2990
- user_phone;
2991
-
2992
- primary_key = 'user_id';
2993
-
2994
- structure_scheme = {
2995
- user_id : 'integer | require',
2996
- country : 'string | enum | require',
2997
- user_name : 'string | require',
2998
- user_password : 'string | protected | require',
2999
- user_status : 'string | enum| require',
3000
- user_email : 'string | email | require',
3001
- user_phone_number: 'string | phone_number | optional',
3002
- };
3003
-
3004
- available_enum_values = {
3005
- user_status: [ 'PENDING', 'APPROVED', 'BANNED', 'FROZEN', 'BLOCKED' ]
3006
- };
3007
-
3008
-
3009
- /**
3010
- *
3011
- * @param {object|false|undefined} data
3012
- */
3013
- constructor(data = false)
3014
- {
3015
- super();
3016
-
3017
- if (data && is_object(data))
3018
- {
3019
- _.mapObject(data, (value, key) =>
3020
- {
3021
- if (this.hasOwnProperty(key))
3022
- {
3023
- this [ key ] = value;
3024
- }
3025
- });
3026
- }
3027
-
3028
- return this;
3029
- }
3030
- }
3031
- /**
3032
- * базовый тип для всех служебных типов
3033
- * @version v.0.1 (26/05/2024)
3034
- */
3035
- export class familyService
3036
- {
3037
- //
3038
- }
3039
-
3040
- /**
3041
- * Общее конфигурирование приложений
3042
- *
3043
- * @version v.0.1 (26/04/2025)
3044
- */
3045
- export class typeAppConfiguration extends familyService
3046
- {
3047
- /**
3048
- *
3049
- * @type {false|array<'PROTOTYPE','DEVELOPMENT','DEPRECATED','TESTING','PRODUCTION'>}
3050
- */
3051
- app_stage = false;
3052
-
3053
- /**
3054
- *
3055
- * @type {false|number}
3056
- */
3057
- app_id = false;
3058
-
3059
-
3060
- constructor(data = false)
3061
- {
3062
- super();
3063
- if (data && typeof data === 'object')
3064
- {
3065
- _.mapObject(data, (value, key) =>
3066
- {
3067
- if (this.hasOwnProperty(key))
3068
- {
3069
- this [ key ] = value;
3070
- }
3071
- });
3072
- }
3073
-
3074
- return this;
3075
- }
3076
- }
3077
-
3078
- /**
3079
- *
3080
- * @version v.1.0 (25/05/2025)
3081
- */
3082
- export class typeFilter extends familyService
3083
- {
3084
- object = {
3085
- attribute : false,
3086
- };
3087
- operator;
3088
- value;
3089
-
3090
- /**
3091
- *
3092
- * @version v.1.0 (25/05/2025)
3093
- * @param {any} data
3094
- * @param {boolean} normalize
3095
- * @return {typeFilter}
3096
- */
3097
- constructor(data = null, normalize = false)
3098
- {
3099
- super();
3100
- if (data && typeof data === 'object')
3101
- {
3102
- _.mapObject(data, (value, key) =>
3103
- {
3104
- if (this.hasOwnProperty(key))
3105
- {
3106
- this [ key ] = value;
3107
- }
3108
- });
3109
- }
3110
-
3111
- return this;
3112
- }
3113
- }
3114
-
3115
- /**
3116
- *
3117
- * @version v.0.1 (26/01/2025)
3118
- */
3119
- export class typeFOR extends familyService
3120
- {
3121
- filters;
3122
- object;
3123
- response;
3124
-
3125
- /**
3126
- *
3127
- * @version v.0.1 (26/01/2025)
3128
- * @param data
3129
- * @returns {typeFOR}
3130
- */
3131
- constructor(data = false)
3132
- {
3133
- super();
3134
-
3135
- if (data && typeof data === 'object')
3136
- {
3137
- _.mapObject(data, (value, key) =>
3138
- {
3139
- if (this.hasOwnProperty(key))
3140
- {
3141
- this [ key ] = value;
3142
- }
3143
- });
3144
- }
3145
-
3146
- return this;
3147
- }
3148
- }
3149
-
3150
- /**
3151
- * Описание стандартного колбека типового для методов
3152
- *
3153
- * @version v.0.1 (26/05/2024)
3154
- */
3155
- export class typeFunctionCallback extends familyService
3156
- {
3157
- before;
3158
- success;
3159
- error;
3160
- final;
3161
- destroy;
3162
-
3163
-
3164
- /**
3165
- *
3166
- * @version v.0.1 (26/05/2024)
3167
- * @param {object|false} data
3168
- * @return {typeFunctionCallback}
3169
- */
3170
- constructor(data = false)
3171
- {
3172
- super();
3173
-
3174
- if (data && typeof data === 'object')
3175
- {
3176
- _.mapObject(data, (value, key) =>
3177
- {
3178
- if (this.hasOwnProperty(key))
3179
- {
3180
- this [ key ] = value;
3181
- }
3182
- });
3183
- }
3184
-
3185
- return this;
3186
- }
3187
- }
3188
-
3189
- /**
3190
- * Уведомления
3191
- * Как будто это абстрактный интерфейс
3192
- * А внутри уже разные настроенные пользователем методы
3193
- *
3194
- */
3195
- export class typeNotification extends familyService
3196
- {
3197
-
3198
- // пока не понятно
3199
-
3200
- /**
3201
- *
3202
- * @param {object|false|undefined} data
3203
- */
3204
- constructor(data = false)
3205
- {
3206
- super();
3207
-
3208
- if (data && is_object(data))
3209
- {
3210
- _.mapObject(data, (value, key) =>
3211
- {
3212
- if (this.hasOwnProperty(key))
3213
- {
3214
- this [ key ] = value;
3215
- }
3216
- });
3217
- }
3218
-
3219
- return this;
3220
- }
3221
- }
3222
-
3223
- /**
3224
- *
3225
- * @version v.0.1 (26/04/2025)
3226
- */
3227
- export class typeTableColumn extends familyService
3228
- {
3229
- header_name;
3230
- field;
3231
- width;
3232
- sort_order;
3233
- cell_classes;
3234
- default_sort;
3235
- is_sortable;
3236
- is_filter;
3237
- is_hide;
3238
- is_editable;
3239
-
3240
-
3241
- constructor(data = false)
3242
- {
3243
- super();
3244
- if (data && typeof data === 'object')
3245
- {
3246
- _.mapObject(data, (value, key) =>
3247
- {
3248
- if (this.hasOwnProperty(key))
3249
- {
3250
- this [ key ] = value;
3251
- }
3252
- });
3253
- }
3254
-
3255
- return this;
3256
- }
3257
- }
3258
-
3259
- /**
3260
- * Настройки таблиц (aggrid)
3261
- *
3262
- * @version v.0.1 (26/04/2025)
3263
- */
3264
- export class typeTableConfiguration extends typeAppConfiguration
3265
- {
3266
- /**
3267
- * @type {array<typeTableColumn>}
3268
- */
3269
- columns;
3270
-
3271
- /**
3272
- * @type {array<typeFOR>}
3273
- */
3274
- for;
3275
-
3276
-
3277
- /**
3278
- * Элемент, в составе
3279
- * надо ли
3280
- */
3281
- contained_element_type;
3282
-
3283
-
3284
-
3285
- /**
3286
- * под развитие
3287
- * @type {{link: false|string, description: false|string}}
3288
- */
3289
- documentation = {
3290
- description: false,
3291
- link : false,
3292
- };
3293
-
3294
-
3295
-
3296
- constructor(data = false)
3297
- {
3298
- super();
3299
- if (data && typeof data === 'object')
3300
- {
3301
- _.mapObject(data, (value, key) =>
3302
- {
3303
- if (this.hasOwnProperty(key))
3304
- {
3305
- this [ key ] = value;
3306
- }
3307
- });
3308
- }
3309
-
3310
- return this;
3311
- }
3312
- }
3313
- /**
3314
- *
3315
- * @version v.0.1 (02/07/2024)
3316
- */
3317
- export class abstractMockData
3318
- {
3319
- mock_data_type = 'correct';
3320
-
3321
- constructor(mock_data_type = 'correct')
3322
- {
3323
- this.mock_data_type = mock_data_type;
3324
- }
3325
- }
3326
-
3327
-
3328
- /**
3329
- * @version v.0.1 (02/07/2024)
3330
- */
3331
- export class MockDataTypeProject extends abstractMockData
3332
- {
3333
- correct = [ {
3334
- project_id : 11,
3335
- project_name : 'Demo Project #11',
3336
- project_description: 'Description – это мета тег, представляющий собой описание. Он находится под заголовком (title) и ссылкой на сайт. Целью тега является вывод страницы в топ. Это в свою очередь привлечет больше целевых пользователей. Можно составить description самостоятельно.',
3337
- project_status : 'OPEN',
3338
- team_id : 0,
3339
- }, {
3340
- project_id : 22,
3341
- project_name : 'Demo Project #22',
3342
- project_description: 'Однако есть риск допустить ошибку. Если использовать не те фразы и длину предложения, то успеха не достичь.',
3343
- project_status : 'OPEN',
3344
- team_id : 0,
3345
- }, {
3346
- project_id : 33,
3347
- project_name : 'Perspective project № 1',
3348
- project_description: 'Чтобы сделать онлайн контент план, нужно ввести тематику блога. На основании данных генератор подберет темы.',
3349
- project_status : 'PLANNED',
3350
- team_id : 0,
3351
- }, {
3352
- project_id : 44,
3353
- project_name : 'Perspective project № 2',
3354
- project_description: 'Укажите любые детали вашей веб-страницы: вставьте сам текст или укажите тему/ключевые слова;',
3355
- project_status : 'PLANNED',
3356
- team_id : 0,
3357
- }, {
3358
- project_id : 55,
3359
- project_name : 'Closed project № 1',
3360
- project_description: 'Протестируйте бесплатно',
3361
- project_status : 'PLANNED',
3362
- team_id : 0,
3363
- }, {
3364
- project_id : 66,
3365
- project_name : 'Closed project № 1',
3366
- project_description: 'Создать теги онлайн можно бесплатно. Для этого вставьте всю информацию в специальную форму. Генератор быстро сформирует результат. Вы сможете убедиться в его скорости и эффективности. Создатель тегов – быстрый и удобный сервис.',
3367
- project_status : 'PLANNED',
3368
- team_id : 0,
3369
- },
3370
- ];
3371
-
3372
- static last_index = {
3373
- correct: 0
3374
- };
3375
-
3376
-
3377
- /**
3378
- *
3379
- * @version v.0.1 (02/07/2024)
3380
- * @param mock_data_type
3381
- */
3382
- constructor(mock_data_type = 'correct')
3383
- {
3384
- super();
3385
-
3386
- let response = false;
3387
- if (mock_data_type === 'correct')
3388
- {
3389
- if (is_object(this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ]))
3390
- {
3391
- response = this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ];
3392
- }
3393
- else
3394
- {
3395
- MockDataTypeProject.last_index[ mock_data_type ] = 0;
3396
- response = this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ];
3397
- }
3398
- }
3399
-
3400
- if (count(this[ mock_data_type ]) >= MockDataTypeProject.last_index[ mock_data_type ])
3401
- {
3402
- MockDataTypeProject.last_index[ mock_data_type ]++;
3403
- }
3404
- else
3405
- {
3406
- MockDataTypeProject.last_index[ mock_data_type ] = 0;
3407
- }
3408
-
3409
- return response;
3410
- }
3411
- }