@rancher/shell 3.0.12-rc.1 → 3.0.12-rc.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.
Files changed (134) hide show
  1. package/assets/images/providers/entraid-black.svg +4 -0
  2. package/assets/images/providers/entraid.svg +9 -0
  3. package/assets/images/vendor/entraid.svg +9 -0
  4. package/assets/styles/app.scss +0 -1
  5. package/assets/translations/en-us.yaml +19 -17
  6. package/assets/translations/zh-hans.yaml +4 -8
  7. package/chart/__tests__/S3.test.ts +10 -3
  8. package/components/CountBox.vue +20 -0
  9. package/components/CreateDriver.vue +0 -12
  10. package/components/DetailText.vue +12 -3
  11. package/components/SelectIconGrid.vue +5 -0
  12. package/components/__tests__/CountBox.test.ts +72 -0
  13. package/components/__tests__/DetailText.test.ts +113 -0
  14. package/components/fleet/FleetClusterTargets/index.vue +18 -1
  15. package/components/form/InputWithSelect.vue +18 -10
  16. package/components/form/KeyValue.vue +17 -1
  17. package/components/form/LabeledSelect.vue +82 -24
  18. package/components/form/Select.vue +73 -56
  19. package/components/form/ServiceNameSelect.vue +13 -11
  20. package/components/form/__tests__/KeyValue.test.ts +66 -0
  21. package/components/form/__tests__/NodeScheduling.test.ts +9 -0
  22. package/components/form/labeled-select-utils/useLabeledSelectPagination.ts +138 -0
  23. package/components/nav/Group.vue +7 -6
  24. package/components/nav/Header.vue +24 -3
  25. package/components/nav/NotificationCenter/Notification.vue +4 -1
  26. package/components/nav/NotificationCenter/NotificationHeader.vue +20 -8
  27. package/components/nav/NotificationCenter/__tests__/NotificationHeader.test.ts +80 -0
  28. package/components/nav/Type.vue +8 -7
  29. package/components/nav/WindowManager/index.vue +2 -1
  30. package/components/nav/WorkspaceSwitcher.vue +13 -0
  31. package/components/nav/__tests__/Group.test.ts +67 -0
  32. package/components/nav/__tests__/Header.test.ts +235 -0
  33. package/components/nav/__tests__/Type.test.ts +20 -3
  34. package/components/templates/default.vue +34 -4
  35. package/components/templates/home.vue +12 -25
  36. package/components/templates/plain.vue +13 -26
  37. package/composables/useLabeledFormElement.ts +10 -2
  38. package/composables/useLabeledSelect.ts +60 -0
  39. package/composables/useUserRetentionValidation.ts +1 -49
  40. package/config/cookies.js +0 -1
  41. package/config/labels-annotations.js +1 -0
  42. package/config/query-params.js +1 -0
  43. package/config/router/routes.js +0 -8
  44. package/core/__tests__/plugin-products.test.ts +616 -25
  45. package/core/plugin-products-base.ts +31 -14
  46. package/core/plugin-products-helpers.ts +5 -4
  47. package/core/plugin-types.ts +18 -3
  48. package/core/types.ts +3 -1
  49. package/detail/__tests__/management.cattle.io.fleetworkspace.test.ts +128 -0
  50. package/detail/management.cattle.io.fleetworkspace.vue +49 -0
  51. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +9 -0
  52. package/edit/__tests__/kontainerDriver.test.ts +0 -13
  53. package/edit/__tests__/nodeDriver.test.ts +5 -11
  54. package/edit/__tests__/resources.cattle.io.restore.test.ts +9 -0
  55. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  56. package/edit/auth/__tests__/oidc.test.ts +54 -0
  57. package/edit/auth/azuread.vue +1 -1
  58. package/edit/auth/oidc.vue +8 -0
  59. package/edit/kontainerDriver.vue +1 -2
  60. package/edit/nodeDriver.vue +0 -2
  61. package/edit/provisioning.cattle.io.cluster/AgentEnv.vue +1 -0
  62. package/edit/provisioning.cattle.io.cluster/__tests__/AgentEnv.test.ts +25 -0
  63. package/edit/provisioning.cattle.io.cluster/index.vue +70 -99
  64. package/initialize/App.vue +29 -2
  65. package/initialize/install-plugins.js +0 -2
  66. package/list/__tests__/management.cattle.io.feature.test.ts +105 -0
  67. package/list/catalog.cattle.io.app.vue +25 -5
  68. package/list/management.cattle.io.feature.vue +1 -1
  69. package/list/management.cattle.io.fleetworkspace.vue +8 -0
  70. package/machine-config/amazonec2.vue +1 -0
  71. package/mixins/chart.js +40 -9
  72. package/models/__tests__/catalog.cattle.io.app.test.ts +15 -1
  73. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +84 -0
  74. package/models/__tests__/chart.test.ts +99 -6
  75. package/models/__tests__/management.cattle.io.feature.test.ts +131 -0
  76. package/models/__tests__/monitoring.coreos.com.alertmanagerconfig.test.ts +98 -0
  77. package/models/catalog.cattle.io.app.js +21 -17
  78. package/models/catalog.cattle.io.clusterrepo.js +39 -11
  79. package/models/chart.js +33 -19
  80. package/models/fleet-application.js +1 -1
  81. package/models/fleet.cattle.io.bundle.js +1 -1
  82. package/models/kontainerdriver.js +11 -0
  83. package/models/management.cattle.io.authconfig.js +5 -1
  84. package/models/management.cattle.io.cluster.js +0 -53
  85. package/models/management.cattle.io.feature.js +3 -3
  86. package/models/management.cattle.io.kontainerdriver.js +1 -26
  87. package/models/monitoring.coreos.com.alertmanagerconfig.js +31 -17
  88. package/models/nodedriver.js +7 -0
  89. package/package.json +13 -12
  90. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +189 -0
  91. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +55 -0
  92. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +53 -0
  93. package/pages/c/_cluster/apps/charts/chart.vue +217 -33
  94. package/pages/c/_cluster/apps/charts/index.vue +2 -2
  95. package/pages/c/_cluster/apps/charts/install.vue +8 -3
  96. package/pages/c/_cluster/auth/user.retention/index.vue +55 -22
  97. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -7
  98. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +39 -2
  99. package/pages/c/_cluster/uiplugins/__tests__/PluginInfoPanel.test.ts +61 -0
  100. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +15 -10
  101. package/pages/c/_cluster/uiplugins/index.vue +23 -25
  102. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +205 -1
  103. package/rancher-components/Form/LabeledInput/LabeledInput.vue +82 -4
  104. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -1
  105. package/scripts/test-plugins-build.sh +5 -2
  106. package/server/server-middleware.js +2 -2
  107. package/static/humans.txt +1 -0
  108. package/static/robots.txt +34 -0
  109. package/static/welcome-cow.svg +18 -0
  110. package/store/__tests__/catalog.test.ts +161 -11
  111. package/store/auth.js +0 -3
  112. package/store/catalog.js +60 -8
  113. package/types/shell/index.d.ts +26 -22
  114. package/utils/__tests__/git.test.ts +270 -0
  115. package/utils/__tests__/inactivity.test.ts +316 -0
  116. package/utils/__tests__/object.test.ts +77 -0
  117. package/utils/__tests__/time.test.ts +14 -1
  118. package/utils/__tests__/url.test.ts +246 -0
  119. package/utils/object.js +33 -2
  120. package/utils/time.ts +5 -0
  121. package/vue.config.js +0 -9
  122. package/assets/images/providers/azuread-black.svg +0 -22
  123. package/assets/images/providers/azuread.svg +0 -25
  124. package/assets/images/vendor/azuread.svg +0 -18
  125. package/assets/styles/fonts/_dots.scss +0 -18
  126. package/components/EmberPage.vue +0 -622
  127. package/components/EmberPageView.vue +0 -39
  128. package/components/form/labeled-select-utils/labeled-select-pagination.ts +0 -116
  129. package/mixins/labeled-form-element.ts +0 -225
  130. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -28
  131. package/pages/c/_cluster/manager/pages/_page.vue +0 -22
  132. package/pages/c/_cluster/mcapps/pages/_page.vue +0 -22
  133. package/plugins/ember-cookie.js +0 -17
  134. package/utils/ember-page.js +0 -30
