mirror of https://github.com/rancher/dashboard.git
204 lines
4.8 KiB
Vue
204 lines
4.8 KiB
Vue
<script>
|
|
import { cleanForNew } from '@/plugins/norman/normalize';
|
|
import CreateEditView from '@/mixins/create-edit-view';
|
|
import ResourceYaml from '@/components/ResourceYaml';
|
|
import { FRIENDLY } from '@/config/friendly';
|
|
import {
|
|
MODE, _VIEW, _EDIT, _CLONE, _STAGE,
|
|
EDIT_YAML, _FLAGGED, _CREATE
|
|
} from '@/config/query-params';
|
|
|
|
// Components can't have asyncData, only pages.
|
|
// So you have to call this in the page and pass it in as a prop.
|
|
export async function asyncData(ctx) {
|
|
const { store, params, route } = ctx;
|
|
const { resource, namespace, id } = params;
|
|
const friendly = FRIENDLY[resource];
|
|
const type = friendly.type;
|
|
const asYaml = route.query[EDIT_YAML] === _FLAGGED;
|
|
const mode = route.query[MODE];
|
|
const schema = store.getters['cluster/schemaFor'](type);
|
|
|
|
let fqid = id;
|
|
|
|
if ( schema.attributes.namespaced ) {
|
|
fqid = `${ namespace }/${ fqid }`;
|
|
}
|
|
|
|
const obj = await store.dispatch('cluster/find', { type, id: fqid });
|
|
|
|
let yaml = null;
|
|
|
|
if ( asYaml ) {
|
|
yaml = (await obj.followLink('view', { headers: { accept: 'application/yaml' } })).data;
|
|
}
|
|
|
|
const forNew = mode === _CLONE || mode === _STAGE;
|
|
const model = await store.dispatch('cluster/clone', { resource: obj });
|
|
|
|
if ( friendly.applyDefaults ) {
|
|
friendly.applyDefaults(ctx, model, mode);
|
|
}
|
|
|
|
if ( forNew ) {
|
|
cleanForNew(model);
|
|
}
|
|
|
|
/*******
|
|
* Important: these need to be declared below as props too
|
|
*******/
|
|
const out = {
|
|
asYaml,
|
|
resource,
|
|
model,
|
|
yaml,
|
|
originalModel: obj
|
|
};
|
|
/*******
|
|
* Important: these need to be declared below as props too
|
|
*******/
|
|
|
|
return out;
|
|
}
|
|
|
|
export const watchQuery = [MODE, EDIT_YAML];
|
|
|
|
export default {
|
|
components: { ResourceYaml },
|
|
mixins: { CreateEditView },
|
|
|
|
props: {
|
|
asYaml: {
|
|
type: Boolean,
|
|
default: null,
|
|
},
|
|
resource: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
model: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
yaml: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
originalModel: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
},
|
|
|
|
computed: {
|
|
// In the beginning, there was 20 bits of address-space, and it was... adequate. Please enable your A20 handler now.
|
|
realMode() {
|
|
return this.$route.query.mode || _VIEW;
|
|
},
|
|
|
|
mode() {
|
|
if ( this.realMode === _STAGE || this.realMode === _CLONE ) {
|
|
return _CREATE;
|
|
}
|
|
|
|
return this.realMode;
|
|
},
|
|
|
|
isView() {
|
|
return this.mode === _VIEW;
|
|
},
|
|
|
|
isEdit() {
|
|
return this.mode === _EDIT;
|
|
},
|
|
|
|
type() {
|
|
return FRIENDLY[this.resource].type;
|
|
},
|
|
|
|
doneRoute() {
|
|
const name = this.$route.name.replace(/(-namespace)?-id$/, '');
|
|
|
|
return name;
|
|
},
|
|
|
|
doneParams() {
|
|
return this.$route.params;
|
|
},
|
|
|
|
parentLink() {
|
|
const name = this.doneRoute;
|
|
const params = this.donneParams;
|
|
const out = this.$router.resolve({ name, params }).href;
|
|
|
|
return out;
|
|
},
|
|
|
|
cruComponent() {
|
|
if ( this.isView && FRIENDLY[this.resource].hasDetail ) {
|
|
return () => import(`@/components/detail/${ this.type }`);
|
|
}
|
|
|
|
return () => import(`@/components/cru/${ this.type }`);
|
|
},
|
|
|
|
typeDisplay() {
|
|
return FRIENDLY[this.resource].singular;
|
|
},
|
|
},
|
|
|
|
methods: {
|
|
showActions() {
|
|
this.$store.commit('selection/show', {
|
|
resources: this.originalModel,
|
|
elem: this.$refs.actions,
|
|
});
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<template v-if="asYaml">
|
|
<ResourceYaml
|
|
:obj="model"
|
|
:value="yaml"
|
|
:done-route="doneRoute"
|
|
:parent-route="doneRoute"
|
|
:parent-params="doneParams"
|
|
/>
|
|
</template>
|
|
<template v-else>
|
|
<header>
|
|
<h1 v-trim-whitespace>
|
|
<span v-if="realMode === 'edit'">Edit {{ typeDisplay }}: </span>
|
|
<span v-else-if="realMode === 'stage'">Stage from {{ typeDisplay }}: </span>
|
|
<span v-else-if="realMode === 'clone'">Clone from {{ typeDisplay }}: </span>
|
|
<nuxt-link v-else v-trim-whitespace :to="parentLink">
|
|
{{ typeDisplay }}:
|
|
</nuxt-link>{{ originalModel.nameDisplay }}
|
|
</h1>
|
|
<div v-if="isView" class="actions">
|
|
<button ref="actions" type="button" class="btn btn-sm role-multi-action actions" @click="showActions">
|
|
<i class="icon icon-actions" />
|
|
</button>
|
|
</div>
|
|
</header>
|
|
<component
|
|
:is="cruComponent"
|
|
v-model="model"
|
|
:original-value="originalModel"
|
|
:done-route="doneRoute"
|
|
:done-params="doneParams"
|
|
:parent-route="doneRoute"
|
|
:parent-params="doneParams"
|
|
:namespace-suffix-on-create="true"
|
|
:type-label="typeDisplay"
|
|
:mode="mode"
|
|
:real-mode="realMode"
|
|
/>
|
|
</template>
|
|
</div>
|
|
</template>
|