mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-04 13:16:05 +08:00
Add pkg/harvester components + shell portings - 1
Signed-off-by: Francesco Torchia <francesco.torchia@suse.com>
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
<script>
|
||||
import CruResource from '@shell/components/CruResource';
|
||||
import { RadioGroup } from '@components/Form/Radio';
|
||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
||||
import { TextAreaAutoGrow } from '@components/Form/TextArea';
|
||||
|
||||
import CreateEditView from '@shell/mixins/create-edit-view';
|
||||
|
||||
import { HCI_ALLOWED_SETTINGS, HCI_SINGLE_CLUSTER_ALLOWED_SETTING, HCI_SETTING } from '../config/settings';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CruResource,
|
||||
LabeledInput,
|
||||
LabeledSelect,
|
||||
RadioGroup,
|
||||
TextAreaAutoGrow
|
||||
},
|
||||
|
||||
mixins: [CreateEditView],
|
||||
|
||||
data() {
|
||||
const t = this.$store.getters['i18n/t'];
|
||||
const setting =
|
||||
HCI_ALLOWED_SETTINGS[this.value.id] ||
|
||||
HCI_SINGLE_CLUSTER_ALLOWED_SETTING[this.value.id];
|
||||
|
||||
let enumOptions = [];
|
||||
|
||||
if (setting.kind === 'enum') {
|
||||
enumOptions = setting.options.map(id => ({
|
||||
label: `advancedSettings.enum.harv-${ this.value.id }.${ id }`,
|
||||
value: id
|
||||
}));
|
||||
}
|
||||
|
||||
const canReset =
|
||||
setting.canReset || !!this.value.default || this.value.canReset;
|
||||
|
||||
if (this.value.value === undefined) {
|
||||
this.$set(this.value, 'value', null);
|
||||
}
|
||||
|
||||
this.value.value = this.value.value || this.value.default || '';
|
||||
const oldValue = this.value.value;
|
||||
|
||||
const isHarvester = this.value?.type?.includes('harvesterhci');
|
||||
|
||||
// Get all the custom volume types from the file names of this folder
|
||||
const customSettingComponents = require
|
||||
.context('../components/settings', false, /^.*\.vue$/)
|
||||
.keys()
|
||||
.map(path => path.replace(/(\.\/)|(.vue)/g, ''));
|
||||
|
||||
return {
|
||||
setting,
|
||||
description: isHarvester ? t(`advancedSettings.descriptions.harv-${ this.value.id }`) : t(`advancedSettings.descriptions.${ this.value.id }`),
|
||||
editHelp: t(`advancedSettings.editHelp.${ this.value.id }`),
|
||||
enumOptions,
|
||||
canReset,
|
||||
errors: [],
|
||||
hasCustomComponent: false,
|
||||
customComponent: null,
|
||||
customSettingComponents,
|
||||
oldValue
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
doneLocationOverride() {
|
||||
return this.value.doneOverride;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
let customComponent = false;
|
||||
const hasCustomComponent = this.customSettingComponents.includes(this.value.id);
|
||||
|
||||
if ( hasCustomComponent ) {
|
||||
try {
|
||||
customComponent = require(`../components/settings/${ this.value.id }.vue`).default;
|
||||
} catch {}
|
||||
} else {
|
||||
// Some resources like vlan and network go out to a non-standard location (edit/<resource>/<id>.vue). For example
|
||||
// 'edit/harvesterhci.io.managedchart/rancher-monitoring.vue'
|
||||
const resource = this.$route.params.resource;
|
||||
const name = this.value.metadata.name;
|
||||
|
||||
try {
|
||||
customComponent = require(`./${ resource }/${ name }.vue`).default;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
this.hasCustomComponent = !!customComponent;
|
||||
this.customComponent = customComponent;
|
||||
|
||||
this.registerAfterHook(() => {
|
||||
if (this.value.id === HCI_SETTING.RANCHER_MANAGER_SUPPORT) {
|
||||
this.$store.commit('isRancherInHarvester', this.value.value === 'true');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
done() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
|
||||
async saveSettings(done) {
|
||||
const t = this.$store.getters['i18n/t'];
|
||||
|
||||
// Validate the JSON if the setting is a json value
|
||||
if (this.setting.kind === 'json' && this.value.default) {
|
||||
try {
|
||||
JSON.parse(this.value.value);
|
||||
this.errors = [];
|
||||
} catch (e) {
|
||||
this.errors = [t('advancedSettings.edit.invalidJSON')];
|
||||
|
||||
return done(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.value.metadata.name === HCI_SETTING.CLUSTER_REGISTRATION_URL && this.oldValue && this.value.value !== this.oldValue) {
|
||||
await this.clusterRegistrationUrlTip();
|
||||
}
|
||||
|
||||
this.save(done);
|
||||
},
|
||||
|
||||
clusterRegistrationUrlTip() {
|
||||
return new Promise((resolve) => {
|
||||
this.$store.dispatch('harvester/promptModal', {
|
||||
component: 'MessageBox',
|
||||
callback: (action) => {
|
||||
if (action === 'ok') {
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
contentKey: 'harvester.setting.clusterRegistrationUrl.message'
|
||||
}, { root: true });
|
||||
});
|
||||
},
|
||||
|
||||
useDefault(ev) {
|
||||
// Lose the focus on the button after click
|
||||
if (ev && ev.srcElement) {
|
||||
ev.srcElement.blur();
|
||||
}
|
||||
|
||||
if (this.value.id === HCI_SETTING.VLAN) {
|
||||
this.value.enable = false;
|
||||
if (this.value.config) {
|
||||
this.value.config.defaultPhysicalNIC = '';
|
||||
}
|
||||
} else {
|
||||
this.value.value = this.value.default || '';
|
||||
}
|
||||
|
||||
if (typeof this.$refs.settingComp?.useDefault === 'function') {
|
||||
this.$refs.settingComp.useDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CruResource
|
||||
class="route"
|
||||
:errors="errors"
|
||||
:mode="mode"
|
||||
:resource="value"
|
||||
:subtypes="[]"
|
||||
:can-yaml="false"
|
||||
:cancel-event="true"
|
||||
@error="e => (errors = e)"
|
||||
@finish="saveSettings"
|
||||
@cancel="done"
|
||||
>
|
||||
<h4 v-clean-html="description"></h4>
|
||||
|
||||
<h5 v-if="editHelp" v-clean-html="editHelp" class="edit-help" />
|
||||
|
||||
<div class="edit-change mt-20">
|
||||
<h5 v-t="'advancedSettings.edit.changeSetting'" />
|
||||
<button
|
||||
:disabled="!canReset"
|
||||
type="button"
|
||||
class="btn role-primary"
|
||||
@click="useDefault"
|
||||
>
|
||||
{{ t('advancedSettings.edit.useDefault') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-20">
|
||||
<div v-if="setting.from === 'import'">
|
||||
<component
|
||||
:is="customComponent"
|
||||
v-if="hasCustomComponent"
|
||||
ref="settingComp"
|
||||
v-model="value"
|
||||
:register-before-hook="registerBeforeHook"
|
||||
:mode="mode"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="setting.kind === 'enum'">
|
||||
<LabeledSelect
|
||||
v-model="value.value"
|
||||
:label="t('advancedSettings.edit.value')"
|
||||
:localized-label="true"
|
||||
:mode="mode"
|
||||
:options="enumOptions"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="setting.kind === 'boolean'">
|
||||
<RadioGroup
|
||||
v-model="value.value"
|
||||
name="settings_value"
|
||||
:labels="[
|
||||
t('advancedSettings.edit.trueOption'),
|
||||
t('advancedSettings.edit.falseOption')
|
||||
]"
|
||||
:options="['true', 'false']"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="setting.kind === 'multiline' || setting.kind === 'json'">
|
||||
<TextAreaAutoGrow v-model="value.value" :min-height="254" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<LabeledInput
|
||||
v-model="value.value"
|
||||
:label="t('advancedSettings.edit.value')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CruResource>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.edit-change {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
> h5 {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .edit-help code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user