complexqa_frontend_core 1.23.1 → 1.25.1

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 (38) hide show
  1. package/package.json +1 -1
  2. package/publish/api/attachment_api.js +55 -0
  3. package/publish/api/file_app_api.js +22 -0
  4. package/publish/api/index.js +10 -0
  5. package/publish/api/tag/tag_color_api.js +16 -0
  6. package/publish/api/tag/tag_template_api.js +16 -0
  7. package/publish/api/tag_api.js +52 -0
  8. package/publish/api/tag_relation_api.js +57 -0
  9. package/publish/app_configuration/table/helpers/table_element_models.js +6 -0
  10. package/publish/app_configuration/table/sections/bug.js +7 -1
  11. package/publish/app_configuration/table/sections/tag.js +84 -0
  12. package/publish/app_configuration/table/sections/tag_relation.js +309 -0
  13. package/publish/app_configuration/table/sections/test_account.js +7 -1
  14. package/publish/app_configuration/table/sections/test_case.js +7 -1
  15. package/publish/app_configuration/table/sections/test_run.js +7 -1
  16. package/publish/app_configuration/table/sections/test_run_result.js +7 -1
  17. package/publish/app_configuration/table/sections/text_document.js +7 -1
  18. package/publish/app_configuration/table/table_configuration.js +4 -0
  19. package/publish/index.js +3 -0
  20. package/publish/services/FileAppService.js +67 -21
  21. package/publish/types/core/1_familyTestDocumentation.js +9 -1
  22. package/publish/types/element_translate/typeAttachment.i18n.js +201 -0
  23. package/publish/types/element_translate/typeBug.i18n.js +11 -0
  24. package/publish/types/element_translate/typeTag.i18n.js +69 -0
  25. package/publish/types/element_translate/typeTagRelation.i18n.js +74 -0
  26. package/publish/types/element_translate/typeTestAccount.i18n.js +11 -0
  27. package/publish/types/element_translate/typeTestCase.i18n.js +11 -0
  28. package/publish/types/element_translate/typeTestRun.i18n.js +11 -0
  29. package/publish/types/element_translate/typeTestRunResult.i18n.js +11 -0
  30. package/publish/types/element_translate/typeTextDocument.i18n.js +11 -0
  31. package/publish/types/family_elements/typeAttachment.js +119 -0
  32. package/publish/types/family_elements/typeBug.js +0 -2
  33. package/publish/types/family_elements/typeTag.js +84 -0
  34. package/publish/types/family_elements/typeTestAccount.js +2 -0
  35. package/publish/types/family_events/familyEvent.js +3 -0
  36. package/publish/types/family_files/typeFileScreenshot.js +2 -2
  37. package/publish/types/family_files/typeTextDocument.js +2 -0
  38. package/publish/types/family_relation/typeTagRelation.js +123 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complexqa_frontend_core",
