@rancher/shell 0.3.20 → 0.3.21

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 (43) hide show
  1. package/assets/translations/en-us.yaml +4 -2
  2. package/components/Questions/Array.vue +2 -2
  3. package/components/Questions/Boolean.vue +7 -1
  4. package/components/Questions/CloudCredential.vue +1 -0
  5. package/components/Questions/Enum.vue +21 -2
  6. package/components/Questions/Float.vue +8 -3
  7. package/components/Questions/Int.vue +8 -3
  8. package/components/Questions/Question.js +72 -0
  9. package/components/Questions/QuestionMap.vue +2 -1
  10. package/components/Questions/Radio.vue +33 -0
  11. package/components/Questions/Reference.vue +2 -0
  12. package/components/Questions/String.vue +8 -3
  13. package/components/Questions/Yaml.vue +46 -0
  14. package/components/Questions/__tests__/Boolean.test.ts +123 -0
  15. package/components/Questions/__tests__/Float.test.ts +123 -0
  16. package/components/Questions/__tests__/Int.test.ts +123 -0
  17. package/components/Questions/__tests__/String.test.ts +123 -0
  18. package/components/Questions/__tests__/Yaml.test.ts +123 -0
  19. package/components/Questions/index.vue +8 -1
  20. package/components/ResourceTable.vue +6 -12
  21. package/components/SideNav.vue +634 -0
  22. package/components/__tests__/NamespaceFilter.test.ts +3 -4
  23. package/components/form/UnitInput.vue +1 -0
  24. package/components/form/__tests__/KeyValue.test.ts +2 -1
  25. package/components/form/__tests__/UnitInput.test.ts +2 -2
  26. package/components/formatter/LinkName.vue +12 -1
  27. package/components/nav/WorkspaceSwitcher.vue +4 -1
  28. package/core/plugin-helpers.js +4 -1
  29. package/core/types.ts +1 -0
  30. package/edit/fleet.cattle.io.gitrepo.vue +7 -0
  31. package/layouts/default.vue +11 -597
  32. package/middleware/authenticated.js +2 -14
  33. package/models/fleet.cattle.io.gitrepo.js +3 -1
  34. package/package.json +1 -1
  35. package/pages/c/_cluster/fleet/index.vue +4 -0
  36. package/pages/c/_cluster/uiplugins/index.vue +3 -3
  37. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +8 -0
  38. package/rancher-components/components/Form/Radio/RadioButton.test.ts +7 -3
  39. package/types/shell/index.d.ts +2 -0
  40. package/utils/auth.js +17 -0
  41. package/utils/object.js +0 -1
  42. package/utils/validators/__tests__/cidr.test.ts +33 -0
  43. package/utils/validators/cidr.js +5 -0
