complexqa_frontend_core 1.0.9 → 1.0.10

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.
Files changed (51) hide show
  1. package/package.json +3 -3
  2. package/publish/api/api_abstract_element_class.js +426 -0
  3. package/publish/api/functional_api.js +18 -0
  4. package/publish/api/index.js +114 -0
  5. package/publish/api/project_api.js +17 -0
  6. package/publish/api/service_api.js +20 -0
  7. package/publish/api/team_member_api.js +18 -0
  8. package/publish/api/test_case_api.js +18 -0
  9. package/publish/api/test_case_step_api.js +18 -0
  10. package/publish/api/test_plan_api.js +18 -0
  11. package/publish/api/test_run_api.js +13 -0
  12. package/publish/api/test_run_result_api.js +18 -0
  13. package/publish/api/test_suite_api.js +18 -0
  14. package/publish/exceptions/ApiException.js +69 -0
  15. package/publish/index.js +50 -0
  16. package/publish/services/UserService.js +129 -0
  17. package/publish/services/abstractService.js +36 -0
  18. package/publish/services/mock_data/MockUserService.js +30 -0
  19. package/publish/services/serviceTranslate.js +98 -0
  20. package/publish/types/family_elements/0_familyGeneralElement.js +439 -0
  21. package/publish/types/family_elements/mock_data/abstract_mock_data.js +13 -0
  22. package/publish/types/family_elements/mock_data/mock_data_typeProject.js +88 -0
  23. package/publish/types/family_elements/typeActionLog.js +9 -0
  24. package/publish/types/family_elements/typeFunctional.js +96 -0
  25. package/publish/types/family_elements/typeFunctionalGroup.js +95 -0
  26. package/publish/types/family_elements/typeMilestone.js +93 -0
  27. package/publish/types/family_elements/typeProject.js +114 -0
  28. package/publish/types/family_elements/typeProjectDocument.js +80 -0
  29. package/publish/types/family_elements/typeProjectTestAccount.js +59 -0
  30. package/publish/types/family_elements/typeProjectTestData.js +43 -0
  31. package/publish/types/family_elements/typeProjectUserRole.js +55 -0
  32. package/publish/types/family_elements/typeTask.js +78 -0
  33. package/publish/types/family_elements/typeTeam.js +105 -0
  34. package/publish/types/family_elements/typeTeamMember.js +58 -0
  35. package/publish/types/family_elements/typeTeamUserRole.js +56 -0
  36. package/publish/types/family_elements/typeTestCase.js +98 -0
  37. package/publish/types/family_elements/typeTestCaseStep.js +87 -0
  38. package/publish/types/family_elements/typeTestPlan.js +35 -0
  39. package/publish/types/family_elements/typeTestRun.js +56 -0
  40. package/publish/types/family_elements/typeTestRunResult.js +72 -0
  41. package/publish/types/family_elements/typeTestSuite.js +75 -0
  42. package/publish/types/family_elements/typeUser.js +56 -0
  43. package/publish/types/family_service/familyService.js +8 -0
  44. package/publish/types/family_service/typeAppConfiguration.js +39 -0
  45. package/publish/types/family_service/typeFOR.js +36 -0
  46. package/publish/types/family_service/typeFilter.js +38 -0
  47. package/publish/types/family_service/typeFunctionCallback.js +40 -0
  48. package/publish/types/family_service/typeNotification.js +36 -0
  49. package/publish/types/family_service/typeTableColumn.js +37 -0
  50. package/publish/types/family_service/typeTableConfiguration.js +56 -0
  51. package/publish/utils/utils.js +190 -0
