dashboard/components/RioDetail.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 }}:&nbsp;</span>
<span v-else-if="realMode === 'stage'">Stage from {{ typeDisplay }}:&nbsp;</span>
<span v-else-if="realMode === 'clone'">Clone from {{ typeDisplay }}:&nbsp;</span>
<nuxt-link v-else v-trim-whitespace :to="parentLink">
{{ typeDisplay }}:&nbsp;
</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>