complexqa_frontend_core 1.18.7 → 1.19.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complexqa_frontend_core",
3
- "version": "1.18.7",
3
+ "version": "1.19.2",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,18 @@
1
+ import { ApiAbstractElementClass } from './api_abstract_element_class.js';
2
+ import { typeBugRelation } from '../types/family_relation/typeBugRelation.js';
3
+
4
+ /**
5
+ * CRUD / Search для bug_relation.
6
+ *
7
+ * @version v.0.1 (13/06/2026)
8
+ */
9
+ export class BugRelationApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'bug_relation';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeBugRelation);
17
+ }
18
+ }
@@ -12,6 +12,7 @@ import { UserProfileApi } from "./user_profile_api.js";
12
12
  import { TaskApi } from "./task_api.js";
13
13
  import { TestAccountApi } from "./test_account_api.js";
14
14
  import { BugApi } from "./bug_api.js";
15
+ import { BugRelationApi } from "./bug_relation_api.js";
15
16
  import { ContextBrowserApi } from "./context/context_browser_api.js";
16
17
  import { ContextDeploymentTargetApi } from "./context/context_deployment_target_api.js";
17
18
  import { ContextDevicesApi } from "./context/context_devices_api.js";
@@ -154,6 +155,7 @@ export class Api
154
155
  this.task = new TaskApi(payload);
155
156
  this.test_account = new TestAccountApi(payload);
156
157
  this.bug = new BugApi(payload);
158
+ this.bug_relation = new BugRelationApi(payload);
157
159
  this.execution_context = new ExecutionContextApi(payload);
158
160
 
159
161
  this.reference = this.bootstrap_reference(payload)
@@ -2,6 +2,7 @@ import { typeTestCase } from '../../../types/family_elements/typeTestCase.js';
2
2
  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
+ import { typeBugRelation } from '../../../types/family_relation/typeBugRelation.js';
5
6
  import { typeTestRunResult } from '../../../types/family_elements/typeTestRunResult.js';
6
7
  import { typeTestAccount } from '../../../types/family_elements/typeTestAccount.js';
7
8
  import { typeExecutionContext } from '../../../types/family_context/typeExecutionContext.js';
@@ -26,6 +27,7 @@ export const TABLE_ELEMENT_MODELS = {
26
27
  project : typeProject,
27
28
  test_run : typeTestRun,
28
29
  bug : typeBug,
30
+ bug_relation : typeBugRelation,
29
31
  test_run_result: typeTestRunResult,
30
32
  test_account : typeTestAccount,
31
33
  execution_context : typeExecutionContext,
@@ -0,0 +1,57 @@
1
+ import { typeBugRelation } from '../../../types/family_relation/typeBugRelation.js';
2
+ import { typeTestCase } from '../../../types/family_elements/typeTestCase.js';
3
+ import { UserService } from '../../../services/UserService.js';
4
+ import { createColumn, createGoToColumn } from '../helpers/column_factory.js';
5
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
6
+
7
+ /**
8
+ * Колонки связанных тест-кейсов на странице bug/details.
9
+ * Поля совпадают с test_case × listing, данные — через hydrate element_id.
10
+ *
11
+ * @param {string} locale
12
+ * @returns {import('../../../types/family_service/typeTableColumn.js').typeTableColumn[]}
13
+ */
14
+ function build_bug_relation_test_cases_columns(locale)
15
+ {
16
+ const relation_model = new typeBugRelation();
17
+ const test_case_model = new typeTestCase();
18
+ const columns = [];
19
+
20
+ const tcColumn = (field, overrides = {}) => createColumn(relation_model, locale, `element_id.${ field }`, {
21
+ header_field : field,
22
+ header_element_type : 'test_case',
23
+ is_editable : false,
24
+ ...overrides,
25
+ });
26
+
27
+ columns.push(tcColumn('test_case_id', { width: '60', default_sort: 'desc' }));
28
+ columns.push(tcColumn('test_case_title', {
29
+ width : '480',
30
+ is_required : true,
31
+ is_title : true,
32
+ }));
33
+ columns.push(tcColumn('assigned_to', { width: '220' }));
34
+ columns.push(tcColumn('test_case_time_to_execute', { width: '80', is_required: true }));
35
+ columns.push(tcColumn('test_case_complexity', { width: '80', is_required: true }));
36
+ columns.push(tcColumn('test_case_importance', { width: '80', is_required: true }));
37
+ columns.push(tcColumn('test_case_status', { width: '150', is_required: true }));
38
+ columns.push(createGoToColumn(test_case_model, locale, { field: 'element_id' }));
39
+
40
+ return columns;
41
+ }
42
+
43
+
44
+ /**
45
+ * Секции `bug_relation`: `test_cases`.
46
+ *
47
+ * @param {Object<string, Object<string, { config: import('../../../types/family_service/typeTableConfiguration.js').typeTableConfiguration }>>} config
48
+ * @returns {void}
49
+ */
50
+ export function bootstrap_bug_relation(config)
51
+ {
52
+ const locale = UserService.get_current_language();
53
+
54
+ registerSection(config, 'bug_relation', 'test_cases', build_bug_relation_test_cases_columns(locale), {
55
+ for: createListingFor([ 'bug_id', 'relation_type' ], { add: [ 'elements' ] }),
56
+ });
57
+ }
@@ -1,5 +1,6 @@
1
1
  import { abstractAppConfiguration } from '../abstract_app_configuration.js';
2
2
  import { bootstrap_bug } from './sections/bug.js';
3
+ import { bootstrap_bug_relation } from './sections/bug_relation.js';
3
4
  import { bootstrap_test_case } from './sections/test_case.js';
4
5
  import { bootstrap_test_case_step } from './sections/test_case_step.js';
5
6
  import { bootstrap_test_run } from './sections/test_run.js';
@@ -106,6 +107,7 @@ export class TableConfiguration extends abstractAppConfiguration
106
107
  }
