complexqa_frontend_core 1.22.3 → 1.24.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 (37) hide show
  1. package/package.json +1 -1
  2. package/publish/api/event_api.js +20 -0
  3. package/publish/api/index.js +34 -21
  4. package/publish/api/tag/tag_color_api.js +16 -0
  5. package/publish/api/tag/tag_template_api.js +16 -0
  6. package/publish/api/tag_api.js +52 -0
  7. package/publish/api/tag_relation_api.js +57 -0
  8. package/publish/app_configuration/table/helpers/table_element_models.js +6 -0
  9. package/publish/app_configuration/table/sections/bug.js +7 -1
  10. package/publish/app_configuration/table/sections/event.js +76 -0
  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 +6 -0
  19. package/publish/index.js +5 -0
  20. package/publish/types/core/0_familyGeneralElement.js +2 -2
  21. package/publish/types/core/1_familyTestDocumentation.js +9 -1
  22. package/publish/types/element_translate/typeBug.i18n.js +11 -0
  23. package/publish/types/element_translate/typeEvent.i18n.js +493 -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/typeBug.js +0 -2
  32. package/publish/types/family_elements/typeTag.js +84 -0
  33. package/publish/types/family_elements/typeTestAccount.js +2 -0
  34. package/publish/types/family_events/familyEvent.js +72 -0
  35. package/publish/types/family_events/typeEvent.js +95 -0
  36. package/publish/types/family_files/typeTextDocument.js +2 -0
  37. 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.22.3",
3
+ "version": "1.24.1",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,20 @@
1
+ import { ApiAbstractElementClass } from './api_abstract_element_class.js';
2
+ import { typeEvent } from '../types/family_events/typeEvent.js';
3
+
4
+ /**
5
+ * Read-only search для доменных событий (прокси main → event-service).
6
+ *
7
+ * Маршрут: POST /web_api/event/search
8
+ *
9
+ * @version v.1.0 (26/07/2026)
10
+ */
11
+ export class EventApi extends ApiAbstractElementClass
12
+ {
13
+ module_prefix = 'event';
14
+
15
+ constructor(options)
16
+ {
17
+ super(options);
18
+ this.set_element_class_instance(typeEvent);
19
+ }
20
+ }
@@ -13,6 +13,10 @@ 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 { TagApi } from "./tag_api.js";
17
+ import { TagRelationApi } from "./tag_relation_api.js";
18
+ import { TagColorApi } from "./tag/tag_color_api.js";
19
+ import { TagTemplateApi } from "./tag/tag_template_api.js";
16
20
  import { ContextBrowserApi } from "./context/context_browser_api.js";
17
21
  import { ContextDeploymentTargetApi } from "./context/context_deployment_target_api.js";
18
22
  import { ContextDevicesApi } from "./context/context_devices_api.js";
@@ -26,6 +30,7 @@ import { TextDocumentApi } from "./text_document_api.js";
26
30
  import { PublicTextDocumentApi } from "./public_text_document_api.js";
27
31
  import { TextDocumentFolderApi } from "./text_document_folder_api.js";
28
32
  import { FileAppApi } from "./file_app_api.js";
33
+ import { EventApi } from "./event_api.js";
29
34
 
30
35
  /**
31
36
  * Обертка над axios
@@ -59,6 +64,9 @@ export class Api
59
64
  general_domain = false;
60
65
  site_section = false;
61
66
 
67
+ /** @type {EventApi} */
68
+ event;
69
+
62
70
 