@@ -0,0 +1,123 @@
1
+ import Questions from '@shell/components/Questions';
2
+ import { mount } from '@vue/test-utils';
3
+ import { _EDIT } from '@shell/config/query-params';
4
+ const defaultStubs = {
5
+ Tab: true,
6
+ Tabbed: true,
7
+ };
8
+ const defaultGetters = {
9
+ currentStore: () => 'current_store',
10
+ 'management/schemaFor': jest.fn(),
11
+ 'current_store/all': jest.fn(),
12
+ 'i18n/t': jest.fn(),
13
+ 'i18n/withFallback': jest.fn((key, args, fallback) => fallback),
14
+ };
15
+
16
+ describe('the Int Component', () => {
17
+ it('input field is present', () => {
18
+ const wrapper = mount(Questions, {
19
+ propsData: {
20
+ value: {},
21
+ targetNamespace: 'test',
22
+ source: [{
23
+ variable: 'var_name',
24
+ type: 'int',
25
+ label: '',
26
+ }],
27
+ mode: _EDIT
28
+ },
29
+ mocks: { $store: { getters: defaultGetters } },
30
+ stubs: defaultStubs,
31
+ });
32
+
33
+ const inputFields = wrapper.findAll('[data-testid="int-input-var_name"]');
34
+
35
+ expect(inputFields).toHaveLength(1);
36
+
37
+ const descriptionFields = wrapper.findAll('[data-testid="int-description-var_name"]');
38
+
39
+ expect(descriptionFields).toHaveLength(0);
40
+
41
+ const labelFields = wrapper.findAll('[data-testid="int-row-var_name"] label');
42
+
43
+ expect(labelFields).toHaveLength(1);
44
+ expect(labelFields.at(0).text()).toBe('var_name');
45
+ });
46
+
47
+ it('description is present', () => {
48
+ const wrapper = mount(Questions, {
49
+ propsData: {
50
+ value: {},
51
+ targetNamespace: 'test',
52
+ source: [{
53
+ variable: 'var_name',
54
+ type: 'int',
55
+ description: 'test description'
56
+ }],
57
+ mode: _EDIT
58
+ },
59
+ mocks: { $store: { getters: defaultGetters } },
60
+ stubs: defaultStubs,
61
+ });
62
+
63
+ const inputFields = wrapper.findAll('[data-testid="int-input-var_name"]');
64
+
65
+ expect(inputFields).toHaveLength(1);
66
+
67
+ const descriptionFields = wrapper.findAll('[data-testid="int-description-var_name"]');
68
+
69
+ expect(descriptionFields).toHaveLength(1);
70
+ expect(descriptionFields.at(0).text()).toBe('test description');
71
+ });
72
+
73
+ it('label is present', () => {
74
+ const wrapper = mount(Questions, {
75
+ propsData: {
76
+ value: {},
77
+ targetNamespace: 'test',
78
+ source: [{
79
+ variable: 'var_name',
80
+ type: 'int',
81
+ label: 'test label'
82
+ }],
83
+ mode: _EDIT
84
+ },
85
+ mocks: { $store: { getters: defaultGetters } },
86
+ stubs: defaultStubs,
87
+ });
88
+
89
+ const inputFields = wrapper.findAll('[data-testid="int-input-var_name"]');
90
+
91
+ expect(inputFields).toHaveLength(1);
92
+
93
+ const labelFields = wrapper.findAll('[data-testid="int-row-var_name"] label');
94
+
95
+ expect(labelFields).toHaveLength(1);
96
+ expect(labelFields.at(0).text()).toBe('test label');
97
+ });
98
+
99
+ it('tooltip is present', () => {
100
+ const wrapper = mount(Questions, {
101
+ propsData: {
102
+ value: {},
103
+ targetNamespace: 'test',
104
+ source: [{
105
+ variable: 'var_name',
106
+ type: 'int',
107
+ tooltip: 'test tooltip'
108
+ }],
109
+ mode: _EDIT
110
+ },
111
+ mocks: { $store: { getters: defaultGetters } },
112
+ stubs: defaultStubs,
113
+ });
114
+
115
+ const inputFields = wrapper.findAll('[data-testid="int-input-var_name"]');
116
+
117
+ expect(inputFields).toHaveLength(1);
118
+
119
+ const labelFields = wrapper.findAll('[data-testid="int-row-var_name"] .labeled-tooltip');
120
+
121
+ expect(labelFields).toHaveLength(1);
122
+ });
123
+ });
@@ -0,0 +1,123 @@
1
+ import Questions from '@shell/components/Questions';
2
+ import { mount } from '@vue/test-utils';
3
+ import { _EDIT } from '@shell/config/query-params';
4
+ const defaultStubs = {
5
+ Tab: true,
6
+ Tabbed: true,
7
+ };
8
+ const defaultGetters = {
9
+ currentStore: () => 'current_store',
10
+ 'management/schemaFor': jest.fn(),
11
+ 'current_store/all': jest.fn(),
12
+ 'i18n/t': jest.fn(),
13
+ 'i18n/withFallback': jest.fn((key, args, fallback) => fallback),
14
+ };
15
+
16
+ describe('the String Component', () => {
17
+ it('input field is present', () => {
18
+ const wrapper = mount(Questions, {
19
+ propsData: {
20
+ value: {},
21
+ targetNamespace: 'test',
22
+ source: [{
23
+ variable: 'var_name',
24
+ type: 'string',
25
+ label: '',
26
+ }],
27
+ mode: _EDIT
28
+ },
29
+ mocks: { $store: { getters: defaultGetters } },
30
+ stubs: defaultStubs,
31
+ });
32
+
33
+ const inputFields = wrapper.findAll('[data-testid="string-input-var_name"]');
34
+
35
+ expect(inputFields).toHaveLength(1);
36
+
37
+ const descriptionFields = wrapper.findAll('[data-testid="string-description-var_name"]');
38
+
39
+ expect(descriptionFields).toHaveLength(0);
40
+
41
+ const labelFields = wrapper.findAll('[data-testid="string-row-var_name"] label');
42
+
43
+ expect(labelFields).toHaveLength(1);
44
+ expect(labelFields.at(0).text()).toBe('var_name');
45
+ });
46
+
47
+ it('description is present', () => {
48
+ const wrapper = mount(Questions, {
49
+ propsData: {
50
+ value: {},
51
+ targetNamespace: 'test',
52
+ source: [{
53
+ variable: 'var_name',
54
+ type: 'string',
55
+ description: 'test description'
56
+ }],
57
+ mode: _EDIT
58
+ },
59
+ mocks: { $store: { getters: defaultGetters } },
60
+ stubs: defaultStubs,
61
+ });
62
+
63
+ const inputFields = wrapper.findAll('[data-testid="string-input-var_name"]');
64
+
65
+ expect(inputFields).toHaveLength(1);
66
+
67
+ const descriptionFields = wrapper.findAll('[data-testid="string-description-var_name"]');
68
+
69
+ expect(descriptionFields).toHaveLength(1);
70
+ expect(descriptionFields.at(0).text()).toBe('test description');
71
+ });
72
+
73
+ it('label is present', () => {
74
+ const wrapper = mount(Questions, {
75
+ propsData: {
76
+ value: {},
77
+ targetNamespace: 'test',
78
+ source: [{
79
+ variable: 'var_name',
80
+ type: 'string',
81
+ label: 'test label'
82
+ }],
83
+ mode: _EDIT
84
+ },
85
+ mocks: { $store: { getters: defaultGetters } },
86
+ stubs: defaultStubs,
87
+ });
88
+
89
+ const inputFields = wrapper.findAll('[data-testid="string-input-var_name"]');
90
+
91
+ expect(inputFields).toHaveLength(1);
92
+
93
+ const labelFields = wrapper.findAll('[data-testid="string-row-var_name"] label');
94
+
95
+ expect(labelFields).toHaveLength(1);
96
+ expect(labelFields.at(0).text()).toBe('test label');
97
+ });
98
+
99
+ it('tooltip is present', () => {
100
+ const wrapper = mount(Questions, {
101
+ propsData: {
102
+ value: {},
103
+ targetNamespace: 'test',
104
+ source: [{
105
+ variable: 'var_name',
106
+ type: 'string',
107
+ tooltip: 'test tooltip'
108
+ }],
109
+ mode: _EDIT
110
+ },
111
+ mocks: { $store: { getters: defaultGetters } },
112
+ stubs: defaultStubs,
113
+ });
114
+
115
+ const inputFields = wrapper.findAll('[data-testid="string-input-var_name"]');
116
+
117
+ expect(inputFields).toHaveLength(1);
118
+
119
+ const labelFields = wrapper.findAll('[data-testid="string-row-var_name"] .labeled-tooltip');
120
+
121
+ expect(labelFields).toHaveLength(1);
122
+ });
123
+ });
@@ -0,0 +1,123 @@
1
+ import Questions from '@shell/components/Questions';
2
+ import { mount } from '@vue/test-utils';
3
+ import { _EDIT } from '@shell/config/query-params';
4
+ const defaultStubs = {
5
+ Tab: true,
6
+ Tabbed: true,
7
+ };
8
+ const defaultGetters = {
9
+ currentStore: () => 'current_store',
10
+ 'management/schemaFor': jest.fn(),
11
+ 'current_store/all': jest.fn(),
12
+ 'i18n/t': jest.fn(),
13
+ 'i18n/withFallback': jest.fn((key, args, fallback) => fallback),
14
+ };
15
+
16
+ describe('the yaml Component', () => {
17
+ it('input field is present', () => {
18
+ const wrapper = mount(Questions, {
19
+ propsData: {
20
+ value: {},
21
+ targetNamespace: 'test',
22
+ source: [{
23
+ variable: 'var_name',
24
+ type: 'yaml',
25
+ label: '',
26
+ }],
27
+ mode: _EDIT
28
+ },
29
+ mocks: { $store: { getters: defaultGetters } },
30
+ stubs: defaultStubs,
31
+ });
32
+
33
+ const inputFields = wrapper.findAll('[data-testid="yaml-input-var_name"]');
34
+
35
+ expect(inputFields).toHaveLength(1);
36
+
37
+ const descriptionFields = wrapper.findAll('[data-testid="yaml-description-var_name"]');
38
+
39
+ expect(descriptionFields).toHaveLength(0);
40
+
41
+ const labelFields = wrapper.findAll('[data-testid="yaml-row-var_name"] h3');
42
+
43
+ expect(labelFields).toHaveLength(1);
44
+ expect(labelFields.at(0).text()).toBe('var_name');
45
+ });
46
+
47
+ it('description is present', () => {
48
+ const wrapper = mount(Questions, {
49
+ propsData: {
50
+ value: {},
51
+ targetNamespace: 'test',
52
+ source: [{
53
+ variable: 'var_name',
54
+ type: 'yaml',
55
+ description: 'test description'
56
+ }],
57
+ mode: _EDIT
58
+ },
59
+ mocks: { $store: { getters: defaultGetters } },
60
+ stubs: defaultStubs,
61
+ });
62
+
63
+ const inputFields = wrapper.findAll('[data-testid="yaml-input-var_name"]');
64
+
65
+ expect(inputFields).toHaveLength(1);
66
+
67
+ const descriptionFields = wrapper.findAll('[data-testid="yaml-description-var_name"]');
68
+
69
+ expect(descriptionFields).toHaveLength(1);
70
+ expect(descriptionFields.at(0).text()).toBe('test description');
71
+ });
72
+
73
+ it('label is present', () => {
74
+ const wrapper = mount(Questions, {
75
+ propsData: {
76
+ value: {},
77
+ targetNamespace: 'test',
78
+ source: [{
79
+ variable: 'var_name',
80
+ type: 'yaml',
81
+ label: 'test label'
82
+ }],
83
+ mode: _EDIT
84
+ },
85
+ mocks: { $store: { getters: defaultGetters } },
86
+ stubs: defaultStubs,
87
+ });
88
+
89
+ const inputFields = wrapper.findAll('[data-testid="yaml-input-var_name"]');
90
+
91
+ expect(inputFields).toHaveLength(1);
92
+
93
+ const labelFields = wrapper.findAll('[data-testid="yaml-row-var_name"] h3');
94
+
95
+ expect(labelFields).toHaveLength(1);
96
+ expect(labelFields.at(0).text()).toBe('test label');
97
+ });
98
+
99
+ it('tooltip is present', () => {
100
+ const wrapper = mount(Questions, {
101
+ propsData: {
102
+ value: {},
103
+ targetNamespace: 'test',
104
+ source: [{
105
+ variable: 'var_name',
106
+ type: 'yaml',
107
+ tooltip: 'test tooltip'
108
+ }],
109
+ mode: _EDIT
110
+ },
111
+ mocks: { $store: { getters: defaultGetters } },
112
+ stubs: defaultStubs,
113
+ });
114
+
115
+ const inputFields = wrapper.findAll('[data-testid="yaml-input-var_name"]');
116
+
117
+ expect(inputFields).toHaveLength(1);
118
+
119
+ const labelFields = wrapper.findAll('[data-testid="yaml-row-var_name"] .has-tooltip');
120
+
121
+ expect(labelFields).toHaveLength(1);
122
+ });
123
+ });
@@ -13,12 +13,17 @@ import ArrayType from './Array';
13
13
  import MapType from './QuestionMap';
