complexqa_frontend_core 1.16.3 → 1.17.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complexqa_frontend_core",
3
- "version": "1.16.3",
3
+ "version": "1.17.1",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
@@ -11,6 +11,7 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "test": "jest --config ../jest.config.cjs",
14
+ "build:dev": "rollup -c rollup.dev.config.js",
14
15
  "build_package": "rollup -c rollup.config.js"
15
16
  },
16
17
  "repository": {
@@ -44,6 +45,8 @@
44
45
  "underscore": "^1.13.6"
45
46
  },
46
47
  "devDependencies": {
48
+ "@rollup/plugin-inject": "^5.0.5",
49
+ "@rollup/plugin-node-resolve": "^16.0.3",
47
50
  "@babel/core": "^7.29.0",
48
51
  "@babel/preset-env": "^7.29.5",
49
52
  "babel": "^6.23.0",
@@ -52,6 +55,7 @@
52
55
  "gulp-uglify": "^3.0.2",
53
56
  "jest": "^30.4.2",
54
57
  "requirejs-babel": "^0.0.9",
58
+ "rollup": "^4.55.1",
55
59
  "rollup-plugin-dts": "^6.2.3"
56
60
  }
57
61
  }
@@ -0,0 +1,120 @@
1
+ import { typeTableColumn } from '../../../types/family_service/typeTableColumn.js';
2
+
3
+ const COLUMN_DEFAULTS = {
4
+ width : '120',
5
+ sort_order : '1',
6
+ cell_classes: '',
7
+ default_sort: '',
8
+ is_sortable : true,
9
+ is_filter : true,
10
+ is_hide : false,
11
+ is_editable : false,
12
+ column_kind : 'data',
13
+ is_required : false,
14
+ is_title : false,
15
+ header_element_type: false,
16
+ };
17
+
18
+
19
+ /**
20
+ * @param {familyGeneralElement} model
21
+ * @param {string} locale
22
+ * @param {string} field
23
+ * @param {object} overrides
24
+ * @returns {typeTableColumn}
25
+ */
26
+ export function createColumn(model, locale, field, overrides = {})
27
+ {
28
+ const header_field = overrides.header_field || field;
29
+ const header_model = overrides.header_model || model;
30
+
31
+ return new typeTableColumn({
32
+ ...COLUMN_DEFAULTS,
33
+ header_name: overrides.header_name ?? header_model.get_attribute_name_translate(header_field, locale),
34
+ field,
35
+ ...overrides,
36
+ });
37
+ }
38
+
39
+
40
+ /**
41
+ * @param {familyGeneralElement} model
42
+ * @param {string} locale
43
+ * @param {object} overrides
44
+ * @returns {typeTableColumn}
45
+ */
46
+ export function createRowSelectColumn(overrides = {})
47
+ {
48
+ return new typeTableColumn({
49
+ ...COLUMN_DEFAULTS,
50
+ header_name : '',
51
+ field : 'select',
52
+ width : '60',
53
+ sort_order : '0',
54
+ is_sortable : false,
55
+ is_filter : false,
56
+ column_kind : 'row_select',
57
+ ...overrides,
58
+ });
59
+ }
60
+
61
+
62
+ /**
63
+ * @param {familyGeneralElement} model
64
+ * @param {string} locale
65
+ * @param {object} overrides
66
+ * @returns {typeTableColumn}
67
+ */
68
+ export function createGoToColumn(model, locale, overrides = {})
69
+ {
70
+ const primary_key = model.get_primary_key();
71
+
72
+ return new typeTableColumn({
73
+ ...COLUMN_DEFAULTS,
74
+ header_name : 'goto',
75
+ field : primary_key,
76
+ width : '80',
77
+ sort_order : '99',
78
+ is_sortable : false,
79
+ is_filter : false,
80
+ column_kind : 'goto',
81
+ ...overrides,
82
+ });
83
+ }
84
+
85
+
86
+ /**
87
+ * @param {familyGeneralElement} model
88
+ * @param {string} locale
89
+ * @param {object} overrides
90
+ * @returns {typeTableColumn}
91
+ */
92
+ export function createPrimaryKeyColumn(model, locale, overrides = {})
93
+ {
94
+ const primary_key = model.get_primary_key();
95
+
96
+ return createColumn(model, locale, primary_key, {
97
+ width : '60',
98
+ default_sort: 'desc',
99
+ is_hide : false,
100
+ ...overrides,
101
+ });
102
+ }
103
+
104
+
105
+ /**
106
+ * @param {familyGeneralElement} model
107
+ * @param {string} locale
108
+ * @param {string} field
109
+ * @param {object} overrides
110
+ * @returns {typeTableColumn}
111
+ */
112
+ export function createDetailsColumn(model, locale, field, overrides = {})
113
+ {
114
+ return createColumn(model, locale, field, {
115
+ sort_order : String(overrides.sort_order ?? 1),
116
+ is_sortable : false,
117
+ is_filter : false,
118
+ ...overrides,
119
+ });
120
+ }
@@ -0,0 +1,60 @@
1
+ import { typeTableConfiguration } from '../../../types/family_service/typeTableConfiguration.js';
2
+ import { typeFOR } from '../../../types/family_service/typeFOR.js';
3
+ import { typeFilter } from '../../../types/family_service/typeFilter.js';
4
+
5
+
6
+ /**
7
+ * @param {object} config
8
+ * @param {string} element_type
9
+ * @param {string} section
10
+ * @param {typeTableColumn[]} columns
11
+ * @param {object} options
12
+ */
13
+ export function registerSection(config, element_type, section, columns, options = {})
14
+ {
15
+ const payload = {
16
+ config: new typeTableConfiguration({
17
+ columns : columns,
18
+ for : options.for || false,
19
+ contained_element_type : options.contained_element_type || false,
20
+ documentation : options.documentation || { description: false, link: false },
21
+ }),
22
+ };
23
+
24
+ if (!config[ element_type ])
25
+ {
26
+ config[ element_type ] = {};
27
+ }
28
+
29
+ config[ element_type ][ section ] = payload;
30
+ }
31
+
32
+
33
+ /**
34
+ * @param {string} attribute
35
+ * @returns {typeFilter}
36
+ */
37
+ export function createRuntimeFilter(attribute)
38
+ {
39
+ return new typeFilter({
40
+ object : { attribute },
41
+ operator: 'EQUAL',
42
+ value : false,
43
+ });
44
+ }
45
+
46
+
47
+ /**
48
+ * @param {string[]} filter_attributes
49
+ * @param {object|false} for_options
50
+ * @returns {typeFOR}
51
+ */
52
+ export function createListingFor(filter_attributes = [ 'project_id' ], for_options = false)
53
+ {
54
+ const filters = filter_attributes.map((attribute) => createRuntimeFilter(attribute));
55
+
56
+ return new typeFOR({
57
+ filters,
58
+ options: for_options || false,
59
+ });
60
+ }
@@ -0,0 +1,76 @@
1
+ import { typeBug } from '../../../types/family_elements/typeBug.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn, createGoToColumn, createPrimaryKeyColumn, createRowSelectColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+
6
+ function build_bug_listing_columns(locale, { include_select = true } = {})
7
+ {
8
+ const model = new typeBug();
9
+ const columns = [];
10
+
11
+ if (include_select)
12
+ {
13
+ columns.push(createRowSelectColumn());
14
+ }
15
+
16
+ columns.push(createPrimaryKeyColumn(model, locale, { is_editable: false }));
17
+ columns.push(createColumn(model, locale, 'bug_title', {
18
+ width : '220',
19
+ is_editable : true,
20
+ is_required : true,
21
+ }));
22
+ columns.push(createColumn(model, locale, 'bug_status', { width: '150', is_editable: true, is_required: true }));
23
+ columns.push(createColumn(model, locale, 'bug_priority', { width: '130', is_editable: true, is_required: true }));
24
+ columns.push(createColumn(model, locale, 'bug_severity', { width: '130', is_editable: true, is_required: true }));
25
+ columns.push(createColumn(model, locale, 'bug_type', { width: '150', is_editable: true, is_required: true }));
26
+ columns.push(createColumn(model, locale, 'bug_resolution', { width: '150', is_editable: true, is_required: true }));
27
+ columns.push(createColumn(model, locale, 'assigned_to', { width: '220', is_editable: true, is_required: true }));
28
+ columns.push(createColumn(model, locale, 'created_at', { width: '150', is_required: true }));
29
+ columns.push(createColumn(model, locale, 'completed_at', { width: '150', is_required: true }));
30
+ columns.push(createGoToColumn(model, locale));
31
+
32
+ return columns;
33
+ }
34
+
35
+
36
+ function build_bug_details_columns(locale)
37
+ {
38
+ const model = new typeBug();
39
+ const fields = [
40
+ 'bug_id',
41
+ 'bug_status',
42
+ 'bug_type',
43
+ 'bug_priority',
44
+ 'bug_severity',
45
+ 'bug_resolution',
46
+ 'reporter_id',
47
+ 'assigned_to',
48
+ 'bug_build_version',
49
+ 'bug_affected_version',
50
+ 'bug_fixed_version',
51
+ 'duplicate_of_id',
52
+ ];
53
+
54
+ return fields.map((field, index) => createColumn(model, locale, field, {
55
+ sort_order : String(index + 1),
56
+ is_editable : field !== 'bug_id',
57
+ is_sortable : false,
58
+ is_filter : false,
59
+ }));
60
+ }
61
+
62
+
63
+ export function bootstrap_bug(config)
64
+ {
65
+ const locale = UserService.get_current_language();
66
+
67
+ registerSection(config, 'bug', 'listing', build_bug_listing_columns(locale), {
68
+ for: createListingFor([ 'project_id' ]),
69
+ });
70
+
71
+ registerSection(config, 'bug', 'todo', build_bug_listing_columns(locale, { include_select: false }), {
72
+ contained_element_type: 'project',
73
+ });
74
+
75
+ registerSection(config, 'bug', 'details', build_bug_details_columns(locale));
76
+ }
@@ -0,0 +1,59 @@
1
+ import { typeProject } from '../../../types/family_elements/typeProject.js';
2
+ import { typeTableColumn } from '../../../types/family_service/typeTableColumn.js';
3
+ import { UserService } from '../../../services/UserService.js';
4
+ import { createColumn } from '../helpers/column_factory.js';
5
+ import { registerSection } from '../helpers/section_registry.js';
6
+
7
+ function build_project_domain_columns()
8
+ {
9
+ return [
10
+ new typeTableColumn({
11
+ header_name : '#',
12
+ field : 'id',
13
+ width : '60',
14
+ sort_order : '0',
15
+ is_sortable : false,
16
+ is_filter : false,
17
+ is_editable : false,
18
+ }),
19
+ new typeTableColumn({
20
+ header_name : 'name',
21
+ field : 'name',
22
+ width : '200',
23
+ sort_order : '1',
24
+ is_editable : true,
25
+ }),
26
+ new typeTableColumn({
27
+ header_name : 'description',
28
+ field : 'description',
29
+ width : '480',
30
+ sort_order : '2',
31
+ is_editable : true,
32
+ }),
33
+ ];
34
+ }
35
+
36
+
37
+ function build_project_todo_column(locale)
38
+ {
39
+ const model = new typeProject();
40
+
41
+ return [
42
+ createColumn(model, locale, 'project_id', {
43
+ width : '480',
44
+ is_sortable : true,
45
+ is_filter : true,
46
+ is_editable : false,
47
+ header_element_type: 'project',
48
+ }),
49
+ ];
50
+ }
51
+
52
+
53
+ export function bootstrap_project(config)
54
+ {
55
+ const locale = UserService.get_current_language();
56
+
57
+ registerSection(config, 'project', 'domains', build_project_domain_columns());
58
+ registerSection(config, 'project', 'todo_column', build_project_todo_column(locale));
59
+ }
@@ -0,0 +1,42 @@
1
+ import { typeTeam } from '../../../types/family_elements/typeTeam.js';
2
+ import { typeTeamTotalStatistic } from '../../../types/family_contracts/typeTeamTotalStatistic.js';
3
+ import { UserService } from '../../../services/UserService.js';
4
+ import { createColumn } from '../helpers/column_factory.js';
5
+ import { registerSection } from '../helpers/section_registry.js';
6
+
7
+ function build_team_profile_columns(locale)
8
+ {
9
+ const model = new typeTeam();
10
+
11
+ return [
12
+ createColumn(model, locale, 'team_name', {
13
+ width : '480',
14
+ is_sortable : false,
15
+ is_filter : false,
16
+ is_editable : false,
17
+ }),
18
+ ];
19
+ }
20
+
21
+
22
+ function build_team_total_statistic_columns(locale)
23
+ {
24
+ const model = new typeTeamTotalStatistic();
25
+ const fields = [ 'project', 'test_suite', 'test_case', 'test_case_step', 'test_run', 'team_member' ];
26
+
27
+ return fields.map((field, index) => createColumn(model, locale, field, {
28
+ sort_order : String(index + 1),
29
+ is_sortable : false,
30
+ is_filter : false,
31
+ is_editable : false,
32
+ }));
33
+ }
34
+
35
+
36
+ export function bootstrap_team(config)
37
+ {
38
+ const locale = UserService.get_current_language();
39
+
40
+ registerSection(config, 'team', 'profile', build_team_profile_columns(locale));
41
+ registerSection(config, 'team_total_statistic', 'details', build_team_total_statistic_columns(locale));
42
+ }
@@ -0,0 +1,47 @@
1
+ import { typeTeamMember } from '../../../types/family_elements/typeTeamMember.js';
2
+ import { typeUser } from '../../../types/family_elements/typeUser.js';
3
+ import { UserService } from '../../../services/UserService.js';
4
+ import { createColumn } from '../helpers/column_factory.js';
5
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
6
+
7
+ function build_team_member_listing_columns(locale)
8
+ {
9
+ const model = new typeTeamMember();
10
+ const user_model = new typeUser();
11
+
12
+ return [
13
+ createColumn(model, locale, 'user_id.first_name', {
14
+ header_name : user_model.get_attribute_name_translate('first_name', locale),
15
+ width : '200',
16
+ is_filter : false,
17
+ is_editable : false,
18
+ header_element_type: 'user',
19
+ }),
20
+ createColumn(model, locale, 'user_id.last_name', {
21
+ header_name : user_model.get_attribute_name_translate('last_name', locale),
22
+ width : '200',
23
+ is_filter : false,
24
+ is_editable : false,
25
+ header_element_type: 'user',
26
+ }),
27
+ createColumn(model, locale, 'user_id.email', {
28
+ header_name : user_model.get_attribute_name_translate('email', locale),
29
+ width : '200',
30
+ is_filter : false,
31
+ is_editable : false,
32
+ header_element_type: 'user',
33
+ }),
34
+ createColumn(model, locale, 'team_member_status', { width: '160', is_filter: false, is_editable: true }),
35
+ createColumn(model, locale, 'member_role', { width: '200', is_filter: false, is_editable: true }),
36
+ ];
37
+ }
38
+
39
+
40
+ export function bootstrap_team_member(config)
41
+ {
42
+ const locale = UserService.get_current_language();
43
+
44
+ registerSection(config, 'team_member', 'listing', build_team_member_listing_columns(locale), {
45
+ for: createListingFor([], { add: [ 'users' ] }),
46
+ });
47
+ }
@@ -0,0 +1,68 @@
1
+ import { typeTestAccount } from '../../../types/family_elements/typeTestAccount.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn, createGoToColumn, createPrimaryKeyColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+ import { typeTableColumn } from '../../../types/family_service/typeTableColumn.js';
6
+
7
+ function build_test_account_listing_columns(locale)
8
+ {
9
+ const model = new typeTestAccount();
10
+
11
+ return [
12
+ createPrimaryKeyColumn(model, locale),
13
+ createColumn(model, locale, 'resource', { width: '480', is_editable: true, is_required: true }),
14
+ createColumn(model, locale, 'login', { width: '480', is_editable: true, is_required: true }),
15
+ createColumn(model, locale, 'password', { width: '480', is_editable: true }),
16
+ createColumn(model, locale, 'test_account_description', { width: '480', is_editable: true }),
17
+ createColumn(model, locale, 'created_at', { width: '150' }),
18
+ createColumn(model, locale, 'updated_at', { width: '150' }),
19
+ createGoToColumn(model, locale),
20
+ ];
21
+ }
22
+
23
+
24
+ function build_test_account_details_columns(locale)
25
+ {
26
+ const model = new typeTestAccount();
27
+ const fields = [
28
+ 'test_account_id',
29
+ 'project_id',
30
+ 'team_id',
31
+ 'resource',
32
+ 'login',
33
+ 'password',
34
+ 'created_at',
35
+ 'updated_at',
36
+ ];
37
+
38
+ return [
39
+ ...fields.map((field, index) => createColumn(model, locale, field, {
40
+ sort_order : String(index + 1),
41
+ is_editable: [ 'resource', 'login', 'password' ].includes(field),
42
+ is_sortable: false,
43
+ is_filter : false,
44
+ })),
45
+ new typeTableColumn({
46
+ header_name: 'copy',
47
+ field : 'copy',
48
+ width : '80',
49
+ sort_order : '99',
50
+ is_sortable: false,
51
+ is_filter : false,
52
+ is_editable: false,
53
+ column_kind: 'copy',
54
+ }),
55
+ ];
56
+ }
57
+
58
+
59
+ export function bootstrap_test_account(config)
60
+ {
61
+ const locale = UserService.get_current_language();
62
+
63
+ registerSection(config, 'test_account', 'listing', build_test_account_listing_columns(locale), {
64
+ for: createListingFor([ 'project_id' ]),
65
+ });
66
+
67
+ registerSection(config, 'test_account', 'details', build_test_account_details_columns(locale));
68
+ }
@@ -0,0 +1,80 @@
1
+ import { typeTestCase } from '../../../types/family_elements/typeTestCase.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn, createGoToColumn, createPrimaryKeyColumn, createRowSelectColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+
6
+ function build_test_case_listing_columns(locale, { include_select = true, include_goto = true } = {})
7
+ {
8
+ const model = new typeTestCase();
9
+ const columns = [];
10
+
11
+ if (include_select)
12
+ {
13
+ columns.push(createRowSelectColumn());
14
+ }
15
+
16
+ columns.push(createPrimaryKeyColumn(model, locale));
17
+ columns.push(createColumn(model, locale, 'test_case_title', {
18
+ width : '480',
19
+ is_editable : true,
20
+ is_required : true,
21
+ is_title : true,
22
+ }));
23
+ columns.push(createColumn(model, locale, 'assigned_to', { width: '220', is_editable: true }));
24
+ columns.push(createColumn(model, locale, 'test_case_time_to_execute', { width: '80', is_editable: true, is_required: true }));
25
+ columns.push(createColumn(model, locale, 'test_case_complexity', { width: '80', is_editable: true, is_required: true }));
26
+ columns.push(createColumn(model, locale, 'test_case_importance', { width: '80', is_editable: true, is_required: true }));
27
+ columns.push(createColumn(model, locale, 'test_case_status', { width: '150', is_editable: true, is_required: true }));
28
+
29
+ if (include_goto)
30
+ {
31
+ columns.push(createGoToColumn(model, locale));
32
+ }
33
+
34
+ return columns;
35
+ }
36
+
37
+
38
+ export function bootstrap_test_case(config)
39
+ {
40
+ const locale = UserService.get_current_language();
41
+
42
+ registerSection(config, 'test_case', 'listing', build_test_case_listing_columns(locale), {
43
+ for: createListingFor([ 'project_id', 'test_suite_id' ]),
44
+ });
45
+
46
+ registerSection(config, 'test_case', 'todo', build_test_case_listing_columns(locale, {
47
+ include_select: false,
48
+ }), {
49
+ contained_element_type: 'project',
50
+ });
51
+
52
+ registerSection(config, 'test_case', 'picker', [
53
+ createRowSelectColumn({ width: '52' }),
54
+ createColumn(new typeTestCase(), locale, 'test_case_title', {
55
+ width : '480',
56
+ is_sortable : false,
57
+ is_filter : false,
58
+ }),
59
+ createColumn(new typeTestCase(), locale, 'assigned_to', {
60
+ width : '220',
61
+ is_sortable : false,
62
+ is_filter : false,
63
+ }),
64
+ createColumn(new typeTestCase(), locale, 'test_case_time_to_execute', {
65
+ width : '80',
66
+ is_sortable : false,
67
+ is_filter : false,
68
+ }),
69
+ createColumn(new typeTestCase(), locale, 'test_case_complexity', {
70
+ width : '80',
71
+ is_sortable : false,
72
+ is_filter : false,
73
+ }),
74
+ createColumn(new typeTestCase(), locale, 'test_case_importance', {
75
+ width : '80',
76
+ is_sortable : false,
77
+ is_filter : false,
78
+ }),
79
+ ]);
80
+ }
@@ -0,0 +1,42 @@
1
+ import { typeTestCaseStep } from '../../../types/family_elements/typeTestCaseStep.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+ import { typeTableColumn } from '../../../types/family_service/typeTableColumn.js';
6
+
7
+ function build_test_case_step_columns(locale)
8
+ {
9
+ const model = new typeTestCaseStep();
10
+
11
+ return [
12
+ createColumn(model, locale, 'sort_order', {
13
+ width : '150',
14
+ sort_order : '0',
15
+ default_sort: 'asc',
16
+ is_editable : true,
17
+ }),
18
+ createColumn(model, locale, 'step_element', { width: '200', is_editable: true }),
19
+ createColumn(model, locale, 'step_element_action', { width: '200', is_editable: true }),
20
+ createColumn(model, locale, 'step_excepted_result', { width: '480', is_editable: true }),
21
+ new typeTableColumn({
22
+ header_name : '',
23
+ field : 'test_case_step_id',
24
+ width : '80',
25
+ sort_order : '99',
26
+ is_sortable : false,
27
+ is_filter : false,
28
+ is_editable : false,
29
+ column_kind : 'sort_action',
30
+ }),
31
+ ];
32
+ }
33
+
34
+
35
+ export function bootstrap_test_case_step(config)
36
+ {
37
+ const locale = UserService.get_current_language();
38
+
39
+ registerSection(config, 'test_case_step', 'embedded', build_test_case_step_columns(locale), {
40
+ for: createListingFor([ 'test_case_id', 'test_case_step_type' ]),
41
+ });
42
+ }
@@ -0,0 +1,47 @@
1
+ import { typeTestRun } from '../../../types/family_elements/typeTestRun.js';
2
+ import { UserService } from '../../../services/UserService.js';
3
+ import { createColumn, createGoToColumn, createPrimaryKeyColumn, createRowSelectColumn } from '../helpers/column_factory.js';
4
+ import { createListingFor, registerSection } from '../helpers/section_registry.js';
5
+
6
+ function build_test_run_listing_columns(locale, { include_select = true } = {})
7
+ {
8
+ const model = new typeTestRun();
9
+ const columns = [];
10
+
11
+ if (include_select)
12
+ {
13
+ columns.push(createRowSelectColumn());
14
+ }
15
+
16
+ columns.push(createPrimaryKeyColumn(model, locale, { is_editable: true }));
17
+ columns.push(createColumn(model, locale, 'test_run_name', {
18
+ width : '480',
19
+ is_editable : true,
20
+ is_required : true,
21
+ }));
22
+ columns.push(createColumn(model, locale, 'test_run_description', {
23
+ width : '480',
24
+ is_editable : false,
25
+ is_required : true,
26
+ }));
27
+ columns.push(createColumn(model, locale, 'assigned_to', { width: '220', is_editable: true, is_required: true }));
28
+ columns.push(createColumn(model, locale, 'test_run_status', { width: '150', is_editable: true, is_required: true }));
29
+ columns.push(createColumn(model, locale, 'completed_at', { width: '150', is_required: true }));
30
+ columns.push(createGoToColumn(model, locale));
31
+
32
+ return columns;
33
+ }
34
+
35
+
36
+ export function bootstrap_test_run(config)
37
+ {
38
+ const locale = UserService.get_current_language();
39
+
40
+ registerSection(config, 'test_run', 'listing', build_test_run_listing_columns(locale), {
41
+ for: createListingFor([ 'project_id' ]),
42
+ });
43
+
44
+ registerSection(config, 'test_run', 'todo', build_test_run_listing_columns(locale, { include_select: false }), {
45
+ contained_element_type: 'project',
46
+ });
47
+ }