dashboard/components/form/Footer.vue

108 lines
2.0 KiB
Vue

<script lang="ts">
import Vue from 'vue';
import { _VIEW } from '@/config/query-params';
import AsyncButton, { AsyncButtonCallback } from '@/components/AsyncButton.vue';
import Banner from '@/components/Banner.vue';
export default Vue.extend({
components: {
AsyncButton,
Banner,
},
props: {
/**
* Current mode of the page
* passed to asyncButton to determine lables of the button
*/
mode: {
type: String,
required: true,
},
errors: {
type: Array,
default: null,
},
disableSave: {
type: Boolean,
default: false,
}
},
computed: {
isView(): boolean {
return this.mode === _VIEW;
},
},
methods: {
save(buttonCb: AsyncButtonCallback) {
this.$emit('save', buttonCb);
},
done() {
this.$emit('done');
}
}
});
</script>
<template>
<div v-if="!isView">
<div class="spacer-small"></div>
<div v-for="(err,idx) in errors" :key="idx">
<Banner color="error" :label="err" />
</div>
<div class="buttons">
<div class="left">
<slot name="left" />
</div>
<div class="right">
<slot name="cancel">
<button type="button" class="btn role-secondary" @click="done">
<t k="generic.cancel" />
</button>
</slot>
<slot name="middle" />
<slot name="save">
<AsyncButton
v-if="!isView"
:mode="mode"
:disabled="disableSave"
@click="save"
/>
</slot>
<slot name="right" />
</div>
</div>
</div>
</template>
<style lang='scss'>
.buttons {
display: grid;
grid-template-areas: "left right";
grid-template-columns: "min-content auto";
.left {
grid-area: left;
text-align: left;
.btn, button {
margin: 0 $column-gutter 0 0;
}
}
.right {
grid-area: right;
text-align: right;
.btn, button {
margin: 0 0 0 $column-gutter;
}
}
}
</style>