add permission role
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
type DialogLocation =
|
||||
| 'top'
|
||||
| 'bottom'
|
||||
| 'left'
|
||||
| 'right'
|
||||
| 'start'
|
||||
| 'end'
|
||||
| 'center';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: boolean;
|
||||
maxWidth?: string | number;
|
||||
persistent?: boolean;
|
||||
transition?: string;
|
||||
location?: DialogLocation;
|
||||
scrollable?: boolean;
|
||||
contentClass?: string;
|
||||
}>(),
|
||||
{
|
||||
maxWidth: 600,
|
||||
persistent: true,
|
||||
transition: 'app-right-slide-transition',
|
||||
location: 'right',
|
||||
scrollable: true,
|
||||
contentClass: '',
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: boolean): void;
|
||||
}>();
|
||||
|
||||
const model = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value: boolean) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
const dialogContentClass = computed(() => {
|
||||
const base = 'app-right-dialog';
|
||||
return props.contentClass ? `${base} ${props.contentClass}` : base;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-dialog
|
||||
v-model="model"
|
||||
:max-width="props.maxWidth"
|
||||
:persistent="props.persistent"
|
||||
:transition="props.transition"
|
||||
:location="props.location"
|
||||
:scrollable="props.scrollable"
|
||||
:content-class="dialogContentClass"
|
||||
>
|
||||
<slot />
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/*
|
||||
Ensures the dialog behaves like a right-side panel:
|
||||
- pinned to the right
|
||||
- full viewport height
|
||||
- no default margins
|
||||
*/
|
||||
.app-right-dialog {
|
||||
height: 100vh !important;
|
||||
max-height: 100vh !important;
|
||||
margin: 0 !important;
|
||||
top: 0 !important;
|
||||
right: 0 !important;
|
||||
left: auto !important;
|
||||
align-self: stretch;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.app-right-dialog .v-dialog {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.app-right-dialog .v-card {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* Vuetify surfaces sometimes wrap card/sheet */
|
||||
.app-right-dialog .v-sheet {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/*
|
||||
Custom transition for v-dialog content:
|
||||
Slide in from right, slide out to right.
|
||||
No fade-in / fade-out.
|
||||
*/
|
||||
.app-right-slide-transition-enter-active,
|
||||
.app-right-slide-transition-leave-active {
|
||||
transition: transform 240ms ease;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.app-right-slide-transition-enter-from,
|
||||
.app-right-slide-transition-leave-to {
|
||||
transform: translateX(100%);
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.app-right-slide-transition-enter-to,
|
||||
.app-right-slide-transition-leave-from {
|
||||
transform: translateX(0%);
|
||||
opacity: 1 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -76,6 +76,7 @@ const onConfirm = () => {
|
||||
:color="props.cancelColor"
|
||||
variant="tonal"
|
||||
flat
|
||||
prepend-icon="mdi-cancel"
|
||||
:disabled="props.loading"
|
||||
@click="onCancel"
|
||||
>
|
||||
@@ -86,6 +87,7 @@ const onConfirm = () => {
|
||||
:color="props.confirmColor"
|
||||
variant="tonal"
|
||||
flat
|
||||
prepend-icon="mdi-check"
|
||||
:loading="props.loading"
|
||||
:disabled="props.loading"
|
||||
@click="onConfirm"
|
||||
|
||||
Reference in New Issue
Block a user