63
71
  /**
64
72
  *
@@ -147,28 +155,31 @@ export class Api
147
155
 
148
156
  //echo({payload});
149
157
 
150
- this.team_management = new TeamManagementApi(payload);
151
- this.team_member = new TeamMemberApi(payload);
152
- this.test_plan = new TestPlanApi(payload);
153
- this.project = new ProjectApi(payload);
154
- this.service = new ServiceApi(payload);
155
- this.test_case = new TestCaseApi(payload);
156
- this.test_case_step = new TestCaseStepApi(payload);
157
- this.test_suite = new TestSuiteApi(payload);
158
- this.test_run = new TestRunApi(payload);
159
- this.test_run_result = new TestRunResultApi(payload);
160
- this.user_profile = new UserProfileApi(payload);
161
- this.task = new TaskApi(payload);
162
- this.test_account = new TestAccountApi(payload);
163
- this.bug = new BugApi(payload);
164
- this.bug_relation = new BugRelationApi(payload);
165
- this.execution_context = new ExecutionContextApi(payload);
166
- this.browser_tools_util_execution = new BrowserToolsUtilExecutionApi(payload);
158
+ this.team_management = new TeamManagementApi(payload);
159
+ this.team_member = new TeamMemberApi(payload);
160
+ this.test_plan = new TestPlanApi(payload);
161
+ this.project = new ProjectApi(payload);
162
+ this.service = new ServiceApi(payload);
163
+ this.test_case = new TestCaseApi(payload);
164
+ this.test_case_step = new TestCaseStepApi(payload);
165
+ this.test_suite = new TestSuiteApi(payload);
166
+ this.test_run = new TestRunApi(payload);
167
+ this.test_run_result = new TestRunResultApi(payload);
168
+ this.user_profile = new UserProfileApi(payload);
169
+ this.task = new TaskApi(payload);
170
+ this.test_account = new TestAccountApi(payload);
171
+ this.bug = new BugApi(payload);
172
+ this.bug_relation = new BugRelationApi(payload);
173
+ this.tag = new TagApi(payload);
174
+ this.tag_relation = new TagRelationApi(payload);
175
+ this.event = new EventApi(payload);
176
+ this.execution_context = new ExecutionContextApi(payload);
177
+ this.browser_tools_util_execution = new BrowserToolsUtilExecutionApi(payload);
167
178
  this.browser_tools_screenshot_multi = new BrowserToolsScreenshotMultiApi(payload);
168
- this.file_app = new FileAppApi(payload);
169
- this.text_document = new TextDocumentApi(payload);
170
- this.text_document_folder = new TextDocumentFolderApi(payload);
171
- this.public_text_document = new PublicTextDocumentApi(payload);
179
+ this.file_app = new FileAppApi(payload);
180
+ this.text_document = new TextDocumentApi(payload);
181
+ this.text_document_folder = new TextDocumentFolderApi(payload);
182
+ this.public_text_document = new PublicTextDocumentApi(payload);
172
183
 
173
184
  this.reference = this.bootstrap_reference(payload)
174
185
  }
@@ -189,6 +200,8 @@ export class Api
189
200
  response.context_locale = new ContextLocaleApi(payload);
190
201
  response.context_os = new ContextOsApi(payload);
191
202
  response.context_screen_resolution = new ContextScreenResolutionApi(payload);
203
+ response.tag_color = new TagColorApi(payload);
204
+ response.tag_template = new TagTemplateApi(payload);
192
205
 
193
206
  return response;
194
207
  }
@@ -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,8 @@ 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 { typeTagRelation } from '../../../types/family_relation/typeTagRelation.js';
6
8
  import { typeTestRunResult } from '../../../types/family_elements/typeTestRunResult.js';
7
9
  import { typeTestAccount } from '../../../types/family_elements/typeTestAccount.js';
8
10
  import { typeExecutionContext } from '../../../types/family_context/typeExecutionContext.js';
@@ -12,6 +14,7 @@ import { typeUser } from '../../../types/family_elements/typeUser.js';
12
14
  import { typeTeam } from '../../../types/family_elements/typeTeam.js';
13
15
  import { typeUtilExecutionScreenshotMulti } from '../../../types/family_utils/typeUtilExecutionScreenshotMulti.js';
14
16
  import { typeTextDocument } from '../../../types/family_files/typeTextDocument.js';
17
+ import { typeEvent } from '../../../types/family_events/typeEvent.js';
15
18
 
16
19
  /**
17
20
  * Реестр классов моделей по ключу `element_type`.
@@ -30,6 +33,8 @@ export const TABLE_ELEMENT_MODELS = {
30
33
  test_run : typeTestRun,
31
34
  bug : typeBug,
32
35
  bug_relation : typeBugRelation,
36
+ tag : typeTag,
37
+ tag_relation : typeTagRelation,
33
38
  test_run_result: typeTestRunResult,
34
39
  test_account : typeTestAccount,
35
40
  execution_context : typeExecutionContext,
@@ -39,4 +44,5 @@ export const TABLE_ELEMENT_MODELS = {
39
44
  team : typeTeam,
40
45
  text_document : typeTextDocument,
41
46
  util_execution : typeUtilExecutionScreenshotMulti,
47
+ event : typeEvent,
42
48
  };
@@ -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,76 @@
1
+ import { typeEvent } from '../../../types/family_events/typeEvent.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn, createGoToColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+
6
+ /**
7
+ * Колонки ленты событий (team / project Activity).
8
+ *
9
+ * @param {string} locale
10
+ * @returns {import('../../../types/family_service/typeTableColumn.js').typeTableColumn[]}
11
+ */
12
+ function build_event_listing_columns(locale)
13
+ {
14
+ const model = new typeEvent();
15
+
16
+ return [
17
+ createColumn(model, locale, 'occurred_at', {
18
+ width : '220',
19
+ is_filter : true,
20
+ is_editable : false,
21
+ default_sort: 'desc',
22
+ }),
23
+ createColumn(model, locale, 'action', {
24
+ width : '120',
25
+ is_filter : true,
26
+ is_editable: false,
27
+ }),
28
+ createColumn(model, locale, 'outcome', {
29
+ width : '120',
30
+ is_filter : true,
31
+ is_editable: false,
32
+ }),
33
+ createColumn(model, locale, 'subject_type', {
34
+ width : '160',
35
+ is_filter : true,
36
+ is_editable: false,
37
+ }),
38
+ createColumn(model, locale, 'subject_id', {
39
+ width : '280',
40
+ is_filter : true,
41
+ is_editable: false,
42
+ }),
43
+ createColumn(model, locale, 'actor_id', {
44
+ width : '200',
45
+ is_filter : true,
46
+ is_editable: false,
47
+ }),
48
+ createColumn(model, locale, 'project_id.project_name', {
49
+ header_field : 'project_name',
50
+ header_element_type: 'project',
51
+ width : '240',
52
+ is_filter : true,
53
+ is_editable : false,
54
+ }),
55
+ createGoToColumn(model, locale),
56
+ ];
57
+ }
58
+
59
+
60
+ /**
61
+ * Секция `event`: `listing` (лента Activity; team_id на беке из сессии).
62
+ * Runtime-фильтр `project_id` — для project Activity; без значения не гидратируется.
63
+ *
64
+ * @param {Object<string, Object<string, { config: import('../../../types/family_service/typeTableConfiguration.js').typeTableConfiguration }>>} config
65
+ * @returns {void}
66
+ */
67
+ export function bootstrap_event(config)
68
+ {
69
+ const locale = UserService.get_current_language();
70
+
71
+ registerSection(config, 'event', 'listing', build_event_listing_columns(locale), {
72
+ for: createListingFor([ 'project_id' ], {
73
+ add: [ 'subjects', 'actors', 'projects' ],
74
+ }),
75
+ });
76
+ }
@@ -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
+ }