@rancher/shell 0.3.4 → 0.3.6
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/assets/images/providers/outscale.svg +19 -0
- package/assets/styles/app.scss +1 -1
- package/assets/styles/base/_basic.scss +18 -0
- package/assets/styles/base/_mixins.scss +0 -11
- package/assets/styles/base/_variables.scss +2 -4
- package/assets/styles/fonts/_fontstack.scss +11 -11
- package/assets/styles/global/_button.scss +12 -2
- package/assets/styles/vendor/vue-js-modal.scss +3 -3
- package/assets/translations/en-us.yaml +113 -22
- package/assets/translations/zh-hans.yaml +113 -24
- package/babel.config.js +13 -0
- package/chart/gatekeeper.vue +78 -0
- package/chart/istio.vue +135 -112
- package/chart/logging/index.vue +13 -4
- package/chart/monitoring/index.vue +15 -5
- package/chart/monitoring/steps/uninstall-v1.vue +2 -2
- package/chart/rancher-backup/index.vue +10 -3
- package/cloud-credential/aws.vue +1 -1
- package/cloud-credential/digitalocean.vue +1 -1
- package/cloud-credential/gcp.vue +1 -1
- package/cloud-credential/generic.vue +2 -2
- package/cloud-credential/linode.vue +1 -1
- package/cloud-credential/pnap.vue +1 -1
- package/components/ActionMenu.vue +3 -4
- package/components/AssignTo.vue +1 -1
- package/components/AsyncButton.vue +1 -1
- package/components/BannerGraphic.vue +1 -1
- package/components/BrandImage.vue +1 -4
- package/components/ButtonDropdown.vue +2 -3
- package/components/Carousel.vue +85 -37
- package/components/ChartPsp.vue +76 -0
- package/components/CruResource.vue +6 -2
- package/components/DashboardMetrics.vue +12 -10
- package/components/DetailText.vue +1 -1
- package/components/DisableAuthProviderModal.vue +1 -1
- package/components/EmberPage.vue +1 -1
- package/components/EtcdInfoBanner.vue +12 -7
- package/components/ExplorerMembers.vue +101 -6
- package/components/ExplorerProjectsNamespaces.vue +46 -3
- package/components/FileDiff.vue +6 -7
- package/components/GrafanaDashboard.vue +27 -23
- package/components/LazyImage.vue +10 -12
- package/components/LogItem.vue +1 -1
- package/components/Markdown.vue +1 -1
- package/components/PromptRemove.vue +2 -2
- package/components/PromptRestore.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +16 -0
- package/components/ResourceDetail/index.vue +21 -4
- package/components/ResourceList/index.vue +1 -1
- package/components/ResourceTable.vue +4 -1
- package/components/SingleClusterInfo.vue +2 -2
- package/components/SortableTable/THead.vue +1 -1
- package/components/SortableTable/index.vue +28 -13
- package/components/SortableTable/selection.js +58 -50
- package/components/Wizard.vue +4 -2
- package/components/__tests__/AsyncButton.test.ts +3 -1
- package/components/__tests__/ChartPsp.test.ts +75 -0
- package/components/__tests__/CruResource.test.ts +3 -1
- package/components/auth/Principal.vue +1 -1
- package/components/auth/RoleDetailEdit.vue +2 -2
- package/components/fleet/FleetBundles.vue +3 -1
- package/components/fleet/FleetClusters.vue +1 -2
- package/components/fleet/FleetIntro.vue +9 -1
- package/components/fleet/FleetNoWorkspaces.vue +62 -0
- package/components/fleet/FleetSummary.vue +7 -1
- package/components/form/HookOption.vue +14 -10
- package/components/form/LabeledSelect.vue +14 -11
- package/components/form/Labels.vue +32 -27
- package/components/form/MatchExpressions.vue +19 -4
- package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
- package/components/form/NameNsDescription.vue +32 -46
- package/components/form/ProjectMemberEditor.vue +46 -21
- package/components/form/ResourceSelector.vue +1 -1
- package/components/form/SecretSelector.vue +5 -1
- package/components/form/ServiceNameSelect.vue +1 -1
- package/components/form/SimpleSecretSelector.vue +9 -9
- package/components/form/Tolerations.vue +4 -1
- package/components/form/ValueFromResource.vue +14 -9
- package/components/form/WorkloadPorts.vue +2 -2
- package/components/form/__tests__/LabeledSelect.test.ts +138 -0
- package/components/form/__tests__/NameNsDescription.ts +59 -0
- package/components/formatter/InternalExternalIP.vue +6 -0
- package/components/formatter/InvolvedObjectLink.vue +54 -0
- package/components/formatter/Link.vue +20 -4
- package/components/formatter/LinkName.vue +6 -1
- package/components/formatter/ServiceTargets.vue +1 -1
- package/components/formatter/WorkloadHealthScale.vue +8 -2
- package/components/nav/Group.vue +2 -2
- package/components/nav/NamespaceFilter.vue +23 -11
- package/components/nav/TopLevelMenu.vue +2 -4
- package/components/nav/Type.vue +1 -1
- package/components/nav/WorkspaceSwitcher.vue +46 -5
- package/components/nuxt/nuxt-build-indicator.vue +143 -0
- package/components/nuxt/nuxt-child.js +122 -0
- package/components/nuxt/nuxt-error.vue +98 -0
- package/components/nuxt/nuxt-link.client.js +98 -0
- package/components/nuxt/nuxt-link.server.js +16 -0
- package/components/nuxt/nuxt-loading.vue +154 -0
- package/components/nuxt/nuxt.js +101 -0
- package/config/labels-annotations.js +17 -0
- package/config/middleware.js +12 -0
- package/config/product/auth.js +3 -2
- package/config/product/explorer.js +34 -6
- package/config/product/fleet.js +2 -0
- package/config/query-params.js +1 -0
- package/config/router.js +414 -0
- package/config/store.js +181 -0
- package/config/table-headers.js +54 -12
- package/config/types.js +18 -8
- package/config/uiplugins.js +30 -0
- package/content/docs/en-us/whats-new.md +10 -0
- package/content/docs/zh-hans/whats-new.md +11 -1
- package/core/plugin-routes.ts +23 -0
- package/core/plugin.ts +4 -2
- package/core/types.ts +258 -1
- package/creators/app/app.package.json +2 -1
- package/creators/app/files/.eslintrc.js +1 -1
- package/creators/app/files/babel.config.js +1 -18
- package/creators/app/files/tsconfig.json +0 -1
- package/creators/app/files/vue.config.js +6 -0
- package/creators/app/init +5 -5
- package/creators/pkg/files/.github/workflows/build-extension.yml +110 -0
- package/creators/pkg/files/tsconfig.json +0 -1
- package/creators/pkg/init +35 -4
- package/creators/pkg/pkg.package.json +3 -3
- package/creators/update/init +1 -1
- package/detail/constraints.gatekeeper.sh.constraint.vue +34 -17
- package/detail/fleet.cattle.io.clustergroup.vue +7 -1
- package/detail/fleet.cattle.io.gitrepo.vue +19 -11
- package/detail/harvesterhci.io.management.cluster.vue +3 -3
- package/detail/provisioning.cattle.io.cluster.vue +54 -12
- package/detail/workload/index.vue +3 -3
- package/dialog/AddClusterMemberDialog.vue +1 -1
- package/dialog/AddProjectMemberDialog.vue +2 -2
- package/dialog/AddonConfigConfirmationDialog.vue +27 -15
- package/dialog/DiagnosticTimingsDialog.vue +1 -1
- package/dialog/ForceMachineRemoveDialog.vue +1 -1
- package/dialog/GenericPrompt.vue +18 -6
- package/dialog/RotateEncryptionKeyDialog.vue +1 -1
- package/dialog/SaveAsRKETemplateDialog.vue +1 -1
- package/dialog/ScaleMachineDownDialog.vue +1 -1
- package/edit/auth/github.vue +8 -8
- package/edit/auth/googleoauth.vue +5 -5
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +1 -1
- package/edit/auth/saml.vue +1 -1
- package/edit/cis.cattle.io.clusterscan.vue +1 -1
- package/edit/fleet.cattle.io.clustergroup.vue +6 -4
- package/edit/fleet.cattle.io.gitrepo.vue +32 -4
- package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
- package/edit/logging.banzaicloud.io.output/index.vue +18 -5
- package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
- package/edit/management.cattle.io.fleetworkspace.vue +141 -6
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
- package/edit/management.cattle.io.setting.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
- package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
- package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
- package/edit/namespace.vue +14 -10
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +21 -4
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
- package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
- package/edit/provisioning.cattle.io.cluster/rke2.vue +344 -102
- package/edit/resources.cattle.io.backup.vue +1 -1
- package/edit/service.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
- package/edit/workload/__tests__/Job.test.ts +3 -1
- package/edit/workload/index.vue +8 -3
- package/edit/workload/mixins/workload.js +22 -7
- package/edit/workload/storage/Mount.vue +3 -3
- package/initialize/App.js +206 -0
- package/initialize/client.js +863 -0
- package/initialize/index.js +364 -0
- package/layouts/default.vue +7 -3
- package/layouts/standalone.vue +13 -0
- package/list/catalog.cattle.io.clusterrepo.vue +1 -0
- package/list/fleet.cattle.io.bundle.vue +6 -3
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
- package/list/fleet.cattle.io.gitrepo.vue +44 -5
- package/list/management.cattle.io.fleetworkspace.vue +45 -0
- package/list/node.vue +69 -16
- package/list/provisioning.cattle.io.cluster.vue +30 -1
- package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
- package/list/workload.vue +6 -4
- package/machine-config/azure.vue +97 -38
- package/middleware/authenticated.js +34 -0
- package/mixins/chart.js +101 -2
- package/mixins/fetch.client.js +95 -0
- package/mixins/fetch.server.js +73 -0
- package/mixins/labeled-form-element.ts +2 -2
- package/mixins/resource-fetch.js +2 -2
- package/models/apps.statefulset.js +28 -0
- package/models/cluster/node.js +23 -2
- package/models/cluster.x-k8s.io.machine.js +4 -2
- package/models/clusterroletemplatebinding.js +7 -0
- package/models/constraints.gatekeeper.sh.constraint.js +46 -0
- package/models/fleet.cattle.io.cluster.js +19 -10
- package/models/fleet.cattle.io.gitrepo.js +7 -2
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/management.cattle.io.fleetworkspace.js +12 -0
- package/models/management.cattle.io.gitreporestriction.js +5 -0
- package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
- package/models/pod.js +4 -0
- package/models/provisioning.cattle.io.cluster.js +7 -5
- package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
- package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
- package/package.json +13 -21
- package/pages/auth/setup.vue +2 -2
- package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
- package/pages/c/_cluster/apps/charts/chart.vue +4 -4
- package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
- package/pages/c/_cluster/apps/charts/install.vue +98 -102
- package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
- package/pages/c/_cluster/explorer/index.vue +29 -25
- package/pages/c/_cluster/explorer/tools/index.vue +8 -8
- package/pages/c/_cluster/fleet/index.vue +95 -34
- package/pages/c/_cluster/gatekeeper/index.vue +1 -1
- package/pages/c/_cluster/istio/index.vue +5 -5
- package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +7 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
- package/pages/c/_cluster/uiplugins/index.vue +49 -17
- package/pages/diagnostic.vue +32 -25
- package/pages/home.vue +9 -4
- package/pages/index.vue +10 -1
- package/pages/rio/mesh.vue +1 -2
- package/pkg/tsconfig.json +0 -1
- package/plugins/clean-html-directive.js +34 -0
- package/plugins/dashboard-store/actions.js +32 -9
- package/plugins/dashboard-store/index.js +1 -1
- package/plugins/dashboard-store/mutations.js +5 -2
- package/plugins/dashboard-store/resource-class.js +8 -1
- package/plugins/plugin.js +0 -14
- package/plugins/portal-vue.js +4 -0
- package/plugins/steve/mutations.js +3 -2
- package/plugins/steve/steve-description-class.js +5 -1
- package/plugins/steve/subscribe.js +63 -54
- package/plugins/steve-create-worker.js +14 -0
- package/promptRemove/management.cattle.io.globalrole.vue +2 -2
- package/promptRemove/management.cattle.io.project.vue +2 -2
- package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
- package/promptRemove/pod.vue +1 -1
- package/public/index.html +65 -0
- package/rancher-components/components/Banner/Banner.test.ts +7 -1
- package/rancher-components/components/Banner/Banner.vue +2 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
- package/scripts/build-pkg.sh +1 -0
- package/scripts/clean +6 -0
- package/scripts/extension/bundle +58 -0
- package/scripts/extension/helmpatch +89 -0
- package/scripts/extension/publish +333 -0
- package/scripts/serve-pkgs +6 -2
- package/scripts/test-plugins-build.sh +4 -0
- package/store/__tests__/index.test.ts +110 -0
- package/store/index.js +145 -58
- package/store/type-map.js +6 -2
- package/tsconfig.default.json +36 -0
- package/tsconfig.json +23 -0
- package/types/rancher/index.d.ts +2 -0
- package/types/shell/index.d.ts +466 -320
- package/utils/__tests__/grafana.test.ts +44 -0
- package/utils/__tests__/string.test.ts +12 -0
- package/utils/auth.js +65 -0
- package/utils/axios.js +190 -0
- package/utils/cookie-universal-nuxt.js +10 -0
- package/utils/dom.js +15 -0
- package/utils/grafana.js +35 -16
- package/utils/monitoring.js +2 -1
- package/utils/nuxt.js +659 -0
- package/utils/position.js +5 -8
- package/utils/router.scrollBehavior.js +80 -0
- package/utils/select.js +1 -3
- package/utils/socket.js +1 -0
- package/utils/string.js +13 -0
- package/utils/time.js +9 -0
- package/vue.config.js +690 -0
- package/chart/rancher-alerting-drivers.vue +0 -53
- package/chart/rancher-gatekeeper.vue +0 -37
- package/creators/app/files/nuxt.config.js +0 -6
- package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
- package/nuxt.config.js +0 -798
- package/plugins/dashboard-store/extensions.js +0 -22
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import $ from 'jquery';
|
|
2
1
|
import { isMore, isRange, suppressContextMenu, isAlternate } from '@shell/utils/platform';
|
|
3
2
|
import { get } from '@shell/utils/object';
|
|
4
3
|
import { filterBy } from '@shell/utils/array';
|
|
4
|
+
import { getParent } from '@shell/utils/dom';
|
|
5
5
|
|
|
6
6
|
export const ALL = 'all';
|
|
7
7
|
export const SOME = 'some';
|
|
@@ -9,23 +9,23 @@ export const NONE = 'none';
|
|
|
9
9
|
|
|
10
10
|
export default {
|
|
11
11
|
mounted() {
|
|
12
|
-
const
|
|
12
|
+
const table = this.$el.querySelector('TABLE');
|
|
13
13
|
|
|
14
14
|
this._onRowClickBound = this.onRowClick.bind(this);
|
|
15
15
|
this._onRowMousedownBound = this.onRowMousedown.bind(this);
|
|
16
16
|
this._onRowContextBound = this.onRowContext.bind(this);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
table.addEventListener('click', this._onRowClickBound);
|
|
19
|
+
table.addEventListener('mousedown', this._onRowMousedownBound);
|
|
20
|
+
table.addEventListener('contextmenu', this._onRowContextBound);
|
|
21
21
|
},
|
|
22
22
|
|
|
23
23
|
beforeDestroy() {
|
|
24
|
-
const
|
|
24
|
+
const table = this.$el.querySelector('TABLE');
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
table.removeEventListener('click', this._onRowClickBound);
|
|
27
|
+
table.removeEventListener('mousedown', this._onRowMousedownBound);
|
|
28
|
+
table.removeEventListener('contextmenu', this._onRowContextBound);
|
|
29
29
|
},
|
|
30
30
|
|
|
31
31
|
computed: {
|
|
@@ -156,31 +156,31 @@ export default {
|
|
|
156
156
|
},
|
|
157
157
|
|
|
158
158
|
onRowMouseEnter(e) {
|
|
159
|
-
const tr =
|
|
159
|
+
const tr = e.target.closest('TR');
|
|
160
160
|
|
|
161
|
-
if (tr.
|
|
162
|
-
const trMainRow = tr.
|
|
161
|
+
if (tr.classList.contains('sub-row')) {
|
|
162
|
+
const trMainRow = tr.previousElementSibling;
|
|
163
163
|
|
|
164
|
-
trMainRow.
|
|
164
|
+
trMainRow.classList.add('sub-row-hovered');
|
|
165
165
|
}
|
|
166
166
|
},
|
|
167
167
|
|
|
168
168
|
onRowMouseLeave(e) {
|
|
169
|
-
const tr =
|
|
169
|
+
const tr = e.target.closest('TR');
|
|
170
170
|
|
|
171
|
-
if (tr.
|
|
172
|
-
const trMainRow = tr.
|
|
171
|
+
if (tr.classList.contains('sub-row')) {
|
|
172
|
+
const trMainRow = tr.previousElementSibling;
|
|
173
173
|
|
|
174
|
-
trMainRow.
|
|
174
|
+
trMainRow.classList.remove('sub-row-hovered');
|
|
175
175
|
}
|
|
176
176
|
},
|
|
177
177
|
|
|
178
178
|
nodeForEvent(e) {
|
|
179
179
|
const tagName = e.target.tagName;
|
|
180
|
-
const tgt =
|
|
181
|
-
const actionElement = tgt.closest('.actions')
|
|
180
|
+
const tgt = e.target;
|
|
181
|
+
const actionElement = tgt.closest('.actions');
|
|
182
182
|
|
|
183
|
-
if ( tgt.
|
|
183
|
+
if ( tgt.classList.contains('select-all-check') ) {
|
|
184
184
|
return;
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -188,31 +188,31 @@ export default {
|
|
|
188
188
|
if (
|
|
189
189
|
tagName === 'A' ||
|
|
190
190
|
tagName === 'BUTTON' ||
|
|
191
|
-
tgt
|
|
191
|
+
getParent(tgt, '.btn')
|
|
192
192
|
) {
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
const tgtRow =
|
|
197
|
+
const tgtRow = e.target.closest('TR');
|
|
198
198
|
|
|
199
199
|
return this.nodeForRow(tgtRow);
|
|
200
200
|
},
|
|
201
201
|
|
|
202
202
|
nodeForRow(tgtRow) {
|
|
203
|
-
if ( tgtRow?.
|
|
203
|
+
if ( tgtRow?.classList.contains('separator-row') ) {
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
while ( tgtRow &&
|
|
208
|
-
tgtRow = tgtRow.
|
|
207
|
+
while ( tgtRow && !tgtRow.classList.contains('main-row') ) {
|
|
208
|
+
tgtRow = tgtRow.previousElementSibling;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
if ( !tgtRow
|
|
211
|
+
if ( !tgtRow ) {
|
|
212
212
|
return;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
const nodeId = tgtRow.
|
|
215
|
+
const nodeId = tgtRow.dataset.nodeId;
|
|
216
216
|
|
|
217
217
|
if ( !nodeId ) {
|
|
218
218
|
return;
|
|
@@ -225,15 +225,15 @@ export default {
|
|
|
225
225
|
|
|
226
226
|
async onRowClick(e) {
|
|
227
227
|
const node = this.nodeForEvent(e);
|
|
228
|
-
const td =
|
|
229
|
-
const skipSelect = td.
|
|
228
|
+
const td = e.target.closest('TD');
|
|
229
|
+
const skipSelect = td?.classList.contains('skip-select');
|
|
230
230
|
|
|
231
231
|
if (skipSelect) {
|
|
232
232
|
return;
|
|
233
233
|
}
|
|
234
234
|
const selection = this.selectedRows;
|
|
235
|
-
const isCheckbox = this.isSelectionCheckbox(e.target) || td.
|
|
236
|
-
const isExpand = td.
|
|
235
|
+
const isCheckbox = this.isSelectionCheckbox(e.target) || td?.classList.contains('row-check');
|
|
236
|
+
const isExpand = td?.classList.contains('row-expand');
|
|
237
237
|
const content = this.pagedRows;
|
|
238
238
|
|
|
239
239
|
this.$emit('rowClick', e);
|
|
@@ -248,28 +248,30 @@ export default {
|
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
const actionElement =
|
|
251
|
+
const actionElement = e.target.closest('.actions');
|
|
252
252
|
|
|
253
253
|
if ( actionElement ) {
|
|
254
254
|
let resources = [node];
|
|
255
255
|
|
|
256
256
|
if ( this.mangleActionResources ) {
|
|
257
|
-
const i =
|
|
257
|
+
const i = actionElement.querySelector('i');
|
|
258
258
|
|
|
259
|
-
i.
|
|
260
|
-
i.
|
|
259
|
+
i.classList.remove('icon-actions');
|
|
260
|
+
i.classList.add('icon-spinner');
|
|
261
|
+
i.classList.add('icon-spin');
|
|
261
262
|
|
|
262
263
|
try {
|
|
263
264
|
resources = await this.mangleActionResources(resources);
|
|
264
265
|
} finally {
|
|
265
|
-
i.
|
|
266
|
-
i.
|
|
266
|
+
i.classList.remove('icon-spinner');
|
|
267
|
+
i.classList.remove('icon-spin');
|
|
268
|
+
i.classList.add('icon-actions');
|
|
267
269
|
}
|
|
268
270
|
}
|
|
269
271
|
|
|
270
272
|
this.$store.commit(`action-menu/show`, {
|
|
271
273
|
resources,
|
|
272
|
-
event: e
|
|
274
|
+
event: e,
|
|
273
275
|
elem: actionElement
|
|
274
276
|
});
|
|
275
277
|
|
|
@@ -332,7 +334,7 @@ export default {
|
|
|
332
334
|
|
|
333
335
|
this.$store.commit(`action-menu/show`, {
|
|
334
336
|
resources,
|
|
335
|
-
event: e
|
|
337
|
+
event: e,
|
|
336
338
|
});
|
|
337
339
|
},
|
|
338
340
|
|
|
@@ -356,7 +358,7 @@ export default {
|
|
|
356
358
|
isSelectionCheckbox(element) {
|
|
357
359
|
return element.tagName === 'INPUT' &&
|
|
358
360
|
element.type === 'checkbox' &&
|
|
359
|
-
|
|
361
|
+
element.closest('.selection-checkbox') !== null;
|
|
360
362
|
},
|
|
361
363
|
|
|
362
364
|
nodesBetween(a, b) {
|
|
@@ -445,7 +447,9 @@ export default {
|
|
|
445
447
|
}
|
|
446
448
|
});
|
|
447
449
|
|
|
448
|
-
|
|
450
|
+
if ( toAdd ) {
|
|
451
|
+
this.selectedRows.push(...toAdd);
|
|
452
|
+
}
|
|
449
453
|
|
|
450
454
|
// Uncheck and check the checkboxes of nodes that have been added/removed
|
|
451
455
|
if (toRemove.length) {
|
|
@@ -474,20 +478,24 @@ export default {
|
|
|
474
478
|
|
|
475
479
|
if ( id ) {
|
|
476
480
|
// Note: This is looking for the checkbox control for the row
|
|
477
|
-
const input =
|
|
481
|
+
const input = this.$el.querySelector(`div[data-checkbox-ctrl][data-node-id="${ id }"]`);
|
|
478
482
|
|
|
479
|
-
if ( input &&
|
|
480
|
-
const label =
|
|
483
|
+
if ( input && !input.disabled ) {
|
|
484
|
+
const label = input.querySelector('label');
|
|
481
485
|
|
|
482
486
|
if (label) {
|
|
483
|
-
label.
|
|
487
|
+
label.value = on;
|
|
484
488
|
}
|
|
485
489
|
let tr = input.closest('tr');
|
|
486
490
|
let first = true;
|
|
487
491
|
|
|
488
|
-
while ( tr && (first || tr.
|
|
489
|
-
|
|
490
|
-
|
|
492
|
+
while ( tr && (first || tr.classList.contains('sub-row') ) ) {
|
|
493
|
+
if (on) {
|
|
494
|
+
tr.classList.add('row-selected');
|
|
495
|
+
} else {
|
|
496
|
+
tr.classList.remove('row-selected');
|
|
497
|
+
}
|
|
498
|
+
tr = tr.nextElementSibling;
|
|
491
499
|
first = false;
|
|
492
500
|
}
|
|
493
501
|
}
|
|
@@ -497,9 +505,9 @@ export default {
|
|
|
497
505
|
select(nodes) {
|
|
498
506
|
nodes.forEach((node) => {
|
|
499
507
|
const id = get(node, this.keyField);
|
|
500
|
-
const input =
|
|
508
|
+
const input = this.$el.querySelector(`label[data-node-id="${ id }"]`);
|
|
501
509
|
|
|
502
|
-
input.
|
|
510
|
+
input.dispatchEvent(new Event('click'));
|
|
503
511
|
});
|
|
504
512
|
},
|
|
505
513
|
|
package/components/Wizard.vue
CHANGED
|
@@ -468,6 +468,9 @@ $spacer: 10px;
|
|
|
468
468
|
flex-direction: column;
|
|
469
469
|
flex: 1;
|
|
470
470
|
padding: 0;
|
|
471
|
+
height: 100%;
|
|
472
|
+
position: relative;
|
|
473
|
+
justify-content: flex-start;
|
|
471
474
|
}
|
|
472
475
|
|
|
473
476
|
.header {
|
|
@@ -643,9 +646,8 @@ $spacer: 10px;
|
|
|
643
646
|
flex-direction: column;
|
|
644
647
|
|
|
645
648
|
&__step {
|
|
646
|
-
display: flex;
|
|
647
|
-
flex-direction: column;
|
|
648
649
|
flex: 1;
|
|
650
|
+
overflow: auto;
|
|
649
651
|
}
|
|
650
652
|
}
|
|
651
653
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mount, Wrapper } from '@vue/test-utils';
|
|
2
2
|
import AsyncButton, { ASYNC_BUTTON_STATES } from '@shell/components/AsyncButton.vue';
|
|
3
|
+
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
3
4
|
|
|
4
5
|
describe('component: AsyncButton', () => {
|
|
5
6
|
it('should render appropriately with default config', () => {
|
|
@@ -7,7 +8,8 @@ describe('component: AsyncButton', () => {
|
|
|
7
8
|
const mockT = jest.fn().mockReturnValue('some-string');
|
|
8
9
|
|
|
9
10
|
const wrapper: Wrapper<InstanceType<typeof AsyncButton> & { [key: string]: any }> = mount(AsyncButton, {
|
|
10
|
-
|
|
11
|
+
directives: { cleanHtmlDirective },
|
|
12
|
+
mocks: {
|
|
11
13
|
$store: {
|
|
12
14
|
getters: {
|
|
13
15
|
'i18n/exists': mockExists,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { shallowMount, mount } from '@vue/test-utils';
|
|
2
|
+
import ChartPsp from '@shell/components/ChartPsp.vue';
|
|
3
|
+
|
|
4
|
+
describe('component: ChartPsp', () => {
|
|
5
|
+
it.each([
|
|
6
|
+
true, false
|
|
7
|
+
])('should render checkbox referencing value.global.cattle.psp.enabled as %p', (value) => {
|
|
8
|
+
const version = 'v1.24.11+rke2r1';
|
|
9
|
+
const wrapper = shallowMount(ChartPsp, {
|
|
10
|
+
propsData: {
|
|
11
|
+
value: { global: { cattle: { psp: { enabled: value } } } },
|
|
12
|
+
cluster: { kubernetesVersion: version }
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(wrapper.findComponent({ name: 'Checkbox' }).props().value).toBe(value);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it.each([
|
|
20
|
+
['v1.24.11+rke2r1'],
|
|
21
|
+
])('should display the checkbox for cluster with k8s version %p', (version) => {
|
|
22
|
+
const wrapper = shallowMount(ChartPsp, {
|
|
23
|
+
propsData: {
|
|
24
|
+
value: { global: { cattle: { psp: { enabled: false } } } },
|
|
25
|
+
cluster: { kubernetesVersion: version }
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const input = wrapper.find(`[data-testid="psp-checkbox"]`).element as HTMLInputElement;
|
|
30
|
+
|
|
31
|
+
expect(input).toBeDefined();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it.each([
|
|
35
|
+
['v1.25.11+rke2r1'],
|
|
36
|
+
])('should not display the checkbox for cluster with k8s version %p', (version) => {
|
|
37
|
+
const wrapper = shallowMount(ChartPsp, {
|
|
38
|
+
propsData: {
|
|
39
|
+
value: { global: { cattle: { psp: { enabled: false } } } },
|
|
40
|
+
cluster: { kubernetesVersion: version }
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const input = wrapper.find(`[data-testid="psp-checkbox"]`).element as HTMLInputElement;
|
|
45
|
+
|
|
46
|
+
expect(input).toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should update value.global.cattle.psp.enabled when checkbox is toggled', async() => {
|
|
50
|
+
const chartValues = { global: {} } as any;
|
|
51
|
+
const version = 'v1.24.11+rke2r1';
|
|
52
|
+
const wrapper = mount(ChartPsp, {
|
|
53
|
+
propsData: {
|
|
54
|
+
value: chartValues,
|
|
55
|
+
cluster: { kubernetesVersion: version }
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await wrapper.find('.checkbox-container').trigger('click');
|
|
60
|
+
|
|
61
|
+
expect(chartValues.global.cattle.psp.enabled).toBe(true);
|
|
62
|
+
|
|
63
|
+
await wrapper.find('.checkbox-container').trigger('click');
|
|
64
|
+
expect(chartValues.global.cattle.psp.enabled).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it.each([
|
|
68
|
+
{ global: {} } as any,
|
|
69
|
+
{ global: { cattle: {} } } as any,
|
|
70
|
+
])('should define cattle.psp.enabled and set to false', (chartValues) => {
|
|
71
|
+
shallowMount(ChartPsp, { propsData: { value: chartValues } });
|
|
72
|
+
|
|
73
|
+
expect(chartValues.global.cattle.psp.enabled).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import CruResource from '@shell/components/CruResource.vue';
|
|
3
3
|
import { _EDIT, _YAML } from '@shell/config/query-params';
|
|
4
|
+
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
4
5
|
|
|
5
6
|
describe('component: CruResource', () => {
|
|
6
7
|
it('should hide Cancel button', () => {
|
|
@@ -33,7 +34,8 @@ describe('component: CruResource', () => {
|
|
|
33
34
|
it('should display multiple errors', () => {
|
|
34
35
|
const errors = ['mistake!', 'BiG MiStAke11'];
|
|
35
36
|
const wrapper = mount(CruResource, {
|
|
36
|
-
|
|
37
|
+
directives: { cleanHtmlDirective },
|
|
38
|
+
propsData: {
|
|
37
39
|
canYaml: false,
|
|
38
40
|
mode: _EDIT,
|
|
39
41
|
resource: {},
|
|
@@ -648,7 +648,7 @@ export default {
|
|
|
648
648
|
</div>
|
|
649
649
|
</template>
|
|
650
650
|
<template #columns="props">
|
|
651
|
-
<div class="columns row">
|
|
651
|
+
<div class="columns row mr-20">
|
|
652
652
|
<div :class="ruleClass">
|
|
653
653
|
<Select
|
|
654
654
|
:value="props.row.value.verbs"
|
|
@@ -713,7 +713,7 @@ export default {
|
|
|
713
713
|
:mode="mode"
|
|
714
714
|
>
|
|
715
715
|
<template #columns="props">
|
|
716
|
-
<div class="columns row">
|
|
716
|
+
<div class="columns row mr-20">
|
|
717
717
|
<div class="col span-12">
|
|
718
718
|
<Select
|
|
719
719
|
v-model="props.row.value"
|
|
@@ -26,7 +26,9 @@ export default {
|
|
|
26
26
|
},
|
|
27
27
|
|
|
28
28
|
async fetch() {
|
|
29
|
-
|
|
29
|
+
if (this.$store.getters['management/schemaFor']( FLEET.CLUSTER )) {
|
|
30
|
+
this.allFleet = await this.$store.getters['management/all'](FLEET.CLUSTER);
|
|
31
|
+
}
|
|
30
32
|
},
|
|
31
33
|
|
|
32
34
|
data() {
|
|
@@ -71,8 +71,7 @@ export default {
|
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
pagingParams() {
|
|
74
|
-
const
|
|
75
|
-
const schema = this.$store.getters[`${ inStore }/schemaFor`](FLEET.CLUSTER);
|
|
74
|
+
const schema = this.$store.getters[`management/schemaFor`](FLEET.CLUSTER);
|
|
76
75
|
|
|
77
76
|
return {
|
|
78
77
|
singularLabel: this.$store.getters['type-map/labelFor'](schema),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { AS, _YAML } from '@shell/config/query-params';
|
|
3
|
+
import { FLEET } from '@shell/config/types';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
|
|
@@ -18,10 +19,14 @@ export default {
|
|
|
18
19
|
query: { [AS]: _YAML },
|
|
19
20
|
};
|
|
20
21
|
|
|
22
|
+
const gitRepoSchema = this.$store.getters['management/schemaFor'](FLEET.GIT_REPO);
|
|
23
|
+
const canCreateRepos = gitRepoSchema && gitRepoSchema.resourceMethods.includes('PUT');
|
|
24
|
+
|
|
21
25
|
return {
|
|
22
26
|
formRoute,
|
|
23
27
|
yamlRoute,
|
|
24
28
|
hasEditComponent,
|
|
29
|
+
canCreateRepos
|
|
25
30
|
};
|
|
26
31
|
},
|
|
27
32
|
};
|
|
@@ -32,7 +37,10 @@ export default {
|
|
|
32
37
|
<div class="title">
|
|
33
38
|
{{ t('fleet.gitRepo.repo.noRepos') }}
|
|
34
39
|
</div>
|
|
35
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
v-if="canCreateRepos"
|
|
42
|
+
class="actions"
|
|
43
|
+
>
|
|
36
44
|
<n-link
|
|
37
45
|
:to="formRoute"
|
|
38
46
|
class="btn role-secondary"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
<script>
|
|
3
|
+
import { FLEET } from '@shell/config/types';
|
|
4
|
+
import { NAME } from '@shell/config/product/fleet';
|
|
5
|
+
export default {
|
|
6
|
+
name: 'NoWorkspaces',
|
|
7
|
+
|
|
8
|
+
props: {
|
|
9
|
+
canView: {
|
|
10
|
+
type: Boolean,
|
|
11
|
+
default: false,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
data() {
|
|
15
|
+
const formRoute = {
|
|
16
|
+
name: `c-cluster-product-resource-create`,
|
|
17
|
+
params: { resource: FLEET.WORKSPACE, product: NAME }
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return { hasWorkspaces: false, formRoute };
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
<template>
|
|
25
|
+
<div class="intro-box">
|
|
26
|
+
<i class="icon icon-repository" />
|
|
27
|
+
<div class="title">
|
|
28
|
+
<span v-clean-html="t('fleet.gitRepo.repo.noWorkspaces', null, true)" />
|
|
29
|
+
</div>
|
|
30
|
+
<div
|
|
31
|
+
v-if="canView"
|
|
32
|
+
class="actions"
|
|
33
|
+
>
|
|
34
|
+
<n-link
|
|
35
|
+
:to="formRoute"
|
|
36
|
+
class="btn role-secondary"
|
|
37
|
+
>
|
|
38
|
+
{{ t('fleet.gitRepo.workspace.addWorkspace') }}
|
|
39
|
+
</n-link>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
<style lang="scss" scoped>
|
|
44
|
+
.intro-box {
|
|
45
|
+
height: calc(100vh - var(--header-height)*2);
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.title {
|
|
53
|
+
margin-bottom: 15px;
|
|
54
|
+
font-size: $font-size-h2;
|
|
55
|
+
text-align: center;
|
|
56
|
+
max-width: 600px;
|
|
57
|
+
}
|
|
58
|
+
.icon-repository {
|
|
59
|
+
font-size: 96px;
|
|
60
|
+
margin-bottom: 32px;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -80,7 +80,12 @@ export default {
|
|
|
80
80
|
},
|
|
81
81
|
|
|
82
82
|
bundleCounts() {
|
|
83
|
-
const resources = this.bundles.filter(item => item.metadata.name.startsWith(`${ this.repoName }-`))
|
|
83
|
+
const resources = this.bundles.filter(item => item.metadata.name.startsWith(`${ this.repoName }-`));
|
|
84
|
+
|
|
85
|
+
if (!resources.length) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
|
|
84
89
|
const out = { ...getResourceDefaultState(this.$store.getters['i18n/withFallback'], this.stateKey) };
|
|
85
90
|
|
|
86
91
|
resources.forEach(({ status, metadata }) => {
|
|
@@ -176,6 +181,7 @@ export default {
|
|
|
176
181
|
<template>
|
|
177
182
|
<div class="row flexwrap">
|
|
178
183
|
<FleetStatus
|
|
184
|
+
v-if="bundleCounts.length"
|
|
179
185
|
title="Bundles"
|
|
180
186
|
:values="bundleCounts"
|
|
181
187
|
value-key="count"
|
|
@@ -202,16 +202,17 @@ export default {
|
|
|
202
202
|
:mode="mode"
|
|
203
203
|
/>
|
|
204
204
|
</template>
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
205
|
+
<div class="remove">
|
|
206
|
+
<button
|
|
207
|
+
v-if="!isView"
|
|
208
|
+
type="button"
|
|
209
|
+
class="btn role-link ml0"
|
|
210
|
+
:disabled="mode==='view'"
|
|
211
|
+
@click.stop="removeHeader(index)"
|
|
212
|
+
>
|
|
213
|
+
<t k="generic.remove" />
|
|
214
|
+
</button>
|
|
215
|
+
</div>
|
|
215
216
|
</div>
|
|
216
217
|
|
|
217
218
|
<div>
|
|
@@ -244,5 +245,8 @@ export default {
|
|
|
244
245
|
.labeled-select {
|
|
245
246
|
min-height: $input-height;
|
|
246
247
|
}
|
|
248
|
+
.remove BUTTON {
|
|
249
|
+
padding: 0px;
|
|
250
|
+
}
|
|
247
251
|
}
|
|
248
252
|
</style>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import CompactInput from '@shell/mixins/compact-input';
|
|
3
3
|
import LabeledFormElement from '@shell/mixins/labeled-form-element';
|
|
4
|
-
import { findBy } from '@shell/utils/array';
|
|
5
4
|
import { get } from '@shell/utils/object';
|
|
6
5
|
import { LabeledTooltip } from '@components/LabeledTooltip';
|
|
7
6
|
import VueSelectOverrides from '@shell/mixins/vue-select-overrides';
|
|
8
7
|
import { onClickOption, calculatePosition } from '@shell/utils/select';
|
|
8
|
+
import isEqual from 'lodash/isEqual';
|
|
9
9
|
|
|
10
10
|
export default {
|
|
11
11
|
name: 'LabeledSelect',
|
|
@@ -105,16 +105,6 @@ export default {
|
|
|
105
105
|
hasLabel() {
|
|
106
106
|
return this.isCompact ? false : !!this.label || !!this.labelKey || !!this.$slots.label;
|
|
107
107
|
},
|
|
108
|
-
|
|
109
|
-
currentLabel() {
|
|
110
|
-
const entry = findBy(this.options || [], 'value', this.value);
|
|
111
|
-
|
|
112
|
-
if (entry) {
|
|
113
|
-
return entry.label;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return this.getOptionLabel(this.value);
|
|
117
|
-
},
|
|
118
108
|
},
|
|
119
109
|
|
|
120
110
|
methods: {
|
|
@@ -159,6 +149,19 @@ export default {
|
|
|
159
149
|
return;
|
|
160
150
|
}
|
|
161
151
|
|
|
152
|
+
// Force to update the option label if prop has been changed
|
|
153
|
+
const isOutdated = !this.options.find(opt => option[this.optionLabel] === opt[this.optionLabel]);
|
|
154
|
+
|
|
155
|
+
if (isOutdated && this.options) {
|
|
156
|
+
const newOption = this.options.find(opt => isEqual(this.reduce(option), this.reduce(opt)));
|
|
157
|
+
|
|
158
|
+
if (newOption) {
|
|
159
|
+
const label = get(newOption, this.optionLabel);
|
|
160
|
+
|
|
161
|
+
return this.localizedLabel ? this.$store.getters['i18n/t'](label) || label : label;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
162
165
|
if (this.$attrs['get-option-label']) {
|
|
163
166
|
return this.$attrs['get-option-label'](option);
|
|
164
167
|
}
|