@@ -1,116 +0,0 @@
1
- import { debounce } from 'lodash';
2
- import { PropType, defineComponent } from 'vue';
3
- import { LabelSelectPaginateFn, LABEL_SELECT_NOT_OPTION_KINDS, LABEL_SELECT_KINDS } from '@shell/types/components/labeledSelect';
4
-
5
- /**
6
- * 'mixin' to provide pagination support to LabeledSelect
7
- */
8
- export default defineComponent({
9
- props: {
10
- paginate: {
11
- default: null,
12
- type: Function as PropType<LabelSelectPaginateFn>,
13
- },
14
-
15
- inStore: {
16
- type: String,
17
- default: 'cluster',
18
- },
19
-
20
- /**
21
- * Resource to show
22
- */
23
- resourceType: {
24
- type: String,
25
- default: null,
26
- },
27
- },
28
-
29
- data() {
30
- return {
31
- // Internal
32
- currentPage: 1,
33
- search: '',
34
- pageSize: 10,
35
- pages: 0,
36
-
37
- debouncedRequestPagination: debounce(this.requestPagination, 700),
38
-
39
- // External
40
- page: [] as any[],
41
- totalResults: 0,
42
- paginating: false,
43
- };
44
- },
45
-
46
- async mounted() {
47
- if (this.canPaginate) {
48
- await this.requestPagination();
49
- }
50
- },
51
-
52
- computed: {
53
- canPaginate() {
54
- return !!this.paginate && !!this.resourceType && this.$store.getters[`${ this.inStore }/paginationEnabled`](this.resourceType);
55
- },
56
-
57
- canLoadMore() {
58
- return this.pages > this.currentPage;
59
- },
60
-
61
- optionsInPage() {
62
- // Number of genuine options (not groups, dividers, etc)
63
- return this.canPaginate ? this._options.filter((o: any) => {
64
- return o.kind !== LABEL_SELECT_KINDS.NONE && !LABEL_SELECT_NOT_OPTION_KINDS.includes(o.kind);
65
- }).length : 0;
66
- },
67
-
68
- optionCounts() {
69
- if (!this.canPaginate || this.optionsInPage === this.totalResults) {
70
- return '';
71
- }
72
-
73
- return this.$store.getters['i18n/t']('labelSelect.pagination.counts', {
74
- count: this.optionsInPage,
75
- totalCount: this.totalResults
76
- });
77
- },
78
- },
79
-
80
- methods: {
81
- loadMore() {
82
- this.currentPage++;
83
- this.requestPagination();
84
- },
85
-
86
- setPaginationFilter(filter: string) {
87
- this.paginating = true; // Do this before debounce
88
- this.currentPage = 1;
89
- this.search = filter;
90
- this.debouncedRequestPagination(true);
91
- },
92
-
93
- async requestPagination(resetPage = false) {
94
- this.paginating = true;
95
- const paginate: LabelSelectPaginateFn = this.paginate as LabelSelectPaginateFn; // Checking is done via prop
96
-
97
- const {
98
- page,
99
- pages,
100
- total
101
- } = await paginate({
102
- resetPage,
103
- pageContent: this.page || [],
104
- page: this.currentPage,
105
- filter: this.search,
106
- pageSize: this.pageSize,
107
- });
108
-
109
- this.page = page;
110
- this.pages = pages || 0;
111
- this.totalResults = total || 0;
112
-
113
- this.paginating = false;
114
- }
115
- }
116
- });
@@ -1,225 +0,0 @@
1
- import { _EDIT, _VIEW } from '@shell/config/query-params';
2
- import { getWidth, setWidth } from '@shell/utils/width';
3
-
4
- interface LabeledFormElement {
5
- raised: boolean;
6
- focused: boolean;
7
- blurred: number | null;
8
- }
9
-
10
- export default {
11
- inheritAttrs: false,
12
-
13
- emits: ['update:validation', 'on-focus', 'on-blur'],
14
-
15
- props: {
16
- mode: {
17
- type: String,
18
- default: _EDIT,
19
- },
20
-
21
- label: {
22
- type: String,
23
- default: null
24
- },
25
-
26
- labelKey: {
27
- type: String,
28
- default: null
29
- },
30
-
31
- placeholderKey: {
32
- type: String,
33
- default: null
34
- },
35
-
36
- tooltip: {
37
- type: [String, Object],
38
- default: null
39
- },
40
-
41
- hoverTooltip: {
42
- type: Boolean,
43
- default: true,
44
- },
45
-
46
- tooltipKey: {
47
- type: String,
48
- default: null
49
- },
50
-
51
- required: {
52
- type: Boolean,
53
- default: false,
54
- },
55
-
56
- disabled: {
57
- type: Boolean,
58
- default: false,
59
- },
60
-
61
- placeholder: {
62
- type: [String, Number],
63
- default: ''
64
- },
65
-
66
- value: {
67
- type: [String, Number, Object],
68
- default: ''
69
- },
70
-
71
- options: {
72
- default: null,
73
- type: Array
74
- },
75
-
76
- searchable: {
77
- default: false,
78
- type: Boolean
79
- },
80
-
81
- filterable: {
82
- default: true,
83
- type: Boolean
84
- },
85
-
86
- rules: {
87
- default: () => [],
88
- type: Array,
89
- // we only want functions in the rules array
90
- validator: (rules: any) => rules.every((rule: any) => ['function'].includes(typeof rule))
91
- },
92
-
93
- requireDirty: {
94
- default: true,
95
- type: Boolean
96
- }
97
- },
98
-
99
- data(): LabeledFormElement {
100
- return {
101
- raised: this.mode === _VIEW || !!`${ this.value }`,
102
- focused: false,
103
- blurred: null,
104
- };
105
- },
106
-
107
- computed: {
108
- requiredField(): boolean {
109
- // using "any" for a type on "rule" here is dirty but the use of the optional chaining operator makes it safe for what we're doing here.
110
- return (this.required || this.rules.some((rule: any): boolean => rule?.name === 'required'));
111
- },
112
- empty(): boolean {
113
- return !!`${ this.value }`;
114
- },
115
-
116
- isView(): boolean {
117
- return this.mode === _VIEW;
118
- },
119
-
120
- isDisabled(): boolean {
121
- return this.disabled || this.isView;
122
- },
123
-
124
- isSearchable(): boolean {
125
- const { searchable, canPaginate } = this as any; // This will be resolved when we migrate from mixin
126
-
127
- if (canPaginate) {
128
- return true;
129
- }
130
- const options = ( this.options || [] );
131
-
132
- if (searchable || options.length >= 10) {
133
- return true;
134
- }
135
-
136
- return false;
137
- },
138
-
139
- isFilterable(): boolean {
140
- const { filterable, canPaginate } = this as any; // This will be resolved when we migrate from mixin
141
-
142
- if (canPaginate) {
143
- return false;
144
- }
145
-
146
- return filterable;
147
- },
148
-
149
- validationMessage(): string | undefined {
150
- // we want to grab the required rule passed in if we can but if it's not there then we can just grab it from the formRulesGenerator
151
- const requiredRule = this.rules.find((rule: any) => rule?.name === 'required') as Function;
152
- const ruleMessages = [];
153
- const value = this?.value;
154
-
155
- if (requiredRule && this.blurred && !this.focused) {
156
- const message = requiredRule(value);
157
-
158
- if (!!message) {
159
- this.$emit('update:validation', false);
160
-
161
- return message;
162
- }
163
- }
164
-
165
- for (const rule of this.rules as Function[]) {
166
- const message = rule(value);
167
-
168
- if (!!message && rule.name !== 'required') { // we're catching 'required' above so we can ignore it here
169
- ruleMessages.push(message);
170
- }
171
- }
172
- if (ruleMessages.length > 0 && (this.blurred || this.focused || !this.requireDirty)) {
173
- this.$emit('update:validation', false);
174
-
175
- return ruleMessages.join(', ');
176
- } else {
177
- this.$emit('update:validation', true);
178
-
179
- return undefined;
180
- }
181
- }
182
- },
183
-
184
- methods: {
185
- resizeHandler() {
186
- // since the DD is positioned there is no way to 'inherit' the size of the input, this calcs the size of the parent and set the dd width if it is smaller. If not let it grow with the regular styles
187
- this.$nextTick(() => {
188
- const DD = (this.$refs.select as HTMLElement).querySelector('ul.vs__dropdown-menu');
189
-
190
- const selectWidth = getWidth(this.$refs.select as Element) || 0;
191
- const dropWidth = getWidth(DD as Element) || 0;
192
-
193
- if (dropWidth < selectWidth) {
194
- setWidth(DD as Element, selectWidth);
195
- }
196
- });
197
- },
198
- onFocus() {
199
- this.$emit('on-focus');
200
-
201
- return this.onFocusLabeled();
202
- },
203
-
204
- onFocusLabeled() {
205
- this.raised = true;
206
- this.focused = true;
207
- },
208
-
209
- onBlur() {
210
- this.$emit('on-blur');
211
-
212
- return this.onBlurLabeled();
213
- },
214
-
215
- onBlurLabeled() {
216
- this.focused = false;
217
-
218
- if ( !this.value ) {
219
- this.raised = false;
220
- }
221
-
222
- this.blurred = Date.now();
223
- }
224
- }
225
- };
@@ -1,28 +0,0 @@
1
- <script>
2
- import EmberPage from '@shell/components/EmberPage';
3
-
4
- const PAGES = {
5
- monitoring: 'monitoring/cluster-setting',
6
- istio: 'istio/cluster-setting',
7
- snapshots: 'backups',
8
- };
9
-
10
- export default {
11
- components: { EmberPage },
12
-
13
- data() {
14
- const cluster = this.$store.getters['currentCluster'];
15
- const page = this.$route.params.page;
16
- const p = PAGES[page] || page;
17
-
18
- return { src: `/k/${ cluster.id }/${ p }` };
19
- }
20
- };
21
- </script>
22
-
23
- <template>
24
- <EmberPage
25
- v-if="src"
26
- :src="src"
27
- />
28
- </template>
@@ -1,22 +0,0 @@
1
- <script>
2
- import EmbeddedPageView from '@shell/components/EmberPageView';
3
-
4
- export default {
5
- components: { EmbeddedPageView },
6
-
7
- data() {
8
- return {
9
- PAGES: {
10
- 'rke-drivers': '/n/drivers/cluster',
11
- 'rke-templates': '/g/rke-templates/index',
12
- 'cloud-credentials': '/g/security/cloud-credentials',
13
- 'node-templates': '/n/node-templates',
14
- }
15
- };
16
- }
17
- };
18
- </script>
19
-
20
- <template>
21
- <EmbeddedPageView :pages="PAGES" />
22
- </template>
@@ -1,22 +0,0 @@
1
- <script>
2
- import EmbeddedPageView from '@shell/components/EmberPageView';
3
-
4
- export default {
5
- components: { EmbeddedPageView },
6
-
7
- data() {
8
- return {
9
- PAGES: {
10
- apps: '/g/apps',
11
- catalogs: '/g/catalog',
12
- 'global-dns-entries': '/g/dns/entries/index/',
13
- 'global-dns-providers': '/g/dns/providers/index/',
14
- }
15
- };
16
- }
17
- };
18
- </script>
19
-
20
- <template>
21
- <EmbeddedPageView :pages="PAGES" />
22
- </template>
@@ -1,17 +0,0 @@
1
- import { REDIRECTED } from '@shell/config/cookies';
2
-
3
- export default function({ store }) {
4
- // This tells Ember not to redirect back to us once you've already been to dashboard once.
5
- // TODO: Remove this once the ember portion of the app is no longer needed
6
- if ( !store.getters['cookies/get']({ key: REDIRECTED })) {
7
- const options = {
8
- path: '/',
9
- sameSite: true,
10
- secure: true,
11
- };
12
-
13
- store.commit('cookies/set', {
14
- key: REDIRECTED, value: 'true', options
15
- });
16
- }
17
- }
@@ -1,30 +0,0 @@
1
-
2
- export const EMBER_FRAME = 'ember-iframe';
3
- let inactiveRemoveTimer;
4
-
5
- // Remove the IFrame if the user has not used an embedded page after this time
6
- // since last visiting an embedded page
7
- const INACTIVITY_CHECK_TIMEOUT = 60000;
8
-
9
- export function findEmberPage() {
10
- return document.getElementById(EMBER_FRAME);
11
- }
12
-
13
- export function clearEmberInactiveTimer() {
14
- clearTimeout(inactiveRemoveTimer);
15
- }
16
-
17
- export function startEmberInactiveTimer() {
18
- if (findEmberPage() !== null) {
19
- inactiveRemoveTimer = setTimeout(removeEmberPage, INACTIVITY_CHECK_TIMEOUT);
20
- }
21
- }
22
-
23
- export function removeEmberPage() {
24
- const iframeEl = findEmberPage();
25
-
26
- if (iframeEl !== null) {
27
- iframeEl.remove();
28
- clearEmberInactiveTimer();
29
- }
30
- }