3
- "version": "1.23.1",
3
+ "version": "1.25.1",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,55 @@
1
+ import { ApiAbstractElementClass } from './api_abstract_element_class.js';
2
+ import { typeAttachment } from '../types/family_elements/typeAttachment.js';
3
+
4
+ /**
5
+ * CRUD / Search / delete_file для attachment.
6
+ *
7
+ * @version v.0.1 (13/08/2026)
8
+ */
9
+ export class AttachmentApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'attachment';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeAttachment);
17
+ }
18
+
19
+
20
+ /**
21
+ * Delete file in File App and unlink all attachments for that file_uuid.
22
+ *
23
+ * POST /web_api/attachment/delete_file
24
+ *
25
+ * @param {object} payload
26
+ * @param {string} payload.file_uuid
27
+ * @returns {Promise<{response: *, payload: *}>}
28
+ */
29
+ async delete_file(payload)
30
+ {
31
+ if (!this.module_prefix)
32
+ {
33
+ throw new Error('Error #attachment-delete-file-1152 in AttachmentApi');
34
+ }
35
+
36
+ if (this.stage === 'development')
37
+ {
38
+ return {
39
+ response: payload,
40
+ payload : payload,
41
+ };
42
+ }
43
+
44
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/delete_file`;
45
+
46
+ payload = this.handle_request_payload(payload);
47
+ let response = this.api_request(url, payload);
48
+ response = this.handle_response(response);
49
+
50
+ return {
51
+ response: response,
52
+ payload : payload,
53
+ };
54
+ }
55
+ }
@@ -114,4 +114,26 @@ export class FileAppApi extends ApiAbstractClass
114
114
  payload : payload,
115
115
  };
116
116
  }
117
+
118
+
119
+ /**
120
+ * POST /web_api/file_app/delete_file
121
+ *
122
+ * @param {object} payload
123
+ * @param {string} payload.file_uuid
124
+ *
125
+ * @returns {Promise<{payload: object, response: object}>}
126
+ */
127
+ async delete_file(payload)
128
+ {
129
+ const url = `/${ this.api_prefix }/${ this.module_prefix }/delete_file`;
130
+ payload = this.handle_request_payload(payload);
131
+ let response = this.api_request(url, payload);
132
+ response = await this.handle_response(response, false);
133
+
134
+ return {
135
+ response: response,
136
+ payload : payload,
137
+ };
138
+ }
117
139
  }
@@ -13,6 +13,11 @@ import { TaskApi } from "./task_api.js";
13
13
  import { TestAccountApi } from "./test_account_api.js";
14
14
  import { BugApi } from "./bug_api.js";
15
15
  import { BugRelationApi } from "./bug_relation_api.js";
16
+ import { AttachmentApi } from "./attachment_api.js";
17
+ import { TagApi } from "./tag_api.js";
18
+ import { TagRelationApi } from "./tag_relation_api.js";
19
+ import { TagColorApi } from "./tag/tag_color_api.js";
20
+ import { TagTemplateApi } from "./tag/tag_template_api.js";
16
21
  import { ContextBrowserApi } from "./context/context_browser_api.js";
17
22
  import { ContextDeploymentTargetApi } from "./context/context_deployment_target_api.js";
18
23
  import { ContextDevicesApi } from "./context/context_devices_api.js";
@@ -166,6 +171,9 @@ export class Api
166
171
  this.test_account = new TestAccountApi(payload);
167
172
  this.bug = new BugApi(payload);
168
173
  this.bug_relation = new BugRelationApi(payload);
174
+ this.attachment = new AttachmentApi(payload);
175
+ this.tag = new TagApi(payload);
176
+ this.tag_relation = new TagRelationApi(payload);
169
177
  this.event = new EventApi(payload);
170
178
  this.execution_context = new ExecutionContextApi(payload);
171
179
  this.browser_tools_util_execution = new BrowserToolsUtilExecutionApi(payload);
@@ -194,6 +202,8 @@ export class Api
194
202
  response.context_locale = new ContextLocaleApi(payload);
195
203
  response.context_os = new ContextOsApi(payload);
196
204
  response.context_screen_resolution = new ContextScreenResolutionApi(payload);
205
+ response.tag_color = new TagColorApi(payload);
206
+ response.tag_template = new TagTemplateApi(payload);
197
207
 
198
208
  return response;
199
209
  }
@@ -0,0 +1,16 @@
1
+ import { ApiAbstractReferenceClass } from '../api_abstract_reference_class.js';
2
+
3
+ /**
4
+ * System tag color palette (read-only).
5
+ *
6
+ * @version v.0.1 (12/08/2026)
7
+ */
8
+ export class TagColorApi extends ApiAbstractReferenceClass
9
+ {
10
+ module_prefix = 'tag_color';
11
+
12
+ constructor(options)
13
+ {
14
+ super(options);
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import { ApiAbstractReferenceClass } from '../api_abstract_reference_class.js';
2
+
3
+ /**
4
+ * System tag templates (read-only for tenants).
5
+ *
6
+ * @version v.0.1 (12/08/2026)
7
+ */
8
+ export class TagTemplateApi extends ApiAbstractReferenceClass
9
+ {
10
+ module_prefix = 'tag_template';
11
+
12
+ constructor(options)
13
+ {
14
+ super(options);
15
+ }
16
+ }
@@ -0,0 +1,52 @@
1
+ import { ApiAbstractElementClass } from './api_abstract_element_class.js';
2
+ import { typeTag } from '../types/family_elements/typeTag.js';
3
+
4
+ /**
5
+ * CRUD / Search / clone_from_templates for tag.
6
+ *
7
+ * @version v.0.1 (12/08/2026)
8
+ */
9
+ export class TagApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'tag';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTag);
17
+ }
18
+
19
+
20
+ /**
21
+ * Clone system tag_templates into project catalog.
22
+ *
23
+ * @param {{ project_id: number, tag_template_ids: number[] }} payload
24
+ * @returns {Promise<{response: *, payload: *}>}
25
+ */
26
+ async clone_from_templates(payload)
27
+ {
28
+ if (!this.module_prefix)
29
+ {
30
+ throw new Error('Error #tag-clone-1152 in TagApi');
31
+ }
32
+
33
+ if (this.stage === 'development')
34
+ {
35
+ return {
36
+ response: payload,
37
+ payload : payload,
38
+ };
39
+ }
40
+
41
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/clone_from_templates`;
42
+
43
+ payload = this.handle_request_payload(payload);
44
+ let response = this.api_request(url, payload);
45
+ response = this.handle_response(response);
46
+
47
+ return {
48
+ response: response,
49
+ payload : payload,
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,57 @@
1
+ import { ApiAbstractElementClass } from './api_abstract_element_class.js';
2
+ import { typeTagRelation } from '../types/family_relation/typeTagRelation.js';
3
+
4
+ /**
5
+ * CRUD / Search / create_mass для tag_relation.
6
+ *
7
+ * @version v.0.2 (12/08/2026)
8
+ */
9
+ export class TagRelationApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'tag_relation';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTagRelation);
17
+ }
18
+
19
+
20
+ /**
21
+ * Additive mass attach: selected tags → selected elements (existing links untouched).
22
+ *
23
+ * @param {{
24
+ * project_id: number,
25
+ * element_type: string,
26
+ * element_ids: number[],
27
+ * tag_ids: number[]
28
+ * }} payload
29
+ * @returns {Promise<{response: *, payload: *}>}
30
+ */
31
+ async create_mass(payload)
32
+ {
33
+ if (!this.module_prefix)
34
+ {
35
+ throw new Error('Error #tag-relation-create-mass-1152 in TagRelationApi');
36
+ }
37
+
38
+ if (this.stage === 'development')
39
+ {
40
+ return {
41
+ response: payload,
42
+ payload : payload,
43
+ };
44
+ }
45
+
46
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/create_mass`;
47
+
48
+ payload = this.handle_request_payload(payload);
49
+ let response = this.api_request(url, payload);
50
+ response = this.handle_response(response);
51
+
52
+ return {
53
+ response: response,
54
+ payload : payload,
55
+ };
56
+ }
57
+ }
@@ -3,6 +3,9 @@ import { typeProject } from '../../../types/family_elements/typeProject.js';
3
3
  import { typeTestRun } from '../../../types/family_elements/typeTestRun.js';
4
4
  import { typeBug } from '../../../types/family_elements/typeBug.js';
5
5
  import { typeBugRelation } from '../../../types/family_relation/typeBugRelation.js';
6
+ import { typeTag } from '../../../types/family_elements/typeTag.js';
7
+ import { typeAttachment } from '../../../types/family_elements/typeAttachment.js';
8
+ import { typeTagRelation } from '../../../types/family_relation/typeTagRelation.js';
6
9
  import { typeTestRunResult } from '../../../types/family_elements/typeTestRunResult.js';
7
10
  import { typeTestAccount } from '../../../types/family_elements/typeTestAccount.js';
8
11
  import { typeExecutionContext } from '../../../types/family_context/typeExecutionContext.js';
@@ -31,6 +34,9 @@ export const TABLE_ELEMENT_MODELS = {
31
34
  test_run : typeTestRun,
32
35
  bug : typeBug,
33
36
  bug_relation : typeBugRelation,
37
+ attachment : typeAttachment,
38
+ tag : typeTag,
39
+ tag_relation : typeTagRelation,
34
40
  test_run_result: typeTestRunResult,
35
41
  test_account : typeTestAccount,
36
42
  execution_context : typeExecutionContext,
@@ -31,6 +31,12 @@ function build_bug_listing_columns(locale, { include_select = true } = {})
31
31
  columns.push(createColumn(model, locale, 'bug_type', { width: '150', is_editable: true, is_required: true }));
32
32
  columns.push(createColumn(model, locale, 'bug_resolution', { width: '150', is_editable: true, is_required: true, hide: true }));
33
33
  columns.push(createColumn(model, locale, 'assigned_to', { width: '220', is_editable: true, is_required: true }));
34
+ columns.push(createColumn(model, locale, 'tags', {
35
+ width : '220',
36
+ is_editable: false,
37
+ is_sortable: false,
38
+ is_required: false,
39
+ }));
34
40
  columns.push(createColumn(model, locale, 'created_at', { width: '170', is_required: true }));
35
41
  columns.push(createColumn(model, locale, 'completed_at', { width: '170', is_required: true, hide: true }));
36
42
  columns.push(createGoToColumn(model, locale));
@@ -96,7 +102,7 @@ export function bootstrap_bug(config)
96
102
  const locale = UserService.get_current_language();
97
103
 
98
104
  registerSection(config, 'bug', 'listing', build_bug_listing_columns(locale), {
99
- for: createListingFor([ 'project_id' ]),
105
+ for: createListingFor([ 'project_id' ], { add: [ 'tags' ] }),
100
106
  });
101
107
 
102
108
  registerSection(config, 'bug', 'todo', build_bug_todo_columns(locale), {
@@ -0,0 +1,84 @@
1
+ import { typeTag } from '../../../types/family_elements/typeTag.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import {
4
+ createColumn,
5
+ createGoToColumn,
6
+ createPrimaryKeyColumn,
7
+ createRowSelectColumn,
8
+ } from '../helpers/column_factory.js';
9
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
10
+ import { typeTableColumn } from '../../../types/family_service/typeTableColumn.js';
11
+
12
+ function build_tag_listing_columns(locale)
13
+ {
14
+ const model = new typeTag();
15
+
16
+ return [
17
+ createRowSelectColumn(),
18
+ createPrimaryKeyColumn(model, locale),
19
+ createColumn(model, locale, 'name', {
20
+ width : '280',
21
+ is_editable: true,
22
+ is_required: true,
23
+ is_title : true,
24
+ }),
25
+ createColumn(model, locale, 'description', { width: '420', is_editable: true }),
26
+ createColumn(model, locale, 'created_at', { width: '170' }),
27
+ createColumn(model, locale, 'updated_at', { width: '170' }),
28
+ createGoToColumn(model, locale),
29
+ ];
30
+ }
31
+
32
+
33
+ function build_tag_details_columns(locale)
34
+ {
35
+ const model = new typeTag();
36
+ const fields = [
37
+ 'tag_id',
38
+ 'project_id',
39
+ 'team_id',
40
+ 'name',
41
+ 'tag_color_id',
42
+ 'created_at',
43
+ 'updated_at',
44
+ ];
45
+
46
+ return [
47
+ ...fields.map((field, index) => createColumn(model, locale, field, {
48
+ sort_order : String(index + 1),
49
+ is_editable: [ 'name', 'tag_color_id' ].includes(field),
50
+ is_sortable: false,
51
+ is_filter : false,
52
+ })),
53
+ new typeTableColumn({
54
+ header_name: 'copy',
55
+ field : 'copy',
56
+ width : '80',
57
+ sort_order : '99',
58
+ is_sortable: false,
59
+ is_filter : false,
60
+ is_editable: false,
61
+ column_kind: 'copy',
62
+ }),
63
+ ];
64
+ }
65
+
66
+
67
+ /**
68
+ * Секции `tag`: `listing`, `details`.
69
+ *
70
+ * @param {Object} config
71
+ * @returns {void}
72
+ */
73
+ export function bootstrap_tag(config)
74
+ {
75
+ const locale = UserService.get_current_language();
76
+
77
+ registerSection(config, 'tag', 'listing', build_tag_listing_columns(locale), {
78
+ for: createListingFor([ 'project_id' ], { add: [ 'colors' ] }),
79
+ });
80
+
81
+ registerSection(config, 'tag', 'details', build_tag_details_columns(locale), {
82
+ for: createListingFor([ 'tag_id' ], { add: [ 'colors' ] }),
83
+ });
84
+ }