mirror of https://github.com/rancher/dashboard.git
242 lines
5.2 KiB
Vue
242 lines
5.2 KiB
Vue
<script>
|
|
import { mapGetters } from 'vuex';
|
|
import { Card } from '@components/Card';
|
|
import { Banner } from '@components/Banner';
|
|
import Loading from '@shell/components/Loading';
|
|
import YamlEditor from '@shell/components/YamlEditor';
|
|
import FileSelector from '@shell/components/form/FileSelector';
|
|
import AsyncButton from '@shell/components/AsyncButton';
|
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
import SortableTable from '@shell/components/SortableTable';
|
|
import { sortBy } from '@shell/utils/sort';
|
|
import { exceptionToErrorsArray } from '@shell/utils/error';
|
|
import { NAMESPACE } from '@shell/config/types';
|
|
import {
|
|
NAME as NAME_COL, STATE, TYPE, NAMESPACE as NAMESPACE_COL, AGE
|
|
} from '@shell/config/table-headers';
|
|
|
|
export default {
|
|
components: {
|
|
AsyncButton,
|
|
Banner,
|
|
Card,
|
|
Loading,
|
|
YamlEditor,
|
|
FileSelector,
|
|
LabeledSelect,
|
|
SortableTable
|
|
},
|
|
|
|
props: {
|
|
defaultNamespace: {
|
|
type: String,
|
|
default: 'default'
|
|
},
|
|
},
|
|
|
|
async fetch() {
|
|
this.allNamespaces = await this.$store.dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } });
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
currentYaml: '',
|
|
allNamespaces: null,
|
|
errors: null,
|
|
rows: null,
|
|
done: false,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
...mapGetters(['currentCluster']),
|
|
|
|
namespaceOptions() {
|
|
const out = this.allNamespaces.map((obj) => {
|
|
return {
|
|
label: obj.name,
|
|
value: obj.name,
|
|
};
|
|
});
|
|
|
|
return sortBy(out, 'label');
|
|
},
|
|
|
|
headers() {
|
|
return [
|
|
STATE,
|
|
TYPE,
|
|
NAME_COL,
|
|
NAMESPACE_COL,
|
|
AGE
|
|
];
|
|
},
|
|
},
|
|
|
|
methods: {
|
|
close() {
|
|
this.$emit('close');
|
|
},
|
|
|
|
onFileSelected(value) {
|
|
const component = this.$refs.yamleditor;
|
|
|
|
if (component) {
|
|
this.errors = null;
|
|
component.updateValue(value);
|
|
}
|
|
},
|
|
|
|
async importYaml(btnCb) {
|
|
try {
|
|
this.errors = [];
|
|
|
|
const res = await this.currentCluster.doAction('apply', {
|
|
yaml: this.currentYaml,
|
|
defaultNamespace: this.defaultNamespace,
|
|
});
|
|
|
|
btnCb(true);
|
|
|
|
this.rows = res;
|
|
this.done = true;
|
|
} catch (err) {
|
|
this.errors = exceptionToErrorsArray(err);
|
|
this.done = false;
|
|
btnCb(false);
|
|
}
|
|
},
|
|
|
|
rowClick(e) {
|
|
if ( e.target.tagName === 'A' ) {
|
|
this.close();
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Loading v-if="$fetchState.pending" />
|
|
<Card
|
|
v-else
|
|
:show-highlight-border="false"
|
|
>
|
|
<template #title>
|
|
<div style="display: block; width: 100%;">
|
|
<template v-if="done">
|
|
<h4>{{ t('import.success', {count: rows.length}) }}</h4>
|
|
</template>
|
|
<template v-else>
|
|
<h4 v-t="'import.title'" />
|
|
<div class="row">
|
|
<div class="col span-6">
|
|
<FileSelector
|
|
class="btn role-secondary pull-left"
|
|
:label="t('generic.readFromFile')"
|
|
@selected="onFileSelected"
|
|
/>
|
|
</div>
|
|
<div class="col span-6">
|
|
<LabeledSelect
|
|
v-model="defaultNamespace"
|
|
class="pull-right"
|
|
:options="namespaceOptions"
|
|
label-key="import.defaultNamespace.label"
|
|
mode="edit"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<template v-if="done">
|
|
<div class="results">
|
|
<SortableTable
|
|
:rows="rows"
|
|
:headers="headers"
|
|
mode="view"
|
|
key-field="_key"
|
|
:search="false"
|
|
:paging="true"
|
|
:row-actions="false"
|
|
:table-actions="false"
|
|
@rowClick="rowClick"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<YamlEditor
|
|
v-else
|
|
ref="yamleditor"
|
|
v-model="currentYaml"
|
|
class="yaml-editor"
|
|
/>
|
|
<Banner
|
|
v-for="(err, i) in errors"
|
|
:key="i"
|
|
color="error"
|
|
:label="err"
|
|
/>
|
|
</template>
|
|
<template #actions>
|
|
<div
|
|
v-if="done"
|
|
class="text-center"
|
|
style="width: 100%"
|
|
>
|
|
<button
|
|
type="button"
|
|
class="btn role-primary"
|
|
@click="close"
|
|
>
|
|
{{ t('generic.close') }}
|
|
</button>
|
|
</div>
|
|
<div
|
|
v-else
|
|
class="text-center"
|
|
style="width: 100%"
|
|
>
|
|
<button
|
|
type="button"
|
|
class="btn role-secondary mr-10"
|
|
@click="close"
|
|
>
|
|
{{ t('generic.cancel') }}
|
|
</button>
|
|
<AsyncButton
|
|
v-if="!done"
|
|
mode="import"
|
|
:disabled="!currentYaml.length"
|
|
@click="importYaml"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</Card>
|
|
</template>
|
|
|
|
<style lang='scss' scoped>
|
|
$min: 50vh;
|
|
$max: 50vh;
|
|
|
|
.yaml-editor {
|
|
flex: 1;
|
|
min-height: $min;
|
|
max-height: $max;
|
|
|
|
::v-deep .code-mirror {
|
|
.CodeMirror {
|
|
position: initial;
|
|
}
|
|
|
|
.CodeMirror,
|
|
.CodeMirror-scroll,
|
|
.CodeMirror-gutters {
|
|
min-height: $min;
|
|
max-height: $max;
|
|
}
|
|
}
|
|
}
|
|
</style>
|