@rancher/shell 0.3.29 → 0.5.0
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/ovhcloudmks.svg +122 -0
- package/assets/images/providers/ovhcloudpubliccloud.svg +122 -0
- package/assets/styles/global/_layout.scss +99 -0
- package/assets/translations/en-us.yaml +31 -6
- package/assets/translations/zh-hans.yaml +2 -2
- package/babel.config.js +7 -1
- package/chart/monitoring/alerting/index.vue +7 -21
- package/chart/monitoring/grafana/index.vue +55 -0
- package/chart/monitoring/index.vue +51 -17
- package/chart/monitoring/prometheus/index.vue +37 -43
- package/chart/rancher-backup/index.vue +2 -1
- package/cloud-credential/azure.vue +4 -17
- package/components/AsyncButton.vue +17 -5
- package/components/Certificates.vue +164 -0
- package/components/CodeMirror.vue +19 -21
- package/components/CopyCode.vue +6 -2
- package/components/CopyToClipboard.vue +2 -1
- package/components/CopyToClipboardText.vue +14 -9
- package/components/CruResource.vue +1 -0
- package/components/DraggableZone.vue +2 -2
- package/components/EtcdInfoBanner.vue +5 -5
- package/components/ExplorerProjectsNamespaces.vue +25 -1
- package/components/IconOrSvg.vue +1 -1
- package/components/LandingPagePreference.vue +1 -4
- package/components/Markdown.vue +16 -12
- package/components/PodSecurityAdmission.vue +2 -2
- package/components/Questions/index.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +25 -9
- package/components/ResourceTable.vue +14 -2
- package/components/ResourceYaml.vue +5 -0
- package/components/SideNav.vue +1 -1
- package/components/SingleClusterInfo.vue +1 -4
- package/components/StatusTable.vue +5 -1
- package/components/Tabbed/index.vue +12 -0
- package/components/__tests__/CopyCode.test.ts +5 -4
- package/components/fleet/FleetBundles.vue +5 -11
- package/components/fleet/FleetRepos.vue +62 -27
- package/components/fleet/FleetResources.vue +6 -1
- package/components/fleet/FleetSummary.vue +3 -3
- package/components/fleet/__tests__/FleetSummary.test.ts +316 -0
- package/components/form/ArrayListSelect.vue +10 -0
- package/components/form/Error.vue +3 -3
- package/components/form/Footer.vue +2 -2
- package/components/form/GitPicker.vue +83 -38
- package/components/form/KeyValue.vue +4 -0
- package/components/form/LabeledSelect.vue +4 -0
- package/components/form/Password.vue +3 -1
- package/components/formatter/Checked.vue +11 -3
- package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
- package/components/formatter/FleetSummaryGraph.vue +23 -11
- package/components/formatter/LiveDuration.vue +1 -1
- package/components/formatter/PercentageBar.vue +1 -1
- package/components/formatter/__tests__/Checked.test.ts +19 -0
- package/components/nav/Group.vue +2 -2
- package/components/nav/Header.vue +1 -2
- package/components/nav/TopLevelMenu.vue +36 -6
- package/components/nav/Type.vue +1 -3
- package/components/nav/WindowManager/ContainerLogs.vue +101 -3
- package/components/nav/WindowManager/ContainerShell.vue +6 -1
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
- package/components/nav/WindowManager/index.vue +11 -10
- package/components/nav/__tests__/TopLevelMenu.test.ts +33 -0
- package/components/nav/__tests__/Type.test.ts +1 -1
- package/components/nuxt/nuxt-child.js +14 -78
- package/components/nuxt/nuxt.js +1 -1
- package/{layouts → components/templates}/blank.vue +1 -1
- package/{layouts → components/templates}/default.vue +8 -98
- package/{layouts → components/templates}/error.vue +10 -19
- package/{layouts → components/templates}/home.vue +4 -1
- package/{layouts → components/templates}/plain.vue +4 -1
- package/{layouts → components/templates}/standalone.vue +1 -1
- package/{layouts → components/templates}/unauthenticated.vue +1 -1
- package/composables/useCompactInput.test.ts +36 -0
- package/composables/useCompactInput.ts +20 -0
- package/composables/useLabeledFormElement.test.ts +135 -0
- package/composables/useLabeledFormElement.ts +138 -0
- package/config/harvester-manager-types.js +2 -0
- package/config/home-links.js +1 -1
- package/config/private-label.js +22 -0
- package/config/product/explorer.js +3 -0
- package/config/product/fleet.js +6 -1
- package/config/product/manager.js +8 -2
- package/config/query-params.js +1 -0
- package/config/router.js +385 -364
- package/config/settings.ts +1 -0
- package/config/store.js +1 -1
- package/config/system-namespaces.js +3 -0
- package/config/table-headers.js +47 -0
- package/core/plugin-helpers.js +3 -5
- package/core/plugin-routes.ts +56 -114
- package/core/plugin.ts +16 -10
- package/core/plugins-loader.js +7 -9
- package/core/plugins.js +0 -3
- package/creators/app/files/.gitlab-ci.yml +14 -0
- package/creators/app/init +19 -0
- package/detail/fleet.cattle.io.cluster.vue +11 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -3
- package/dialog/ScaleMachineDownDialog.vue +34 -17
- package/edit/__tests__/service.test.ts +89 -0
- package/edit/auth/googleoauth.vue +1 -5
- package/edit/cloudcredential.vue +2 -0
- package/edit/configmap.vue +2 -1
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +12 -3
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -1
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +15 -7
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +112 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +6 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +7 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/index.vue +92 -36
- package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -583
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +157 -0
- package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +94 -19
- package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +189 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +144 -0
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
- package/edit/service.vue +12 -0
- package/edit/workload/Upgrading.vue +3 -2
- package/edit/workload/mixins/workload.js +1 -1
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +2 -1
- package/initialize/App.js +25 -71
- package/initialize/client.js +21 -162
- package/initialize/index.js +47 -124
- package/list/management.cattle.io.feature.vue +1 -7
- package/list/node.vue +1 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +100 -21
- package/machine-config/vmwarevsphere.vue +73 -51
- package/middleware/authenticated.js +10 -17
- package/mixins/auth-config.js +2 -7
- package/mixins/brand.js +29 -41
- package/mixins/create-edit-view/index.js +2 -2
- package/mixins/labeled-form-element.ts +6 -1
- package/models/__tests__/management.cattle.io.cluster.test.ts +4 -0
- package/models/__tests__/management.cattle.io.node.ts +85 -0
- package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
- package/models/__tests__/namespace.test.ts +49 -9
- package/models/__tests__/workload.test.ts +91 -0
- package/models/cluster/node.js +4 -4
- package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
- package/models/fleet.cattle.io.cluster.js +4 -0
- package/models/fleet.cattle.io.gitrepo.js +56 -13
- package/models/management.cattle.io.cluster.js +7 -3
- package/models/management.cattle.io.kontainerdriver.js +1 -1
- package/models/management.cattle.io.node.js +18 -14
- package/models/management.cattle.io.nodepool.js +17 -0
- package/models/namespace.js +1 -1
- package/models/pod.js +20 -0
- package/models/provisioning.cattle.io.cluster.js +39 -4
- package/models/secret.js +117 -18
- package/models/workload.js +16 -0
- package/models/workload.service.js +18 -0
- package/package.json +11 -10
- package/pages/about.vue +0 -1
- package/pages/account/create-key.vue +0 -1
- package/pages/account/index.vue +0 -1
- package/pages/auth/login.vue +0 -1
- package/pages/auth/logout.vue +0 -2
- package/pages/auth/setup.vue +0 -4
- package/pages/auth/verify.vue +14 -8
- package/pages/c/_cluster/apps/charts/index.vue +64 -43
- package/pages/c/_cluster/apps/charts/install.vue +4 -4
- package/pages/c/_cluster/apps/index.vue +0 -2
- package/pages/c/_cluster/auth/index.vue +0 -2
- package/pages/c/_cluster/ecm/index.vue +0 -2
- package/pages/c/_cluster/explorer/index.vue +28 -2
- package/pages/c/_cluster/fleet/index.vue +1 -1
- package/pages/c/_cluster/index.vue +0 -2
- package/pages/c/_cluster/settings/banners.vue +0 -2
- package/pages/c/_cluster/settings/brand.vue +0 -2
- package/pages/c/_cluster/settings/index.vue +0 -2
- package/pages/c/_cluster/settings/links.vue +0 -1
- package/pages/c/_cluster/settings/performance.vue +0 -1
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -1
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
- package/pages/c/_cluster/uiplugins/index.vue +0 -2
- package/pages/diagnostic.vue +1 -2
- package/pages/fail-whale.vue +0 -1
- package/pages/prefs.vue +0 -1
- package/pages/support/index.vue +2 -8
- package/pkg/auto-import.js +1 -1
- package/plugins/axios.js +0 -36
- package/plugins/back-button.js +3 -5
- package/plugins/clean-html-directive.js +1 -19
- package/plugins/clean-html.js +53 -0
- package/plugins/clean-tooltip-directive.js +1 -1
- package/plugins/codemirror-loader.js +1 -1
- package/plugins/codemirror.js +41 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.ts → mutations.test.ts} +1 -1
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
- package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
- package/plugins/dashboard-store/actions.js +30 -4
- package/plugins/dashboard-store/classify.js +1 -18
- package/plugins/dashboard-store/getters.js +10 -5
- package/plugins/dashboard-store/index.js +0 -12
- package/plugins/dashboard-store/mutations.js +0 -4
- package/plugins/dashboard-store/resource-class.js +59 -18
- package/plugins/index.js +11 -0
- package/plugins/steve/__tests__/steve-class.spec.ts +59 -0
- package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
- package/plugins/steve/getters.js +4 -1
- package/plugins/steve/norman-class.js +19 -0
- package/plugins/steve/steve-class.js +22 -0
- package/plugins/steve/subscribe.js +4 -10
- package/rancher-components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/Accordion/Accordion.vue +86 -0
- package/rancher-components/Accordion/index.ts +1 -0
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +3 -3
- package/rancher-components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +65 -24
- package/rancher-components/Form/Radio/RadioButton.test.ts +7 -3
- package/rancher-components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/Form/Radio/RadioGroup.test.ts +30 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +8 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/StringList/StringList.test.ts +270 -0
- package/rancher-components/StringList/StringList.vue +65 -26
- package/rancher-components/components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/components/Accordion/Accordion.vue +86 -0
- package/rancher-components/components/Accordion/index.ts +1 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/components/Banner/Banner.vue +2 -2
- package/rancher-components/components/Card/Card.vue +3 -3
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +57 -24
- package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/components/StringList/StringList.vue +8 -8
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +50 -0
- package/scripts/extension/bundle +19 -7
- package/scripts/extension/helm/scripts/package +11 -3
- package/scripts/extension/parse-tag-name +2 -2
- package/scripts/extension/publish +20 -9
- package/scripts/publish-shell.sh +10 -0
- package/scripts/test-plugins-build.sh +85 -9
- package/server/har-file.js +183 -0
- package/store/catalog.js +1 -1
- package/store/features.js +1 -0
- package/store/i18n.js +11 -0
- package/store/index.js +13 -15
- package/store/prefs.js +33 -35
- package/store/type-map.js +8 -7
- package/tsconfig.json +35 -9
- package/tsconfig.paths.json +21 -0
- package/types/shell/index.d.ts +433 -234
- package/types/vue-shim.d.ts +42 -0
- package/utils/__tests__/create-yaml.test.ts +60 -0
- package/utils/axios.js +0 -19
- package/utils/azure.js +24 -0
- package/utils/clipboard.js +5 -0
- package/utils/create-yaml.js +17 -10
- package/utils/git.ts +1 -1
- package/utils/monitoring.js +1 -1
- package/utils/nuxt.js +18 -39
- package/utils/object.js +14 -0
- package/utils/router.scrollBehavior.js +12 -14
- package/utils/time.js +1 -1
- package/utils/url.ts +1 -1
- package/vue.config.js +23 -2
- package/.DS_Store +0 -0
- package/assets/images/providers/aks-black.svg +0 -28
- package/assets/images/providers/aks.svg +0 -31
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -234
- package/initialize/layouts.ts +0 -26
- package/mixins/fetch.server.js +0 -73
- package/pages/c/index.vue +0 -9
- package/pages/rio/mesh.vue +0 -508
- package/plugins/transitions.js +0 -4
- package/plugins/vue-clipboard2.js +0 -4
- package/tsconfig.default.json +0 -46
- package/yarn-error.log +0 -200
- /package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +0 -0
- /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
- /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
- /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
- /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
- /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Steve from '@shell/plugins/steve/steve-class.js';
|
|
2
|
+
import { steveClassJunkObject } from './utils/steve-mocks';
|
|
3
|
+
|
|
4
|
+
describe('class: Steve', () => {
|
|
5
|
+
describe('given custom resource keys', () => {
|
|
6
|
+
const customResource = steveClassJunkObject;
|
|
7
|
+
|
|
8
|
+
it('should keep internal keys', () => {
|
|
9
|
+
const steve = new Steve(customResource, {
|
|
10
|
+
getters: { schemaFor: () => ({ linkFor: jest.fn() }) },
|
|
11
|
+
dispatch: jest.fn(),
|
|
12
|
+
rootGetters: { 'i18n/t': jest.fn() },
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
expect({ ...steve }).toStrictEqual(customResource);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('method: save', () => {
|
|
19
|
+
it('should remove all the internal keys', async() => {
|
|
20
|
+
const dispatch = jest.fn();
|
|
21
|
+
const steve = new Steve(customResource, {
|
|
22
|
+
getters: { schemaFor: () => ({ linkFor: jest.fn() }) },
|
|
23
|
+
dispatch,
|
|
24
|
+
rootGetters: { 'i18n/t': jest.fn() },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const expectation = {
|
|
28
|
+
type: customResource.type,
|
|
29
|
+
metadata: {
|
|
30
|
+
resourceVersion: 'whatever',
|
|
31
|
+
fields: 'whatever',
|
|
32
|
+
clusterName: 'whatever',
|
|
33
|
+
deletionGracePeriodSeconds: 'whatever',
|
|
34
|
+
generateName: 'whatever',
|
|
35
|
+
},
|
|
36
|
+
spec: { versions: {} }
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
await steve.save();
|
|
40
|
+
|
|
41
|
+
const opt = {
|
|
42
|
+
data: expectation,
|
|
43
|
+
headers: {
|
|
44
|
+
accept: 'application/json',
|
|
45
|
+
'content-type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
method: 'post',
|
|
48
|
+
url: undefined,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Data sent should have been cleaned
|
|
52
|
+
expect(dispatch).toHaveBeenCalledWith('request', { opt, type: customResource.type });
|
|
53
|
+
|
|
54
|
+
// Original workload model should remain unchanged
|
|
55
|
+
expect({ ...steve }).toStrictEqual(customResource);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resourceClassJunkObject } from '@shell/plugins/dashboard-store/__tests__/utils/store-mocks';
|
|
2
|
+
|
|
3
|
+
const customType = 'asdasd';
|
|
4
|
+
|
|
5
|
+
export const steveClassJunkObject = {
|
|
6
|
+
...resourceClassJunkObject,
|
|
7
|
+
type: customType,
|
|
8
|
+
__clone: 'whatever',
|
|
9
|
+
metadata: {
|
|
10
|
+
clusterName: 'whatever',
|
|
11
|
+
creationTimestamp: 'whatever',
|
|
12
|
+
deletionGracePeriodSeconds: 'whatever',
|
|
13
|
+
deletionTimestamp: 'whatever',
|
|
14
|
+
fields: 'whatever',
|
|
15
|
+
finalizers: 'whatever',
|
|
16
|
+
generateName: 'whatever',
|
|
17
|
+
generation: 'whatever',
|
|
18
|
+
initializers: 'whatever',
|
|
19
|
+
managedFields: 'whatever',
|
|
20
|
+
ownerReferences: 'whatever',
|
|
21
|
+
relationships: 'whatever',
|
|
22
|
+
selfLink: 'whatever',
|
|
23
|
+
state: 'whatever',
|
|
24
|
+
uid: 'whatever',
|
|
25
|
+
resourceVersion: 'whatever',
|
|
26
|
+
},
|
|
27
|
+
spec: { versions: { schema: 'whatever' } },
|
|
28
|
+
links: 'whatever',
|
|
29
|
+
status: 'whatever',
|
|
30
|
+
stringData: 'whatever',
|
|
31
|
+
};
|
package/plugins/steve/getters.js
CHANGED
|
@@ -24,11 +24,14 @@ const GC_IGNORE_TYPES = {
|
|
|
24
24
|
[UI.NAV_LINK]: true,
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
// Include calls to /v1 AND /k8s/clusters/<cluster id>/v1
|
|
28
|
+
const steveRegEx = new RegExp('(/v1)|(\/k8s\/clusters\/[a-z0-9-]+\/v1)');
|
|
29
|
+
|
|
27
30
|
export default {
|
|
28
31
|
urlOptions: () => (url, opt) => {
|
|
29
32
|
opt = opt || {};
|
|
30
33
|
const parsedUrl = parse(url);
|
|
31
|
-
const isSteve = parsedUrl.path
|
|
34
|
+
const isSteve = steveRegEx.test(parsedUrl.path);
|
|
32
35
|
|
|
33
36
|
// Filter
|
|
34
37
|
if ( opt.filter ) {
|
|
@@ -3,6 +3,7 @@ import pickBy from 'lodash/pickBy';
|
|
|
3
3
|
import Vue from 'vue';
|
|
4
4
|
import { matchesSomeRegex } from '@shell/utils/string';
|
|
5
5
|
import Resource from '@shell/plugins/dashboard-store/resource-class';
|
|
6
|
+
import { findBy } from '@shell/utils/array';
|
|
6
7
|
|
|
7
8
|
export default class NormanModel extends Resource {
|
|
8
9
|
setLabels(val) {
|
|
@@ -56,4 +57,22 @@ export default class NormanModel extends Resource {
|
|
|
56
57
|
Vue.set(this, key, { ...spec[key] });
|
|
57
58
|
});
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
isCondition(condition, withStatus = 'True') {
|
|
62
|
+
if ( !this.conditions ) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const entry = findBy((this.conditions || []), 'type', condition);
|
|
67
|
+
|
|
68
|
+
if ( !entry ) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if ( !withStatus ) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return (entry.status || '').toLowerCase() === `${ withStatus }`.toLowerCase();
|
|
77
|
+
}
|
|
59
78
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { DESCRIPTION } from '@shell/config/labels-annotations';
|
|
2
2
|
import HybridModel from './hybrid-class';
|
|
3
|
+
import { NEVER_ADD } from '@shell/utils/create-yaml';
|
|
4
|
+
import { deleteProperty } from '@shell/utils/object';
|
|
5
|
+
|
|
6
|
+
// Some fields that are removed for YAML (NEVER_ADD) are required via API
|
|
7
|
+
const STEVE_ADD = [
|
|
8
|
+
'metadata.resourceVersion',
|
|
9
|
+
'metadata.fields',
|
|
10
|
+
'metadata.clusterName',
|
|
11
|
+
'metadata.deletionGracePeriodSeconds',
|
|
12
|
+
'metadata.generateName',
|
|
13
|
+
];
|
|
14
|
+
const STEVE_NEVER_SAVE = NEVER_ADD.filter((na) => !STEVE_ADD.includes(na));
|
|
3
15
|
|
|
4
16
|
export default class SteveModel extends HybridModel {
|
|
5
17
|
get name() {
|
|
@@ -28,4 +40,14 @@ export default class SteveModel extends HybridModel {
|
|
|
28
40
|
|
|
29
41
|
this._description = value;
|
|
30
42
|
}
|
|
43
|
+
|
|
44
|
+
cleanForSave(data, forNew) {
|
|
45
|
+
const val = super.cleanForSave(data);
|
|
46
|
+
|
|
47
|
+
for (const field of STEVE_NEVER_SAVE) {
|
|
48
|
+
deleteProperty(val, field);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return val;
|
|
52
|
+
}
|
|
31
53
|
}
|
|
@@ -332,10 +332,6 @@ const sharedActions = {
|
|
|
332
332
|
|
|
333
333
|
commit('setWantSocket', true);
|
|
334
334
|
|
|
335
|
-
if ( process.server ) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
335
|
state.debugSocket && console.info(`Subscribe [${ getters.storeName }]`); // eslint-disable-line no-console
|
|
340
336
|
|
|
341
337
|
const url = `${ state.config.baseUrl }/subscribe`;
|
|
@@ -601,7 +597,7 @@ const defaultActions = {
|
|
|
601
597
|
},
|
|
602
598
|
|
|
603
599
|
rehydrateSubscribe({ state, dispatch }) {
|
|
604
|
-
if (
|
|
600
|
+
if ( state.wantSocket && !state.socket ) {
|
|
605
601
|
dispatch('subscribe');
|
|
606
602
|
}
|
|
607
603
|
},
|
|
@@ -728,11 +724,9 @@ const defaultActions = {
|
|
|
728
724
|
}
|
|
729
725
|
|
|
730
726
|
// Try resending any frames that were attempted to be sent while the socket was down, once.
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
dispatch('sendImmediate', obj);
|
|
735
|
-
}
|
|
727
|
+
for ( const obj of state.pendingFrames.slice() ) {
|
|
728
|
+
commit('dequeuePendingFrame', obj);
|
|
729
|
+
dispatch('sendImmediate', obj);
|
|
736
730
|
}
|
|
737
731
|
},
|
|
738
732
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import { Accordion } from './index';
|
|
3
|
+
|
|
4
|
+
describe('component: Accordion', () => {
|
|
5
|
+
it('is closed initially by default', () => {
|
|
6
|
+
const title = 'Test Title';
|
|
7
|
+
|
|
8
|
+
const wrapper = shallowMount(Accordion, { propsData: { title } });
|
|
9
|
+
|
|
10
|
+
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
11
|
+
expect(wrapper.find('[data-testid="accordion-header"]').text()).toBe(title);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('is opened initially when openInitially prop is true', () => {
|
|
15
|
+
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
16
|
+
|
|
17
|
+
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('when closed, opens when the header is clicked', async() => {
|
|
21
|
+
const wrapper = shallowMount(Accordion, { });
|
|
22
|
+
|
|
23
|
+
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
24
|
+
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('when open, closes when the header is clicked', async() => {
|
|
28
|
+
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
29
|
+
|
|
30
|
+
await wrapper.find('[data-testid="accordion-header"]').trigger('click');
|
|
31
|
+
expect(wrapper.find('[data-testid="accordion-body"]').isVisible()).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('displays a chevron when closed', async() => {
|
|
35
|
+
const wrapper = shallowMount(Accordion, { propsData: { } });
|
|
36
|
+
|
|
37
|
+
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-up').exists()).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('displays an inverted chevron when open', async() => {
|
|
41
|
+
const wrapper = shallowMount(Accordion, { propsData: { openInitially: true } });
|
|
42
|
+
|
|
43
|
+
expect(wrapper.find('[data-testid="accordion-header"] .icon-chevron-down').exists()).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { defineComponent } from 'vue';
|
|
3
|
+
import { mapGetters } from 'vuex';
|
|
4
|
+
|
|
5
|
+
export default defineComponent({
|
|
6
|
+
props: {
|
|
7
|
+
title: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: ''
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
titleKey: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: null
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
openInitially: {
|
|
18
|
+
type: Boolean,
|
|
19
|
+
default: false
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
data() {
|
|
24
|
+
return { isOpen: this.openInitially };
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
computed: { ...mapGetters({ t: 'i18n/t' }) },
|
|
28
|
+
|
|
29
|
+
methods: {
|
|
30
|
+
toggle() {
|
|
31
|
+
this.isOpen = !this.isOpen;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<div class="accordion-container">
|
|
39
|
+
<div
|
|
40
|
+
class="accordion-header"
|
|
41
|
+
data-testid="accordion-header"
|
|
42
|
+
@click="toggle"
|
|
43
|
+
>
|
|
44
|
+
<i
|
|
45
|
+
class="icon text-primary"
|
|
46
|
+
:class="{'icon-chevron-down':isOpen, 'icon-chevron-up':!isOpen}"
|
|
47
|
+
data-testid="accordion-chevron"
|
|
48
|
+
/>
|
|
49
|
+
<slot name="header">
|
|
50
|
+
<h4
|
|
51
|
+
data-testid="accordion-title-slot-content"
|
|
52
|
+
class="mb-0"
|
|
53
|
+
>
|
|
54
|
+
{{ titleKey ? t(titleKey) : title }}
|
|
55
|
+
</h4>
|
|
56
|
+
</slot>
|
|
57
|
+
</div>
|
|
58
|
+
<div
|
|
59
|
+
v-show="isOpen"
|
|
60
|
+
class="accordion-body"
|
|
61
|
+
data-testid="accordion-body"
|
|
62
|
+
>
|
|
63
|
+
<slot />
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<style lang="scss" scoped>
|
|
69
|
+
.accordion-container {
|
|
70
|
+
border: 1px solid var(--border)
|
|
71
|
+
}
|
|
72
|
+
.accordion-header {
|
|
73
|
+
padding: 5px;
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
&>*{
|
|
77
|
+
padding: 5px 0px 5px 0px;
|
|
78
|
+
}
|
|
79
|
+
I {
|
|
80
|
+
margin: 0px 10px 0px 10px;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
.accordion-body {
|
|
84
|
+
padding: 10px;
|
|
85
|
+
}
|
|
86
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Accordion } from './Accordion.vue';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { PropType, defineComponent } from 'vue';
|
|
3
3
|
|
|
4
4
|
interface Badge {
|
|
5
5
|
stateBackground: string;
|
|
@@ -11,7 +11,7 @@ interface Badge {
|
|
|
11
11
|
* <p>Represents a badge whose label and color is either taken from the value property or
|
|
12
12
|
* from the label and color properties. The state property takes precedence.</p>
|
|
13
13
|
*/
|
|
14
|
-
export default
|
|
14
|
+
export default defineComponent({
|
|
15
15
|
props: {
|
|
16
16
|
/**
|
|
17
17
|
* A value having the properties `stateBackground` and `stateDisplay`
|
|
@@ -59,7 +59,7 @@ export default Vue.extend({
|
|
|
59
59
|
</script>
|
|
60
60
|
|
|
61
61
|
<template>
|
|
62
|
-
<span :class="
|
|
62
|
+
<span :class="['badge-state', bg]">
|
|
63
63
|
<i
|
|
64
64
|
v-if="icon"
|
|
65
65
|
class="icon"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { defineComponent } from 'vue';
|
|
3
3
|
import { nlToBr } from '@shell/utils/string';
|
|
4
4
|
import { stringify } from '@shell/utils/error';
|
|
5
5
|
|
|
6
|
-
export default
|
|
6
|
+
export default defineComponent({
|
|
7
7
|
props: {
|
|
8
8
|
/**
|
|
9
9
|
* A color class that represents the color of the banner.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { defineComponent, PropType } from 'vue';
|
|
3
3
|
|
|
4
|
-
export default
|
|
4
|
+
export default defineComponent({
|
|
5
5
|
name: 'Card',
|
|
6
6
|
props: {
|
|
7
7
|
/**
|
|
@@ -22,7 +22,7 @@ export default Vue.extend({
|
|
|
22
22
|
* The function to invoke when the default action button is clicked.
|
|
23
23
|
*/
|
|
24
24
|
buttonAction: {
|
|
25
|
-
type: Function
|
|
25
|
+
type: Function as PropType<(event: MouseEvent) => void>,
|
|
26
26
|
default: (): void => { }
|
|
27
27
|
},
|
|
28
28
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { PropType, defineComponent } from 'vue';
|
|
3
3
|
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
4
4
|
import { addObject, removeObject } from '@shell/utils/array';
|
|
5
5
|
import cloneDeep from 'lodash/cloneDeep';
|
|
6
6
|
|
|
7
|
-
export default
|
|
7
|
+
export default defineComponent({
|
|
8
8
|
name: 'Checkbox',
|
|
9
9
|
|
|
10
10
|
props: {
|
|
@@ -140,7 +140,7 @@ export default Vue.extend({
|
|
|
140
140
|
/**
|
|
141
141
|
* Toggles the checked state for the checkbox and emits an 'input' event.
|
|
142
142
|
*/
|
|
143
|
-
clicked(event: MouseEvent): boolean | void {
|
|
143
|
+
clicked(event: MouseEvent | KeyboardEvent): boolean | void {
|
|
144
144
|
if ((event.target as HTMLLinkElement).tagName === 'A' && (event.target as HTMLLinkElement).href) {
|
|
145
145
|
// Ignore links inside the checkbox label so you can click them
|
|
146
146
|
return true;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { mount } from '@vue/test-utils';
|
|
3
2
|
import { LabeledInput } from './index';
|
|
4
3
|
|
|
@@ -20,4 +19,22 @@ describe('component: LabeledInput', () => {
|
|
|
20
19
|
expect(wrapper.emitted('input')).toHaveLength(1);
|
|
21
20
|
expect(wrapper.emitted('input')![0][0]).toBe(value);
|
|
22
21
|
});
|
|
22
|
+
|
|
23
|
+
it('using mode "multiline" should emit input value correctly', () => {
|
|
24
|
+
const value = 'any-string';
|
|
25
|
+
const delay = 1;
|
|
26
|
+
const wrapper = mount(LabeledInput as any, {
|
|
27
|
+
propsData: { delay, multiline: true },
|
|
28
|
+
mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
jest.useFakeTimers();
|
|
32
|
+
wrapper.find('input').setValue('1');
|
|
33
|
+
wrapper.find('input').setValue(value);
|
|
34
|
+
jest.advanceTimersByTime(delay);
|
|
35
|
+
jest.useRealTimers();
|
|
36
|
+
|
|
37
|
+
expect(wrapper.emitted('input')).toHaveLength(1);
|
|
38
|
+
expect(wrapper.emitted('input')![0][0]).toBe(value);
|
|
39
|
+
});
|
|
23
40
|
});
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import CompactInput from '@shell/mixins/compact-input';
|
|
4
|
-
import LabeledFormElement from '@shell/mixins/labeled-form-element';
|
|
2
|
+
import { defineComponent } from 'vue';
|
|
5
3
|
import TextAreaAutoGrow from '@components/Form/TextArea/TextAreaAutoGrow.vue';
|
|
6
4
|
import LabeledTooltip from '@components/LabeledTooltip/LabeledTooltip.vue';
|
|
7
5
|
import { escapeHtml } from '@shell/utils/string';
|
|
8
6
|
import cronstrue from 'cronstrue';
|
|
9
7
|
import { isValidCron } from 'cron-validator';
|
|
10
8
|
import { debounce } from 'lodash';
|
|
9
|
+
import { useLabeledFormElement, labeledFormElementProps } from '@shell/composables/useLabeledFormElement';
|
|
10
|
+
import { useCompactInput } from '@shell/composables/useCompactInput';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
)
|
|
12
|
+
declare module 'vue/types/vue' {
|
|
13
|
+
interface Vue {
|
|
14
|
+
onInput: (event: Event) => void | ((event: Event) => void);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default defineComponent({
|
|
15
19
|
components: { LabeledTooltip, TextAreaAutoGrow },
|
|
16
|
-
|
|
20
|
+
|
|
21
|
+
inheritAttrs: false,
|
|
17
22
|
|
|
18
23
|
props: {
|
|
24
|
+
...labeledFormElementProps,
|
|
19
25
|
/**
|
|
20
26
|
* The type of the Labeled Input.
|
|
21
27
|
* @values text, cron, multiline, multiline-password
|
|
@@ -90,24 +96,39 @@ export default (
|
|
|
90
96
|
delay: {
|
|
91
97
|
type: Number,
|
|
92
98
|
default: 0
|
|
93
|
-
}
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
setup(props, { emit }) {
|
|
103
|
+
const {
|
|
104
|
+
focused,
|
|
105
|
+
onFocusLabeled,
|
|
106
|
+
onBlurLabeled,
|
|
107
|
+
isDisabled,
|
|
108
|
+
validationMessage,
|
|
109
|
+
requiredField
|
|
110
|
+
} = useLabeledFormElement(props, emit);
|
|
111
|
+
const { isCompact } = useCompactInput(props);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
focused,
|
|
115
|
+
onFocusLabeled,
|
|
116
|
+
onBlurLabeled,
|
|
117
|
+
isDisabled,
|
|
118
|
+
validationMessage,
|
|
119
|
+
requiredField,
|
|
120
|
+
isCompact,
|
|
121
|
+
};
|
|
94
122
|
},
|
|
95
123
|
|
|
96
124
|
data() {
|
|
97
125
|
return {
|
|
98
126
|
updated: false,
|
|
99
|
-
validationErrors: ''
|
|
127
|
+
validationErrors: '',
|
|
100
128
|
};
|
|
101
129
|
},
|
|
102
130
|
|
|
103
131
|
computed: {
|
|
104
|
-
/**
|
|
105
|
-
* Determines if the Labeled Input @input event should be debounced.
|
|
106
|
-
*/
|
|
107
|
-
onInput(): ((value: string) => void) | void {
|
|
108
|
-
return this.delay ? debounce(this.delayInput, this.delay) : this.delayInput;
|
|
109
|
-
},
|
|
110
|
-
|
|
111
132
|
/**
|
|
112
133
|
* Determines if the Labeled Input should display a label.
|
|
113
134
|
*/
|
|
@@ -122,7 +143,7 @@ export default (
|
|
|
122
143
|
return !!this.tooltip || !!this.tooltipKey;
|
|
123
144
|
},
|
|
124
145
|
|
|
125
|
-
tooltipValue(): string | undefined {
|
|
146
|
+
tooltipValue(): string | Record<string, unknown> | undefined {
|
|
126
147
|
if (this.hasTooltip) {
|
|
127
148
|
return this.tooltipKey ? this.t(this.tooltipKey) : this.tooltip;
|
|
128
149
|
}
|
|
@@ -144,7 +165,7 @@ export default (
|
|
|
144
165
|
if (this.type !== 'cron' || !this.value) {
|
|
145
166
|
return;
|
|
146
167
|
}
|
|
147
|
-
if (!isValidCron(this.value)) {
|
|
168
|
+
if (typeof this.value === 'string' && !isValidCron(this.value)) {
|
|
148
169
|
return this.t('generic.invalidCron');
|
|
149
170
|
}
|
|
150
171
|
try {
|
|
@@ -173,15 +194,22 @@ export default (
|
|
|
173
194
|
/**
|
|
174
195
|
* The max length for the Labeled Input.
|
|
175
196
|
*/
|
|
176
|
-
_maxlength(): number |
|
|
197
|
+
_maxlength(): number | undefined {
|
|
177
198
|
if (this.type === 'text' && this.maxlength) {
|
|
178
199
|
return this.maxlength;
|
|
179
200
|
}
|
|
180
201
|
|
|
181
|
-
return
|
|
202
|
+
return undefined;
|
|
182
203
|
},
|
|
183
204
|
},
|
|
184
205
|
|
|
206
|
+
created() {
|
|
207
|
+
/**
|
|
208
|
+
* Determines if the Labeled Input @input event should be debounced.
|
|
209
|
+
*/
|
|
210
|
+
this.onInput = this.delay ? debounce(this.delayInput, this.delay) : this.delayInput;
|
|
211
|
+
},
|
|
212
|
+
|
|
185
213
|
methods: {
|
|
186
214
|
/**
|
|
187
215
|
* Attempts to give the Labeled Input focus.
|
|
@@ -206,11 +234,23 @@ export default (
|
|
|
206
234
|
}
|
|
207
235
|
},
|
|
208
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Emit on input change
|
|
239
|
+
*/
|
|
240
|
+
onChange(event: Event): void {
|
|
241
|
+
this.$emit('change', event);
|
|
242
|
+
},
|
|
243
|
+
|
|
209
244
|
/**
|
|
210
245
|
* Emit on input with delay. Note: Arrow function is avoided due context
|
|
211
246
|
* binding.
|
|
247
|
+
*
|
|
248
|
+
* NOTE: In multiline, TextAreaAutoGrow emits a string with the value
|
|
249
|
+
* https://github.com/rancher/dashboard/issues/10249
|
|
212
250
|
*/
|
|
213
|
-
delayInput(
|
|
251
|
+
delayInput(val: string | Event): void {
|
|
252
|
+
const value = typeof val === 'string' ? val : (val?.target as HTMLInputElement)?.value;
|
|
253
|
+
|
|
214
254
|
this.$emit('input', value);
|
|
215
255
|
},
|
|
216
256
|
|
|
@@ -227,7 +267,7 @@ export default (
|
|
|
227
267
|
* event.
|
|
228
268
|
* @see labeled-form-element.ts mixin for onBlurLabeled()
|
|
229
269
|
*/
|
|
230
|
-
onBlur(event: string): void {
|
|
270
|
+
onBlur(event: string | FocusEvent): void {
|
|
231
271
|
this.$emit('blur', event);
|
|
232
272
|
this.onBlurLabeled();
|
|
233
273
|
},
|
|
@@ -279,7 +319,7 @@ export default (
|
|
|
279
319
|
:placeholder="_placeholder"
|
|
280
320
|
autocapitalize="off"
|
|
281
321
|
:class="{ conceal: type === 'multiline-password' }"
|
|
282
|
-
@input="onInput
|
|
322
|
+
@input="onInput"
|
|
283
323
|
@focus="onFocus"
|
|
284
324
|
@blur="onBlur"
|
|
285
325
|
/>
|
|
@@ -296,9 +336,10 @@ export default (
|
|
|
296
336
|
autocomplete="off"
|
|
297
337
|
autocapitalize="off"
|
|
298
338
|
:data-lpignore="ignorePasswordManagers"
|
|
299
|
-
@input="onInput
|
|
339
|
+
@input="onInput"
|
|
300
340
|
@focus="onFocus"
|
|
301
341
|
@blur="onBlur"
|
|
342
|
+
@change="onChange"
|
|
302
343
|
>
|
|
303
344
|
</slot>
|
|
304
345
|
|
|
@@ -4,7 +4,7 @@ import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
|
4
4
|
|
|
5
5
|
describe('radioButton.vue', () => {
|
|
6
6
|
it('renders label slot contents', () => {
|
|
7
|
-
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' } });
|
|
7
|
+
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' }, propsData: { val: {}, value: {} } });
|
|
8
8
|
|
|
9
9
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
10
10
|
});
|
|
@@ -14,7 +14,9 @@ describe('radioButton.vue', () => {
|
|
|
14
14
|
RadioButton,
|
|
15
15
|
{
|
|
16
16
|
directives: { cleanHtmlDirective },
|
|
17
|
-
propsData: {
|
|
17
|
+
propsData: {
|
|
18
|
+
label: 'Test Label', val: {}, value: {}
|
|
19
|
+
}
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
@@ -23,7 +25,9 @@ describe('radioButton.vue', () => {
|
|
|
23
25
|
it('renders slot contents when both slot and label prop are provided', () => {
|
|
24
26
|
const wrapper = shallowMount(RadioButton, {
|
|
25
27
|
slots: { label: 'Test Label - Slot' },
|
|
26
|
-
propsData: {
|
|
28
|
+
propsData: {
|
|
29
|
+
label: 'Test Label - Props', val: {}, value: {}
|
|
30
|
+
},
|
|
27
31
|
});
|
|
28
32
|
|
|
29
33
|
expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
|