249 lines
6 KiB
Vue
249 lines
6 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import {
|
|
EditButton,
|
|
DeleteButton,
|
|
CancelButton,
|
|
SaveButton,
|
|
UndoButton,
|
|
} from 'components/button';
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
title: string;
|
|
category?: string;
|
|
isEdit?: boolean;
|
|
bgOn?: boolean;
|
|
statusBranch?: string;
|
|
badgeLabel?: string;
|
|
badgeClass?: string;
|
|
badgeStyle?: string;
|
|
bgColor?: string;
|
|
hideAction?: boolean;
|
|
editData?: (...args: unknown[]) => void;
|
|
deleteData?: (...args: unknown[]) => void;
|
|
submit?: (...args: unknown[]) => void;
|
|
close?: (...args: unknown[]) => void;
|
|
undo?: (...args: unknown[]) => void;
|
|
beforeClose?: (...args: unknown[]) => boolean;
|
|
show?: (...args: unknown[]) => void;
|
|
}>(),
|
|
{
|
|
hideAction: false,
|
|
},
|
|
);
|
|
|
|
const windowSize = ref(window.innerWidth);
|
|
|
|
const drawerOpen = defineModel<boolean>('drawerOpen', {
|
|
default: false,
|
|
});
|
|
|
|
const myForm = ref();
|
|
|
|
function reset() {
|
|
if (props.beforeClose) {
|
|
drawerOpen.value = props.beforeClose
|
|
? props.beforeClose()
|
|
: !drawerOpen.value;
|
|
}
|
|
if (myForm.value) {
|
|
myForm.value.resetValidation();
|
|
}
|
|
}
|
|
|
|
async function onValidationError(ref: any) {
|
|
const el = ref.$el as Element;
|
|
el.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'center',
|
|
inline: 'nearest',
|
|
});
|
|
}
|
|
</script>
|
|
<template>
|
|
<q-drawer
|
|
no-swipe-open
|
|
@show="show"
|
|
@before-hide="reset"
|
|
@hide="close"
|
|
:width="$q.screen.gt.xs ? windowSize * 0.85 : windowSize"
|
|
v-model="drawerOpen"
|
|
behavior="mobile"
|
|
side="right"
|
|
show-if-above
|
|
>
|
|
<q-form
|
|
ref="myForm"
|
|
class="full-height"
|
|
greedy
|
|
@submit.prevent
|
|
@validation-success="submit"
|
|
@validation-error="onValidationError"
|
|
>
|
|
<div
|
|
class="column justify-between full-height"
|
|
style="padding: 0; border-radius: var(--radius-2)"
|
|
>
|
|
<!-- header -->
|
|
<div
|
|
class="bordered-b row items-center"
|
|
:class="{
|
|
'q-px-lg q-py-md': $q.screen.gt.sm,
|
|
'q-py-xs': !$q.screen.gt.sm,
|
|
}"
|
|
>
|
|
<div v-if="!hideAction">
|
|
<div v-if="isEdit" class="row">
|
|
<UndoButton id="btn-info-undo" iconOnly @click="undo" />
|
|
<div style="width: 38.8px"></div>
|
|
</div>
|
|
<div v-else class="row">
|
|
<EditButton id="btn-info-edit" iconOnly @click="editData" />
|
|
<DeleteButton id="btn-info-delete" iconOnly @click="deleteData" />
|
|
</div>
|
|
</div>
|
|
<div v-else style="width: 38.8px"></div>
|
|
|
|
<div
|
|
class="col text-weight-bold text-center ellipsis"
|
|
style="width: 0px"
|
|
>
|
|
<text
|
|
v-if="badgeLabel"
|
|
class="badge-label badge text-caption q-px-sm q-mr-sm"
|
|
:class="badgeClass"
|
|
:style="badgeStyle"
|
|
>
|
|
{{ badgeLabel }}
|
|
</text>
|
|
<text v-if="category" class="app-text-muted q-mr-sm">
|
|
{{ category }}
|
|
</text>
|
|
<slot name="badgeList">
|
|
<span>
|
|
{{ title }}
|
|
</span>
|
|
|
|
<text
|
|
v-if="!!statusBranch"
|
|
class="branch-badge branch-card__badge q-ml-sm"
|
|
:class="{
|
|
'branch-card__inactive ': statusBranch === 'INACTIVE',
|
|
}"
|
|
>
|
|
{{
|
|
statusBranch === 'INACTIVE'
|
|
? $t('status.INACTIVE')
|
|
: $t('status.ACTIVE')
|
|
}}
|
|
</text>
|
|
</slot>
|
|
</div>
|
|
|
|
<div v-if="!hideAction" class="q-mr-md" style="width: 38.8px"></div>
|
|
<CancelButton
|
|
icon-only
|
|
id="btn-info-close"
|
|
@click="
|
|
() => {
|
|
drawerOpen = beforeClose ? beforeClose() : !drawerOpen;
|
|
close?.();
|
|
}
|
|
"
|
|
type="reset"
|
|
resetValidation
|
|
/>
|
|
</div>
|
|
|
|
<!-- body -->
|
|
<div
|
|
class="col form-body full-width"
|
|
:class="`${bgColor || 'surface-2'} ${$q.dark.isActive && 'dark'}`"
|
|
>
|
|
<slot></slot>
|
|
<slot name="info"></slot>
|
|
</div>
|
|
|
|
<!-- footer -->
|
|
<div
|
|
class="bordered-t row items-center justify-end"
|
|
:class="{
|
|
'q-pr-lg q-py-md': $q.screen.gt.sm,
|
|
'q-pr-xs q-py-xs': !$q.screen.gt.sm,
|
|
}"
|
|
>
|
|
<CancelButton
|
|
id="btn-info-cancel"
|
|
outlined
|
|
@click="
|
|
() => {
|
|
drawerOpen = beforeClose ? beforeClose() : !drawerOpen;
|
|
close?.();
|
|
}
|
|
"
|
|
/>
|
|
<SaveButton
|
|
class="q-ml-md"
|
|
id="btn-info-save"
|
|
v-if="isEdit && !hideAction"
|
|
type="submit"
|
|
solid
|
|
/>
|
|
</div>
|
|
</div>
|
|
</q-form>
|
|
</q-drawer>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.close-btn {
|
|
color: hsl(var(--negative-bg));
|
|
background-color: hsla(var(--negative-bg) / 0.1);
|
|
|
|
&.dark {
|
|
background-color: transparent;
|
|
border: 1px solid hsl(var(--negative-bg));
|
|
}
|
|
}
|
|
|
|
.form-body {
|
|
--_body-bg: var(--sand-0);
|
|
background-color: var(--_body-bg);
|
|
background-repeat: no-repeat;
|
|
background-size: cover;
|
|
&.dark {
|
|
--_body-bg: var(--gray-10);
|
|
}
|
|
}
|
|
|
|
.branch-badge {
|
|
--_branch-badge-fg: var(--green-8-hsl);
|
|
--_branch-badge-bg: var(--green-6-hsl);
|
|
|
|
&.branch-card__inactive {
|
|
--_branch-badge-fg: var(--red-4-hsl);
|
|
--_branch-badge-bg: var(--red-4-hsl);
|
|
}
|
|
|
|
&.branch-card__badge {
|
|
display: inline-block;
|
|
border-radius: 999rem;
|
|
padding-inline: var(--size-2);
|
|
color: hsl(var(--_branch-badge-fg));
|
|
background-color: hsla(var(--_branch-badge-bg) / 0.1);
|
|
}
|
|
}
|
|
|
|
.badge-label {
|
|
display: inline-block;
|
|
text-wrap: nowrap;
|
|
}
|
|
|
|
.badge {
|
|
display: inline-block;
|
|
border-radius: var(--radius-6);
|
|
background-color: var(--surface-tab);
|
|
text-wrap: nowrap;
|
|
}
|
|
</style>
|