107
108
 
108
109
  bootstrap_bug(this.config);
110
+ bootstrap_bug_relation(this.config);
109
111
  bootstrap_test_case(this.config);
110
112
  bootstrap_test_case_step(this.config);
111
113
  bootstrap_test_run(this.config);
package/publish/index.js CHANGED
@@ -16,6 +16,9 @@ export { typeTestRunResult } from './types/family_elements/typeTestRunResult.js'
16
16
  export { typeTestAccount } from './types/family_elements/typeTestAccount.js'
17
17
  export {typeBug} from './types/family_elements/typeBug.js';
18
18
 
19
+ export { familyRelation } from './types/core/1_familyRelation.js';
20
+ export { typeBugRelation } from './types/family_relation/typeBugRelation.js';
21
+
19
22
  export { familyContext } from './types/core/1_familyContext.js';
20
23
  export { typeBrowserContext } from './types/family_context/typeBrowserContext.js';
21
24
  export { typeOsContext } from './types/family_context/typeOsContext.js';
@@ -0,0 +1,83 @@
1
+ import { familyGeneralElement } from './0_familyGeneralElement.js';
2
+
3
+ /**
4
+ * Базовое семейство junction-типов (связи N-к-ко-многим между main elements).
5
+ *
6
+ * Каждый наследник описывает свой домен (bug↔TMS, bug↔context, …),
7
+ * без единого god-type для всех связей.
8
+ *
9
+ * @version v.0.1 (13/06/2026)
10
+ */
11
+ export class familyRelation extends familyGeneralElement
12
+ {
13
+ /**
14
+ * FK на «главный» элемент связи (у typeBugRelation — bug_id).
15
+ *
16
+ * @type {string|false}
17
+ */
18
+ source_key = false;
19
+
20
+ /**
21
+ * Polymorphic target id (обычно element_id).
22
+ *
23
+ * @type {string}
24
+ */
25
+ target_key = 'element_id';
26
+
27
+ /**
28
+ * Enum-поле типа цели (relation_type, …).
29
+ *
30
+ * @type {string}
31
+ */
32
+ relation_type_key = 'relation_type';
33
+
34
+
35
+ constructor(data = false)
36
+ {
37
+ super();
38
+ }
39
+
40
+
41
+ /**
42
+ * @returns {string[]}
43
+ */
44
+ static get_relation_type_values()
45
+ {
46
+ return [];
47
+ }
48
+
49
+
50
+ /**
51
+ * @returns {Object<string, { type_token: string, primary_key: string, api_key: string }>}
52
+ */
53
+ static get_relation_target_map()
54
+ {
55
+ return {};
56
+ }
57
+
58
+
59
+ /**
60
+ * @param {string} relation_type
61
+ * @returns {object|false}
62
+ */
63
+ static resolve_relation_target(relation_type)
64
+ {
65
+ const map = this.get_relation_target_map();
66
+
67
+ return map?.[ relation_type ] || false;
68
+ }
69
+
70
+
71
+ get_element_name()
72
+ {
73
+ const relation_type = this?.[ this.relation_type_key ];
74
+ const element_id = this?.[ this.target_key ];
75
+
76
+ if (relation_type && element_id)
77
+ {
78
+ return `${ relation_type }:${ element_id }`;
79
+ }
80
+
81
+ return String(this?.[ this.get_primary_key() ] ?? '');
82
+ }
83
+ }
@@ -0,0 +1,122 @@
1
+ import { is_object } from '../../utils/utils.js';
2
+ import _ from 'underscore';
3
+ import { familyRelation } from '../core/1_familyRelation.js';
4
+
5
+ /**
6
+ * Связь бага с сущностью TMS: test case, test run, test run result.
7
+ *
8
+ * @see docs/Relations/bug-relation-docs.MD
9
+ *
10
+ * @version v.0.1 (13/06/2026)
11
+ */
12
+ export class typeBugRelation extends familyRelation
13
+ {
14
+ bug_relation_id;
15
+ bug_id;
16
+ relation_type;
17
+ element_id;
18
+
19
+ source_key = 'bug_id';
20
+ target_key = 'element_id';
21
+ relation_type_key = 'relation_type';
22
+
23
+ primary_key = 'bug_relation_id';
24
+ api_key = 'bug_relation';
25
+
26
+ static relation_target_map = {
27
+ test_case_id : { type_token: 'typeTestCase', primary_key: 'test_case_id', api_key: 'test_case' },
28
+ test_run_id : { type_token: 'typeTestRun', primary_key: 'test_run_id', api_key: 'test_run' },
29
+ test_run_result_id: { type_token: 'typeTestRunResult', primary_key: 'test_run_result_id', api_key: 'test_run_result' },
30
+ };
31
+
32
+ structure_scheme = {
33
+ bug_relation_id: 'integer | require',
34
+ bug_id : 'integer | typeBug | require',
35
+ relation_type : 'string | enum | require',
36
+ element_id : 'integer | require',
37
+ };
38
+
39
+ create_scheme = [
40
+ 'bug_id',
41
+ 'relation_type',
42
+ 'element_id',
43
+ ];
44
+
45
+ available_enum_values = {
46
+ relation_type: typeBugRelation.get_relation_type_values(),
47
+ };
48
+
49
+ enum_value_translate_matrix = {
50
+ relation_type: {
51
+ en: {
52
+ test_case_id : 'Test case',
53
+ test_run_id : 'Test run',
54
+ test_run_result_id: 'Test run result',
55
+ },
56
+ ru: {
57
+ test_case_id : 'Тест-кейс',
58
+ test_run_id : 'Прогон',
59
+ test_run_result_id: 'Результат прогона',
60
+ },
61
+ },
62
+ };
63
+
64
+ attribute_name_translate_matrix = {
65
+ en: {
66
+ bug_relation_id: 'ID',
67
+ bug_id : 'Bug',
68
+ relation_type : 'Relation type',
69
+ element_id : 'Linked element',
70
+ },
71
+ ru: {
72
+ bug_relation_id: 'ID',
73
+ bug_id : 'Баг',
74
+ relation_type : 'Тип связи',
75
+ element_id : 'Связанный элемент',
76
+ },
77
+ };
78
+
79
+
80
+ static get_relation_type_values()
81
+ {
82
+ return Object.keys(typeBugRelation.relation_target_map);
83
+ }
84
+
85
+
86
+ static get_relation_target_map()
87
+ {
88
+ return typeBugRelation.relation_target_map;
89
+ }
90
+
91
+
92
+ /**
93
+ * @param {object|false|undefined} data
94
+ * @returns {typeBugRelation}
95
+ */
96
+ constructor(data = false)
97
+ {
98
+ super();
99
+
100
+ if (data && is_object(data))
101
+ {
102
+ _.mapObject(data, (value, key) =>
103
+ {
104
+ if (this.hasOwnProperty(key))
105
+ {
106
+ this[ key ] = value;
107
+ }
108
+ });
109
+ }
110
+
111
+ return this;
112
+ }
113
+
114
+
115
+ /**
116
+ * @returns {object|false}
117
+ */
118
+ get_relation_target_meta()
119
+ {
120
+ return typeBugRelation.resolve_relation_target(this.relation_type);
121
+ }
122
+ }