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