@@ -0,0 +1,439 @@
1
+ import { clone_object, echo, in_array, is_array } from "../../utils/utils";
2
+
3
+ /**
4
+ * Базовый абстрактный класс для всех типов
5
+ *
6
+ * @version v.0.2 (12/06/2025)
7
+ */
8
+ export class familyGeneralElement
9
+ {
10
+ primary_key = false;
11
+ create_scheme = false;
12
+ structure_scheme = false;
13
+ available_enum_values = false;
14
+ api_key = false;
15
+
16
+
17
+ /***********************************************/
18
+ /***********************************************/
19
+
20
+ /***********************************************/
21
+
22
+ /**
23
+ *
24
+ * @version v.0.1 (26/05/2024)
25
+ * @return {string|false}
26
+ */
27
+ get_primary_key()
28
+ {
29
+ if (this.primary_key)
30
+ {
31
+ return this.primary_key;
32
+ }
33
+ else
34
+ {
35
+ throw new Error('familyGeneralElement has no primary_key. Error #01-01');
36
+ }
37
+ }
38
+
39
+
40
+ /**
41
+ *
42
+ * @version v.0.1 (27/06/2024)
43
+ * @returns {array<familyGeneralElement>}
44
+ * @param {number} count
45
+ */
46
+ get_random_demo_data(count)
47
+ {
48
+ // @todo validations
49
+ let response = [];
50
+ for (let i = 0; i < count; i++)
51
+ {
52
+ response.push(this.get_demo_row());
53
+ }
54
+ // получаем массив сгенерированных элементов,
55
+ // в том числе - с незаполненными данными (корректная обработка)
56
+
57
+ // контроль пересечения primary key
58
+ // прототип идеи
59
+ // @todo - дописать
60
+ return response;
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @returns {familyGeneralElement}
66
+ */
67
+ get_demo_row()
68
+ {
69
+ return this;
70
+ }
71
+
72
+ /**
73
+ *
74
+ * @version v.0.2 (15/06/2024)
75
+ * @param {string} attribute
76
+ */
77
+ get_available_enum_values(attribute)
78
+ {
79
+ let response = false;
80
+ if (this.structure_scheme?.[ attribute ])
81
+ {
82
+ // выбрасывать исключения?
83
+ return false;
84
+ }
85
+
86
+ let rules = this.get_attribute_structure_scheme(attribute);
87
+ if (!rules)
88
+ {
89
+ return false;
90
+ }
91
+ if (!in_array('enum', rules))
92
+ {
93
+ return false;
94
+ }
95
+
96
+ if (this.available_enum_values?.[ attribute ])
97
+ {
98
+ response = this.available_enum_values?.[ attribute ];
99
+ }
100
+
101
+ return response;
102
+ }
103
+
104
+
105
+ /**
106
+ *
107
+ * @param attribute
108
+ * @returns {array|false}
109
+ */
110
+ get_attribute_structure_scheme(attribute)
111
+ {
112
+ let response = false;
113
+ if (this.structure_scheme[ attribute ])
114
+ {
115
+ let scheme = clone_object(this.structure_scheme[ attribute ]);
116
+
117
+ if (scheme)
118
+ {
119
+ scheme = scheme.split('|');
120
+ if (is_array(scheme))
121
+ {
122
+ response = [];
123
+ scheme.map((row) =>
124
+ {
125
+ response.push(row.trim());
126
+ });
127
+ }
128
+ }
129
+ }
130
+
131
+ return response;
132
+ }
133
+
134
+
135
+ /**
136
+ *
137
+ * @version v.0.1 (26/05/2024)
138
+ */
139
+ get_data()
140
+ {
141
+ return this.get_pure_data();
142
+ }
143
+
144
+
145
+ /**
146
+ *
147
+ * @version v.0.1 (26/05/2024)
148
+ */
149
+ get_pure_data()
150
+ {
151
+ let response = false;
152
+ if (this.structure_scheme)
153
+ {
154
+ response = {};
155
+ _.mapObject(this.structure_scheme, (value, attribute) =>
156
+ {
157
+ if (this[ attribute ])
158
+ {
159
+ response [ attribute ] = this[ attribute ];
160
+ }
161
+ });
162
+ }
163
+
164
+ return response;
165
+ }
166
+
167
+
168
+ /**
169
+ * @todo - сделать нормализация по create scheme с валидацией
170
+ *
171
+ * @version v.0.1 (26/01/2025)
172
+ *
173
+ * @param payload
174
+ * @returns {*}
175
+ */
176
+ normalize_payload(payload)
177
+ {
178
+
179
+ return payload;
180
+ }
181
+
182
+
183
+ get_editable_attributes() {}
184
+
185
+ is_editable_attribute(attribute) {}
186
+
187
+
188
+ /**
189
+ *
190
+ * @version v.0.1 (26/05/2024)
191
+ * @param {string} attribute_name
192
+ * @return {string}
193
+ */
194
+ get_attribute_name_translate(attribute_name)
195
+ {
196
+ return attribute_name;
197
+ }
198
+
199
+ /***********************************************/
200
+
201
+ /**
202
+ * Возвращаем "имя", то есть значение атрибута, который является именем
203
+ *
204
+ * @version v.0.1 (05/06/2025)
205
+ */
206
+ get_element_name()
207
+ {
208
+ alert('Error #205-001 Not implemented method');
209
+ }
210
+
211
+ /***********************************************/
212
+ /***********************************************/
213
+
214
+ /***********************************************/
215
+
216
+ /**
217
+ *
218
+ * @version v.0.1 (26/05/2024)
219
+ * @param id
220
+ */
221
+ async find(id = false)
222
+ {
223
+ // или передаем ID, или используем вложенный
224
+ // возвращаем инстанс себя же
225
+ alert('Error #267-001 Not implemented method');
226
+ }
227
+
228
+
229
+ /**
230
+ *
231
+ * @param {familyGeneralElement|object} payload
232
+ *
233
+ * @param {typeFunctionCallback|object|false} callback
234
+ *
235
+ * @param {?function} callback.before
236
+ * @param {?function} callback.success
237
+ * @param {?function} callback.error
238
+ * @param {?function} callback.final
239
+ *
240
+ * @version v.2.0 (12/06/2025)
241
+ */
242
+ async create(payload, callback)
243
+ {
244
+ if (!this.api_key)
245
+ {
246
+ throw new Error('element has not api_key');
247
+ }
248
+
249
+ if (typeof callback?.before === 'function')
250
+ {
251
+ callback?.before({ payload });
252
+ }
253
+
254
+ payload = this.normalize_payload(payload);
255
+
256
+
257
+ /**
258
+ * {Api} ApiService
259
+ */
260
+ return ApiService[this.api_key].create(payload).then((response) =>
261
+ {
262
+ if (typeof callback?.success === 'function')
263
+ {
264
+ callback?.success({ response, payload })
265
+ }
266
+ }).catch((error) =>
267
+ {
268
+ echo({ error });
269
+ if (typeof callback?.error === 'function')
270
+ {
271
+ callback?.error({ error, payload })
272
+ }
273
+ }).finally((response) =>
274
+ {
275
+ if (typeof callback?.final === 'function')
276
+ {
277
+ callback?.final({ response, payload })
278
+ }
279
+ });
280
+ }
281
+
282
+
283
+
284
+ /**
285
+ *
286
+ * @version v.2.0 (12/06/2025)
287
+ */
288
+ async update(payload, callback)
289
+ {
290
+ if (!this.api_key)
291
+ {
292
+ throw new Error('element has not api_key');
293
+ }
294
+
295
+ if (typeof callback?.before === 'function')
296
+ {
297
+ callback?.before({ payload });
298
+ }
299
+
300
+ payload = this.normalize_payload(payload);
301
+
302
+
303
+ /**
304
+ * {Api} ApiService
305
+ */
306
+ return ApiService[this.api_key].update(payload).then((response) =>
307
+ {
308
+ if (typeof callback?.success === 'function')
309
+ {
310
+ callback?.success({ response, payload })
311
+ }
312
+ }).catch((error) =>
313
+ {
314
+ echo({ error });
315
+ if (typeof callback?.error === 'function')
316
+ {
317
+ callback?.error({ error, payload })
318
+ }
319
+ }).finally((response) =>
320
+ {
321
+ if (typeof callback?.final === 'function')
322
+ {
323
+ callback?.final({ response, payload })
324
+ }
325
+ });
326
+ }
327
+
328
+
329
+
330
+ /**
331
+ *
332
+ * @version v.2.0 (12/06/2025)
333
+ * @param key
334
+ * @param value
335
+ * @param callback
336
+ * @returns {Promise<>}
337
+ */
338
+ async update_property(key, value, callback)
339
+ {
340
+ if (!this.api_key)
341
+ {
342
+ throw new Error('element has not api_key');
343
+ }
344
+
345
+ let payload = {
346
+ key : key,
347
+ value : value,
348
+ };
349
+ payload[this.get_primary_key()] = this[this.get_primary_key()];
350
+
351
+ if (typeof callback?.before === 'function')
352
+ {
353
+ callback?.before({ payload });
354
+ }
355
+
356
+ /**
357
+ * {Api} ApiService
358
+ */
359
+ return ApiService[this.api_key].update_property(payload).then((response) =>
360
+ {
361
+ if (typeof callback?.success === 'function')
362
+ {
363
+ callback?.success({ response, payload })
364
+ }
365
+ }).catch((error) =>
366
+ {
367
+ echo({ error });
368
+ if (typeof callback?.error === 'function')
369
+ {
370
+ callback?.error({ error, payload })
371
+ }
372
+ }).finally((response) =>
373
+ {
374
+ if (typeof callback?.final === 'function')
375
+ {
376
+ callback?.final({ response, payload })
377
+ }
378
+ });
379
+ }
380
+
381
+
382
+ /**
383
+ *
384
+ * @version v.0.1 (26/05/2024)
385
+ */
386
+ async update_properties()
387
+ {
388
+ alert('Error #272-001 Not implemented method');
389
+ }
390
+
391
+
392
+
393
+ /**
394
+ *
395
+ * @version v.2.0 (12/06/2025)
396
+ */
397
+ async delete(element = false, callback = {})
398
+ {
399
+ if (!this.api_key)
400
+ {
401
+ throw new Error('element has not api_key');
402
+ }
403
+
404
+ if (!element)
405
+ {
406
+ element = this;
407
+ }
408
+
409
+ let payload = {};
410
+
411
+ payload[this.get_primary_key()] = element[this.get_primary_key()];
412
+
413
+ if (typeof callback?.before === 'function')
414
+ {
415
+ callback?.before({ payload });
416
+ }
417
+
418
+ return ApiService[this.api_key].delete(payload).then((response) =>
419
+ {
420
+ if (typeof callback?.success === 'function')
421
+ {
422
+ callback?.success({ response, payload })
423
+ }
424
+ }).catch((error) =>
425
+ {
426
+ echo({ error });
427
+ if (typeof callback?.error === 'function')
428
+ {
429
+ callback?.error({ error, payload })
430
+ }
431
+ }).finally((response) =>
432
+ {
433
+ if (typeof callback?.final === 'function')
434
+ {
435
+ callback?.final({ response, payload })
436
+ }
437
+ });
438
+ }
439
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ *
3
+ * @version v.0.1 (02/07/2024)
4
+ */
5
+ export class abstractMockData
6
+ {
7
+ mock_data_type = 'correct';
8
+
9
+ constructor(mock_data_type = 'correct')
10
+ {
11
+ this.mock_data_type = mock_data_type;
12
+ }
13
+ }
@@ -0,0 +1,88 @@
1
+ import { abstractMockData } from "./abstract_mock_data";
2
+ import { count, is_object } from "../../../utils/utils";
3
+
4
+
5
+ /**
6
+ * @version v.0.1 (02/07/2024)
7
+ */
8
+ export class MockDataTypeProject extends abstractMockData
9
+ {
10
+ correct = [ {
11
+ project_id : 11,
12
+ project_name : 'Demo Project #11',
13
+ project_description: 'Description – это мета тег, представляющий собой описание. Он находится под заголовком (title) и ссылкой на сайт. Целью тега является вывод страницы в топ. Это в свою очередь привлечет больше целевых пользователей. Можно составить description самостоятельно.',
14
+ project_status : 'OPEN',
15
+ team_id : 0,
16
+ }, {
17
+ project_id : 22,
18
+ project_name : 'Demo Project #22',
19
+ project_description: 'Однако есть риск допустить ошибку. Если использовать не те фразы и длину предложения, то успеха не достичь.',
20
+ project_status : 'OPEN',
21
+ team_id : 0,
22
+ }, {
23
+ project_id : 33,
24
+ project_name : 'Perspective project № 1',
25
+ project_description: 'Чтобы сделать онлайн контент план, нужно ввести тематику блога. На основании данных генератор подберет темы.',
26
+ project_status : 'PLANNED',
27
+ team_id : 0,
28
+ }, {
29
+ project_id : 44,
30
+ project_name : 'Perspective project № 2',
31
+ project_description: 'Укажите любые детали вашей веб-страницы: вставьте сам текст или укажите тему/ключевые слова;',
32
+ project_status : 'PLANNED',
33
+ team_id : 0,
34
+ }, {
35
+ project_id : 55,
36
+ project_name : 'Closed project № 1',
37
+ project_description: 'Протестируйте бесплатно',
38
+ project_status : 'PLANNED',
39
+ team_id : 0,
40
+ }, {
41
+ project_id : 66,
42
+ project_name : 'Closed project № 1',
43
+ project_description: 'Создать теги онлайн можно бесплатно. Для этого вставьте всю информацию в специальную форму. Генератор быстро сформирует результат. Вы сможете убедиться в его скорости и эффективности. Создатель тегов – быстрый и удобный сервис.',
44
+ project_status : 'PLANNED',
45
+ team_id : 0,
46
+ },
47
+ ];
48
+
49
+ static last_index = {
50
+ correct: 0
51
+ };
52
+
53
+
54
+ /**
55
+ *
56
+ * @version v.0.1 (02/07/2024)
57
+ * @param mock_data_type
58
+ */
59
+ constructor(mock_data_type = 'correct')
60
+ {
61
+ super();
62
+
63
+ let response = false;
64
+ if (mock_data_type === 'correct')
65
+ {
66
+ if (is_object(this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ]))
67
+ {
68
+ response = this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ];
69
+ }
70
+ else
71
+ {
72
+ MockDataTypeProject.last_index[ mock_data_type ] = 0;
73
+ response = this.correct[ MockDataTypeProject.last_index[ mock_data_type ] ];
74
+ }
75
+ }
76
+
77
+ if (count(this[ mock_data_type ]) >= MockDataTypeProject.last_index[ mock_data_type ])
78
+ {
79
+ MockDataTypeProject.last_index[ mock_data_type ]++;
80
+ }
81
+ else
82
+ {
83
+ MockDataTypeProject.last_index[ mock_data_type ] = 0;
84
+ }
85
+
86
+ return response;
87
+ }
88
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Заготовка - логи действий
3
+ *
4
+ * @version v.0.1 (15/10/2024)
5
+ */
6
+ export class typeActionLog
7
+ {
8
+
9
+ }
@@ -0,0 +1,96 @@
1
+ import { familyGeneralElement } from "./0_familyGeneralElement";
2
+ import { is_object } from "../../utils/utils";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (23/06/2024)
8
+ */
9
+ export class typeFunctional extends familyGeneralElement
10
+ {
11
+ functional_id;
12
+ project_id; // foreign key
13
+ functional_group_id; // foreign key
14
+ team_id; // foreign key
15
+ functional_name;
16
+ functional_description;
17
+ reference_document_ids; // IDS документов по функционалу (к примеру confluence)
18
+ created_at;
19
+ updated_at;
20
+
21
+ primary_key = 'functional_id';
22
+
23
+ structure_scheme = {
24
+ functional_id : 'integer | require',
25
+ project_id : 'integer | require',
26
+ functional_group_id : 'integer | require',
27
+ team_id : 'integer | require',
28
+ functional_name : 'string | max:90 | require',
29
+ functional_description: 'string | max:2500 | optional',
30
+ reference_document_ids: 'array | reference | optional',
31
+ created_at : 'timestamp | require',
32
+ updated_at : 'timestamp | optional',
33
+ };
34
+
35
+ available_enum_values = {
36
+ functional_status: [ 'не идей. нужен ли тут статус' ]
37
+ };
38
+
39
+
40
+ /**
41
+ *
42
+ * @param {object|false|undefined} data
43
+ */
44
+ constructor(data = false)
45
+ {
46
+ super();
47
+
48
+ if (data && is_object(data))
49
+ {
50
+ _.mapObject(data, (value, key) =>
51
+ {
52
+ if (this.hasOwnProperty(key))
53
+ {
54
+ this [ key ] = value;
55
+ }
56
+ });
57
+ }
58
+
59
+ return this;
60
+ }
61
+
62
+
63
+ /******************************************************************************************/
64
+ /*********************************** general **********************************************/
65
+
66
+ /******************************************************************************************/
67
+
68
+ /**
69
+ *
70
+ * @version v.0.1 (07/07/2024)
71
+ */
72
+ async create()
73
+ {}
74
+
75
+
76
+ /**
77
+ *
78
+ * @version v.0.1 (07/07/2024)
79
+ */
80
+ async update()
81
+ {
82
+
83
+ }
84
+
85
+
86
+ /**
87
+ *
88
+ * @version v.0.1 (07/07/2024)
89
+ */
90
+ async delete()
91
+ {
92
+
93
+ }
94
+
95
+
96
+ }