14
14
  import ReferenceType from './Reference';
15
15
  import CloudCredentialType from './CloudCredential';
16
+ import RadioType from './Radio';
17
+ import YamlType from './Yaml';
16
18
 
17
19
  export const knownTypes = {
18
20
  string: StringType,
19
- hostname: StringType, // @TODO
21
+ hostname: StringType,
20
22
  multiline: StringType,
21
23
  password: StringType,
24
+ ipaddr: StringType,
25
+ cidr: StringType,
26
+ cron: StringType,
22
27
  boolean: BooleanType,
23
28
  enum: EnumType,
24
29
  int: IntType,
@@ -30,6 +35,8 @@ export const knownTypes = {
30
35
  storageclass: ReferenceType,
31
36
  pvc: ReferenceType,
32
37
  cloudcredential: CloudCredentialType,
38
+ radio: RadioType,
39
+ yaml: YamlType,
33
40
  };
34
41
 
35
42
  export function componentForQuestion(q) {
@@ -7,6 +7,7 @@ import SortableTable from '@shell/components/SortableTable';
7
7
  import { NAMESPACE, AGE } from '@shell/config/table-headers';
8
8
  import { findBy } from '@shell/utils/array';
9
9
  import { ExtensionPoint, TableColumnLocation } from '@shell/core/types';
10
+ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
10
11
 
11
12
  // Default group-by in the case the group stored in the preference does not apply
12
13
  const DEFAULT_GROUP = 'namespace';
@@ -223,7 +224,6 @@ export default {
223
224
  _headers() {
224
225
  let headers;
225
226
  const showNamespace = this.showNamespaceColumn;
226
- const type = this.schema?.id || this.$route?.params?.resource || undefined;
227
227
 
228
228
  if ( this.headers ) {
229
229
  headers = this.headers.slice();
@@ -234,7 +234,7 @@ export default {
234
234
  // add custom table columns provided by the extensions ExtensionPoint.TABLE_COL hook
235
235
  // gate it so that we prevent errors on older versions of dashboard
236
236
  if (this.$store.$plugin?.getUIConfig) {
237
- const extensionCols = this.$store.$plugin.getUIConfig(ExtensionPoint.TABLE_COL, TableColumnLocation.RESOURCE);
237
+ const extensionCols = getApplicableExtensionEnhancements(this, ExtensionPoint.TABLE_COL, TableColumnLocation.RESOURCE, this.$route);
238
238
 
239
239
  // Try and insert the columns before the Age column
240
240
  let insertPosition = headers.length;
@@ -257,17 +257,11 @@ export default {
257
257
 
258
258
  // adding extension defined cols to the correct header config
259
259
  extensionCols.forEach((col) => {
260
- if (col.locationConfig.resource) {
261
- col.locationConfig.resource.forEach((resource) => {
262
- if (resource && type === resource) {
263
- // we need the 'value' prop to be populated in order for the rows to show the values
264
- if (!col.value && col.getValue) {
265
- col.value = col.getValue;
266
- }
267
- headers.splice(insertPosition, 0, col);
268
- }
269
- });
260
+ // we need the 'value' prop to be populated in order for the rows to show the values
261
+ if (!col.value && col.getValue) {
262
+ col.value = col.getValue;
270
263
  }
264
+ headers.splice(insertPosition, 0, col);
271
265
  });
272
266
  }
273
267