mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-04 21:26:08 +08:00
Merge branch 'main' into issue-7081
This commit is contained in:
@@ -25,6 +25,9 @@ export default {
|
||||
|
||||
return Array.from(new Set(options));
|
||||
},
|
||||
enableFilterButton() {
|
||||
return this.rows.some((r) => r.sourceSchedule !== undefined);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -63,27 +66,30 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="vm-schedule-filter">
|
||||
<template>
|
||||
<span
|
||||
v-if="selected"
|
||||
class="banner-item bg-warning"
|
||||
>
|
||||
{{ t('harvester.tableHeaders.vmSchedule') }}{{ selected ? ` = ${selected}`: '' }}<i
|
||||
class="icon icon-close ml-5"
|
||||
@click="remove"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div
|
||||
class="vm-schedule-filter"
|
||||
>
|
||||
<span
|
||||
v-if="selected"
|
||||
class="banner-item bg-warning"
|
||||
>
|
||||
{{ t('harvester.tableHeaders.vmSchedule') }}{{ selected ? ` = ${selected}`: '' }}
|
||||
<i
|
||||
class="icon icon-close ml-5"
|
||||
@click="remove"
|
||||
/>
|
||||
</span>
|
||||
<v-dropdown
|
||||
popper-class="vm-schedule-dropdown"
|
||||
:triggers="scheduleOptions.length ? ['click'] : []"
|
||||
placement="bottom-end"
|
||||
offset="1"
|
||||
:distance="20"
|
||||
>
|
||||
<button
|
||||
ref="actionDropDown"
|
||||
class="btn bg-primary mr-10"
|
||||
:disabled="!enableFilterButton"
|
||||
>
|
||||
<slot name="title">
|
||||
{{ t('harvester.fields.filterSchedule') }}
|
||||
@@ -98,7 +104,7 @@ export default {
|
||||
name="model"
|
||||
:options="scheduleOptions"
|
||||
:labels="scheduleOptions"
|
||||
@input="onSelect"
|
||||
@update:value="onSelect"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -106,6 +112,12 @@ export default {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.vm-schedule-dropdown .v-popper__arrow-container {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vm-schedule-filter {
|
||||
display: inline-block;
|
||||
|
||||
@@ -60,7 +60,8 @@ export default {
|
||||
});
|
||||
|
||||
this.queue = [];
|
||||
}, 5)
|
||||
}, 10),
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ const featuresV132 = [
|
||||
'improveMaintenanceMode',
|
||||
];
|
||||
|
||||
// TODO: add v1.3.3 official release note
|
||||
// https://github.com/harvester/dashboard/releases/tag/v1.3.3-dev-20250105
|
||||
const featuresV133 = [
|
||||
...featuresV132,
|
||||
];
|
||||
|
||||
// https://github.com/harvester/dashboard/releases/tag/v1.4.0
|
||||
const featuresV140 = [
|
||||
...featuresV132,
|
||||
@@ -35,10 +41,17 @@ const featuresV141 = [
|
||||
...featuresV140
|
||||
];
|
||||
|
||||
// TODO: add v1.5.0 official release note
|
||||
const featuresV150 = [
|
||||
...featuresV141
|
||||
];
|
||||
|
||||
export const RELEASE_FEATURES = {
|
||||
'v1.3.0': featuresV130,
|
||||
'v1.3.1': featuresV131,
|
||||
'v1.3.2': featuresV132,
|
||||
'v1.3.3': featuresV133,
|
||||
'v1.4.0': featuresV140,
|
||||
'v1.4.1': featuresV141,
|
||||
'v1.5.0': featuresV150
|
||||
};
|
||||
|
||||
@@ -24,35 +24,24 @@ export default {
|
||||
},
|
||||
|
||||
async fetch() {
|
||||
const hash = await allHash({
|
||||
await allHash({
|
||||
vms: this.$store.dispatch('harvester/findAll', { type: HCI.VM }),
|
||||
vmis: this.$store.dispatch('harvester/findAll', { type: HCI.VMI }),
|
||||
allClusterNetwork: this.$store.dispatch('harvester/findAll', { type: HCI.CLUSTER_NETWORK }),
|
||||
});
|
||||
const instanceMap = {};
|
||||
|
||||
(hash.vmis || []).forEach((vmi) => {
|
||||
const vmiUID = vmi?.metadata?.ownerReferences?.[0]?.uid;
|
||||
|
||||
if (vmiUID) {
|
||||
instanceMap[vmiUID] = vmi;
|
||||
}
|
||||
});
|
||||
|
||||
this.allClusterNetwork = hash.allClusterNetwork;
|
||||
this.rows = hash.vms.filter((row) => {
|
||||
return instanceMap[row.metadata?.uid]?.status?.nodeName === this.node?.metadata?.labels?.[HOSTNAME];
|
||||
});
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
rows: [],
|
||||
allClusterNetwork: []
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
allClusterNetwork() {
|
||||
return this.$store.getters['harvester/all'](HCI.CLUSTER_NETWORK);
|
||||
},
|
||||
|
||||
rows() {
|
||||
const vms = this.$store.getters['harvester/all'](HCI.VM);
|
||||
|
||||
return vms.filter((vm) => vm.vmi?.status?.nodeName === this.node?.metadata?.labels?.[HOSTNAME]);
|
||||
},
|
||||
|
||||
headers() {
|
||||
return [
|
||||
STATE,
|
||||
@@ -87,8 +76,6 @@ export default {
|
||||
];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,34 +1,31 @@
|
||||
<script>
|
||||
import merge from 'lodash/merge';
|
||||
import jsyaml from 'js-yaml';
|
||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
import Tabbed from '@shell/components/Tabbed';
|
||||
import Tab from '@shell/components/Tabbed/Tab';
|
||||
import { RadioGroup } from '@components/Form/Radio';
|
||||
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
||||
|
||||
import CreateEditView from '@shell/mixins/create-edit-view';
|
||||
|
||||
import { STORAGE_CLASS } from '@shell/config/types';
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { set, get, clone } from '@shell/utils/object';
|
||||
|
||||
const VALUES_YAML_KEYS = [
|
||||
'resources.requests.cpu',
|
||||
'resources.requests.memory',
|
||||
'resources.limits.cpu',
|
||||
'resources.limits.memory',
|
||||
'pvcClaim.enabled',
|
||||
'pvcClaim.size',
|
||||
'pvcClaim.storageClassName',
|
||||
];
|
||||
|
||||
const DEFAULT_VALUES = {
|
||||
'resources.requests.cpu': '0.5',
|
||||
'resources.requests.memory': '2Gi',
|
||||
'resources.limits.cpu': '2',
|
||||
'resources.limits.memory': '4Gi',
|
||||
'pvcClaim.enabled': false,
|
||||
'pvcClaim.size': '200Gi',
|
||||
'pvcClaim.storageClassName': '',
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: '0.5',
|
||||
memory: '2Gi'
|
||||
},
|
||||
limits: {
|
||||
cpu: '2',
|
||||
memory: '4Gi'
|
||||
}
|
||||
},
|
||||
pvcClaim: {
|
||||
enabled: false,
|
||||
size: '200Gi',
|
||||
storageClassName: ''
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
@@ -64,19 +61,7 @@ export default {
|
||||
},
|
||||
|
||||
data() {
|
||||
let valuesObj = {};
|
||||
|
||||
try {
|
||||
valuesObj = JSON.parse(this.value?.spec?.valuesContent || '{}');
|
||||
} catch (err) {}
|
||||
|
||||
const valuesContent = clone(valuesObj);
|
||||
|
||||
VALUES_YAML_KEYS.map((key) => {
|
||||
if (!get(valuesObj, key)) {
|
||||
set(valuesContent, key, DEFAULT_VALUES[key]);
|
||||
}
|
||||
});
|
||||
const valuesContent = this.parseValuesContent();
|
||||
|
||||
return { valuesContent };
|
||||
},
|
||||
@@ -100,8 +85,21 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseValuesContent() {
|
||||
try {
|
||||
return merge({}, DEFAULT_VALUES, jsyaml.load(this.value.spec.valuesContent));
|
||||
} catch (err) {
|
||||
this.$store.dispatch('growl/fromError', {
|
||||
title: this.$store.getters['i18n/t']('generic.notification.title.error'),
|
||||
err: err.data || err,
|
||||
}, { root: true });
|
||||
|
||||
return DEFAULT_VALUES;
|
||||
}
|
||||
},
|
||||
|
||||
update() {
|
||||
set(this.value, 'spec.valuesContent', JSON.stringify(this.valuesContent));
|
||||
this.value.spec.valuesContent = jsyaml.dump(this.valuesContent);
|
||||
},
|
||||
|
||||
setDefaultClassName() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { Sortable } from 'sortablejs-vue3';
|
||||
import { VueDraggableNext } from 'vue-draggable-next';
|
||||
import InfoBox from '@shell/components/InfoBox';
|
||||
import { Banner } from '@components/Banner';
|
||||
import BadgeStateFormatter from '@shell/components/formatter/BadgeStateFormatter';
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
components: {
|
||||
Banner, BadgeStateFormatter, Sortable, InfoBox, LabeledInput, UnitInput, LabeledSelect, ModalWithCard
|
||||
Banner, BadgeStateFormatter, VueDraggableNext, InfoBox, LabeledInput, UnitInput, LabeledSelect, ModalWithCard
|
||||
},
|
||||
|
||||
props: {
|
||||
@@ -272,129 +272,130 @@ export default {
|
||||
color="info"
|
||||
label-key="harvester.virtualMachine.volume.dragTip"
|
||||
/>
|
||||
<Sortable
|
||||
<VueDraggableNext
|
||||
:list="rows"
|
||||
:options="{disabled: isView}"
|
||||
:disabled="isView"
|
||||
item-key="id"
|
||||
@end="update"
|
||||
>
|
||||
<template #item="{element: volume, index: i}">
|
||||
<div :key="volume.name">
|
||||
<InfoBox class="box">
|
||||
<button
|
||||
<div
|
||||
v-for="(volume, i) in rows"
|
||||
:key="volume.id"
|
||||
>
|
||||
<InfoBox class="box">
|
||||
<button
|
||||
v-if="!isView"
|
||||
type="button"
|
||||
class="role-link btn btn-sm remove"
|
||||
@click="removeVolume(volume)"
|
||||
>
|
||||
<i class="icon icon-x" />
|
||||
</button>
|
||||
<button
|
||||
v-if="volume.hotpluggable && isView"
|
||||
type="button"
|
||||
class="role-link btn remove"
|
||||
@click="unplugVolume(volume)"
|
||||
>
|
||||
{{ t('harvester.virtualMachine.unplug.detachVolume') }}
|
||||
</button>
|
||||
<h3>
|
||||
<span
|
||||
v-if="volume.to && isVirtualType"
|
||||
class="title"
|
||||
>
|
||||
<router-link :to="volume.to">
|
||||
{{ t('harvester.virtualMachine.volume.edit') }} {{ headerFor(volume.source) }}
|
||||
</router-link>
|
||||
|
||||
<BadgeStateFormatter
|
||||
v-if="volume.pvc"
|
||||
class="ml-10 state"
|
||||
:arbitrary="true"
|
||||
:row="volume.pvc"
|
||||
:value="volume.pvc.state"
|
||||
/>
|
||||
<a
|
||||
v-if="dev && !!volume.pvc && !!volume.pvc.resourceExternalLink"
|
||||
v-clean-tooltip="t(volume.pvc.resourceExternalLink.tipsKey || 'generic.resourceExternalLinkTips')"
|
||||
class="ml-5 resource-external"
|
||||
rel="nofollow noopener noreferrer"
|
||||
target="_blank"
|
||||
:href="volume.pvc.resourceExternalLink.url"
|
||||
>
|
||||
<i class="icon icon-external-link" />
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span v-else>
|
||||
{{ headerFor(volume.source, !!volume?.volumeBackups) }}
|
||||
</span>
|
||||
</h3>
|
||||
<div>
|
||||
<component
|
||||
:is="componentFor(volume.source)"
|
||||
:value="rows[i]"
|
||||
:rows="rows"
|
||||
:namespace="namespace"
|
||||
:is-create="isCreate"
|
||||
:is-edit="isEdit"
|
||||
:is-view="isView"
|
||||
:is-virtual-type="isVirtualType"
|
||||
:mode="mode"
|
||||
:idx="i"
|
||||
:validate-required="validateRequired"
|
||||
@update="update"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="bootOrder">
|
||||
<div
|
||||
v-if="!isView"
|
||||
type="button"
|
||||
class="role-link btn btn-sm remove"
|
||||
@click="removeVolume(volume)"
|
||||
class="mr-15"
|
||||
>
|
||||
<i class="icon icon-x" />
|
||||
</button>
|
||||
<button
|
||||
v-if="volume.hotpluggable && isView"
|
||||
type="button"
|
||||
class="role-link btn remove"
|
||||
@click="unplugVolume(volume)"
|
||||
>
|
||||
{{ t('harvester.virtualMachine.unplug.detachVolume') }}
|
||||
</button>
|
||||
<h3>
|
||||
<span
|
||||
v-if="volume.to && isVirtualType"
|
||||
class="title"
|
||||
<button
|
||||
:disabled="i === 0"
|
||||
class="btn btn-sm role-primary"
|
||||
@click.prevent="changeSort(i, false)"
|
||||
>
|
||||
<router-link :to="volume.to">
|
||||
{{ t('harvester.virtualMachine.volume.edit') }} {{ headerFor(volume.source) }}
|
||||
</router-link>
|
||||
<i class="icon icon-lg icon-chevron-up"></i>
|
||||
</button>
|
||||
|
||||
<BadgeStateFormatter
|
||||
v-if="volume.pvc"
|
||||
class="ml-10 state"
|
||||
:arbitrary="true"
|
||||
:row="volume.pvc"
|
||||
:value="volume.pvc.state"
|
||||
/>
|
||||
<a
|
||||
v-if="dev && !!volume.pvc && !!volume.pvc.resourceExternalLink"
|
||||
v-clean-tooltip="t(volume.pvc.resourceExternalLink.tipsKey || 'generic.resourceExternalLinkTips')"
|
||||
class="ml-5 resource-external"
|
||||
rel="nofollow noopener noreferrer"
|
||||
target="_blank"
|
||||
:href="volume.pvc.resourceExternalLink.url"
|
||||
>
|
||||
<i class="icon icon-external-link" />
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span v-else>
|
||||
{{ headerFor(volume.source, !!volume?.volumeBackups) }}
|
||||
</span>
|
||||
</h3>
|
||||
<div>
|
||||
<component
|
||||
:is="componentFor(volume.source)"
|
||||
:value="rows[i]"
|
||||
:rows="rows"
|
||||
:namespace="namespace"
|
||||
:is-create="isCreate"
|
||||
:is-edit="isEdit"
|
||||
:is-view="isView"
|
||||
:is-virtual-type="isVirtualType"
|
||||
:mode="mode"
|
||||
:idx="i"
|
||||
:validate-required="validateRequired"
|
||||
@update="update"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="bootOrder">
|
||||
<div
|
||||
v-if="!isView"
|
||||
class="mr-15"
|
||||
<button
|
||||
:disabled="i === rows.length -1"
|
||||
class="btn btn-sm role-primary"
|
||||
@click.prevent="changeSort(i, true)"
|
||||
>
|
||||
<button
|
||||
:disabled="i === 0"
|
||||
class="btn btn-sm role-primary"
|
||||
@click.prevent="changeSort(i, false)"
|
||||
>
|
||||
<i class="icon icon-lg icon-chevron-up"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
:disabled="i === rows.length -1"
|
||||
class="btn btn-sm role-primary"
|
||||
@click.prevent="changeSort(i, true)"
|
||||
>
|
||||
<i class="icon icon-lg icon-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="text-muted">
|
||||
bootOrder: {{ i + 1 }}
|
||||
</div>
|
||||
<i class="icon icon-lg icon-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-15">
|
||||
<Banner
|
||||
v-if="volume.volumeStatus && !isCreate"
|
||||
class="volume-status"
|
||||
color="warning"
|
||||
:label="ucFirst(volume.volumeStatus)"
|
||||
/>
|
||||
<Banner
|
||||
v-if="value.volumeBackups && value.volumeBackups.error && value.volumeBackups.error.message"
|
||||
color="error"
|
||||
:label="ucFirst(value.volumeBackups.error.message)"
|
||||
/>
|
||||
<Banner
|
||||
v-if="isLonghornV2(volume) && !isView"
|
||||
color="warning"
|
||||
:label="t('harvester.volume.longhorn.disableResize')"
|
||||
/>
|
||||
<div class="text-muted">
|
||||
bootOrder: {{ i + 1 }}
|
||||
</div>
|
||||
</InfoBox>
|
||||
</div>
|
||||
</template>
|
||||
</Sortable>
|
||||
</div>
|
||||
|
||||
<div class="mt-15">
|
||||
<Banner
|
||||
v-if="volume.volumeStatus && !isCreate"
|
||||
class="volume-status"
|
||||
color="warning"
|
||||
:label="ucFirst(volume.volumeStatus)"
|
||||
/>
|
||||
<Banner
|
||||
v-if="value.volumeBackups && value.volumeBackups.error && value.volumeBackups.error.message"
|
||||
color="error"
|
||||
:label="ucFirst(value.volumeBackups.error.message)"
|
||||
/>
|
||||
<Banner
|
||||
v-if="isLonghornV2(volume) && !isView"
|
||||
color="warning"
|
||||
:label="t('harvester.volume.longhorn.disableResize')"
|
||||
/>
|
||||
</div>
|
||||
</InfoBox>
|
||||
</div>
|
||||
</VueDraggableNext>
|
||||
<Banner
|
||||
v-if="showVolumeTip"
|
||||
color="warning"
|
||||
|
||||
@@ -742,6 +742,9 @@ harvester:
|
||||
terminationGracePeriodSeconds:
|
||||
label: Termination Grace Period
|
||||
affinity:
|
||||
addLabel: Add Workload Selector
|
||||
topologyKey:
|
||||
placeholder: 'topology.kubernetes.io/zone'
|
||||
thisPodNamespace: This virtual machine's namespace
|
||||
matchExpressions:
|
||||
inNamespaces: "Workloads in these namespaces"
|
||||
@@ -1494,18 +1497,6 @@ harvester:
|
||||
pollingInterval:
|
||||
label: Polling Interval
|
||||
|
||||
affinity:
|
||||
thisPodNamespace: This virtual machine's namespace
|
||||
matchExpressions:
|
||||
inNamespaces: "Workloads in these namespaces"
|
||||
vmAffinityTitle: Virtual Machine Scheduling
|
||||
namespaces:
|
||||
placeholder: e.g. default,system,base
|
||||
label: Namespaces
|
||||
addLabel: Add Workload Selector
|
||||
topologyKey:
|
||||
placeholder: 'topology.kubernetes.io/zone'
|
||||
|
||||
advancedSettings:
|
||||
experimental: 'Experimental features allow users to test and evaluate early-access functionality prior to official supported releases'
|
||||
descriptions:
|
||||
|
||||
@@ -282,14 +282,14 @@ export default {
|
||||
|
||||
affinityLabels() {
|
||||
return {
|
||||
namespaceInputLabel: this.t('harvesterManager.affinity.namespaces.label'),
|
||||
namespaceInputLabel: this.t('harvester.virtualMachine.affinity.namespaces.label'),
|
||||
namespaceSelectionLabels: [
|
||||
this.t('harvesterManager.affinity.thisPodNamespace'),
|
||||
this.t('harvester.virtualMachine.affinity.thisPodNamespace'),
|
||||
this.t('workload.scheduling.affinity.allNamespaces'),
|
||||
this.t('harvesterManager.affinity.matchExpressions.inNamespaces')
|
||||
this.t('harvester.virtualMachine.affinity.matchExpressions.inNamespaces')
|
||||
],
|
||||
addLabel: this.t('harvesterManager.affinity.addLabel'),
|
||||
topologyKeyPlaceholder: this.t('harvesterManager.affinity.topologyKey.placeholder')
|
||||
addLabel: this.t('harvester.virtualMachine.affinity.addLabel'),
|
||||
topologyKeyPlaceholder: this.t('harvester.virtualMachine.affinity.topologyKey.placeholder')
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import HarvesterResource from './harvester';
|
||||
import { get } from '@shell/utils/object';
|
||||
import { findBy } from '@shell/utils/array';
|
||||
import { colorForState, stateDisplay, STATES } from '@shell/plugins/dashboard-store/resource-class';
|
||||
import { _CREATE } from '@shell/config/query-params';
|
||||
import { ucFirst, escapeHtml } from '@shell/utils/string';
|
||||
@@ -66,15 +64,12 @@ export default class ScheduleVmBackup extends HarvesterResource {
|
||||
}
|
||||
}
|
||||
|
||||
get stateObj() {
|
||||
return this?.metadata?.state || {};
|
||||
}
|
||||
|
||||
get state() {
|
||||
const conditions = get(this, 'status.conditions');
|
||||
const isSuspended = findBy(conditions, 'type', 'BackupSuspend')?.status === 'True';
|
||||
|
||||
if (isSuspended) {
|
||||
return STATES.suspended.label;
|
||||
}
|
||||
|
||||
return this.metadata.state.name;
|
||||
return this.status?.suspended === true ? STATES.suspended.label : STATES.active.label;
|
||||
}
|
||||
|
||||
get stateDescription() {
|
||||
|
||||
@@ -1120,10 +1120,6 @@ export default class VirtVm extends HarvesterResource {
|
||||
return qemu?.status === 'True';
|
||||
}
|
||||
|
||||
get warnDeletionMessage() {
|
||||
return this.t('harvester.virtualMachine.promptRemove.tips');
|
||||
}
|
||||
|
||||
get instanceLabels() {
|
||||
const all = this.spec?.template?.metadata?.labels || {};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "harvester",
|
||||
"description": "Rancher UI Extension for Harvester",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"private": false,
|
||||
"rancher": {
|
||||
"annotations": {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { isEmpty } from '@shell/utils/object';
|
||||
import Parse from 'url-parse';
|
||||
import { resourceNames } from '@shell/utils/string';
|
||||
import { HCI } from '../types';
|
||||
import { alternateLabel as alternateLabelButton } from '@shell/utils/platform';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterPromptRemove',
|
||||
@@ -39,8 +40,9 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
checkedList: [],
|
||||
checkAll: true
|
||||
checkedList: [],
|
||||
checkAll: true,
|
||||
alternateLabel: alternateLabelButton
|
||||
};
|
||||
},
|
||||
|
||||
@@ -138,44 +140,53 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mt-10">
|
||||
{{ t('promptRemove.attemptingToRemove', {type}) }}
|
||||
<span v-clean-html="resourceNames(names, plusMore, t)"></span>
|
||||
|
||||
<div>
|
||||
<div class="mt-10">
|
||||
{{ t('harvester.virtualMachine.promptRemove.title') }}
|
||||
</div>
|
||||
<div v-if="value.length === 1">
|
||||
<span
|
||||
v-for="(name, i) in removeNameArr[value[0].id]"
|
||||
:key="i"
|
||||
>
|
||||
<label class="checkbox-container mr-15"><input
|
||||
v-model="checkedList"
|
||||
type="checkbox"
|
||||
:label="name"
|
||||
:value="name"
|
||||
/>
|
||||
{{ t('promptRemove.attemptingToRemove', {type}) }}
|
||||
<span v-clean-html="resourceNames(names, plusMore, t)"></span>
|
||||
|
||||
<div class="mt-10">
|
||||
{{ t('harvester.virtualMachine.promptRemove.title') }}
|
||||
</div>
|
||||
<div v-if="value.length === 1">
|
||||
<span
|
||||
v-for="(name, i) in removeNameArr[value[0].id]"
|
||||
:key="i"
|
||||
>
|
||||
<label class="checkbox-container mr-15">
|
||||
<input
|
||||
v-model="checkedList"
|
||||
type="checkbox"
|
||||
:label="name"
|
||||
:value="name"
|
||||
/>
|
||||
<span
|
||||
class="checkbox-custom mr-5"
|
||||
role="checkbox"
|
||||
/>
|
||||
{{ name }}
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<label class="checkbox-container mr-15">
|
||||
<input
|
||||
v-model="checkedList"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="checkbox-custom mr-5"
|
||||
role="checkbox"
|
||||
/>
|
||||
{{ name }}
|
||||
{{ t('harvester.virtualMachine.promptRemove.deleteAll') }}
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<label class="checkbox-container mr-15"><input
|
||||
v-model="checkAll"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="checkbox-custom mr-5"
|
||||
role="checkbox"
|
||||
/>
|
||||
{{ t('harvester.virtualMachine.promptRemove.deleteAll') }}
|
||||
</label>
|
||||
<div class="text-warning mb-10 mt-10">
|
||||
{{ t('harvester.virtualMachine.promptRemove.tips') }}
|
||||
</div>
|
||||
<div class="text-info mt-20">
|
||||
{{ t('promptRemove.protip', { alternateLabel }) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user