jws-frontend/src/components/DialogForm.vue

313 lines
8.5 KiB
Vue
Raw Normal View History

2024-08-01 08:44:40 +00:00
<script setup lang="ts">
2024-08-08 06:11:47 +00:00
import {
EditButton,
DeleteButton,
CancelButton,
SaveButton,
UndoButton,
2024-08-09 14:02:40 +07:00
} from 'components/button';
2024-08-08 06:11:47 +00:00
2024-08-01 08:44:40 +00:00
defineProps<{
title: string;
branchStatus?: string;
badgeLabel?: string;
customerLabel?: string;
badgeClass?: string;
maxWidth?: string;
width?: string;
height?: string;
2024-09-30 11:37:18 +07:00
bgColor?: string;
2024-08-01 08:44:40 +00:00
employee?: boolean;
edit?: boolean;
2024-09-30 11:37:18 +07:00
hideFooter?: boolean;
2024-09-19 11:33:43 +07:00
hideDelete?: boolean;
2024-12-24 13:19:18 +07:00
hideBtn?: boolean;
2024-10-17 11:48:56 +07:00
readonly?: boolean;
disabledSubmit?: boolean;
2024-08-01 08:44:40 +00:00
2024-08-16 15:31:49 +07:00
saveAmount?: number;
2024-08-26 16:24:08 +07:00
submitLabel?: string;
submitIcon?: string;
2024-08-01 08:44:40 +00:00
isEdit?: boolean;
tabsList?: { name: string; label: string }[];
hideCloseEvent?: boolean;
2024-08-01 08:44:40 +00:00
editData?: (...args: unknown[]) => void;
deleteData?: (...args: unknown[]) => void;
2024-08-05 15:09:36 +07:00
show?: (...args: unknown[]) => void;
2024-08-01 08:44:40 +00:00
submit?: (...args: unknown[]) => void;
close?: (...args: unknown[]) => void;
undo?: (...args: unknown[]) => void;
2024-08-06 08:56:06 +07:00
beforeClose?: (...args: unknown[]) => boolean;
2024-08-01 08:44:40 +00:00
}>();
const modal = defineModel('modal', { default: false });
const currentTab = defineModel<string>('currentTab');
</script>
<template>
2024-08-06 08:56:06 +07:00
<q-dialog
:model-value="modal"
@update:model-value="(v) => (modal = beforeClose ? beforeClose() : v)"
@before-show="show"
@hide="hideCloseEvent !== undefined && hideCloseEvent ? '' : close?.()"
2024-08-06 08:56:06 +07:00
>
2024-08-01 08:44:40 +00:00
<div
class="surface-1"
style="padding: 0; border-radius: var(--radius-2); height: 100%"
:style="`max-width:${$q.screen.xs ? '100%' : maxWidth ? maxWidth : '85%'}; width: ${$q.screen.xs ? '100%' : width ? width : '85%'}; height: ${height ? height : '85vh'} `"
>
<q-form
greedy
@submit.prevent
@validation-success="submit"
class="column full-height"
>
<!-- header -->
2024-09-27 15:21:19 +07:00
<div
class="form-header"
:class="{
'q-py-sm q-px-lg': $q.screen.gt.sm,
'q-pa-xs': !$q.screen.gt.sm,
}"
>
2024-08-01 08:44:40 +00:00
<div class="row items-center">
2024-12-24 17:41:38 +07:00
<template v-if="!hideBtn">
2024-12-24 13:19:18 +07:00
<div v-if="!readonly && isEdit && edit" class="row">
<q-btn
round
flat
id="closeDialog"
icon="mdi-arrow-left"
padding="xs"
class="q-mr-md"
:class="{ dark: $q.dark.isActive }"
style="color: var(--brand-1)"
@click="undo"
/>
<div style="width: 31.98px"></div>
</div>
<div v-if="!readonly && !isEdit && edit">
<q-btn
round
flat
id="editDialog"
icon="mdi-pencil-outline"
padding="xs"
class="q-mr-md"
:class="{ dark: $q.dark.isActive }"
style="color: var(--brand-1)"
@click="editData"
/>
<q-btn
v-if="edit && !hideDelete"
round
flat
id="deleteDialog"
icon="mdi-trash-can-outline"
padding="xs"
:class="{ dark: $q.dark.isActive }"
style="color: hsl(var(--negative-bg))"
@click="deleteData"
/>
</div>
2024-12-24 17:41:38 +07:00
</template>
2024-08-01 08:44:40 +00:00
<div style="width: 31.98px"></div>
<div class="col text-subtitle1 text-weight-bold text-center">
2024-10-10 17:21:46 +07:00
<slot name="iconTitle" />
2024-08-01 08:44:40 +00:00
{{ title }}
<text v-if="customerLabel">
:
<text
class="text-customer"
:class="{ 'dark-text': $q.dark.isActive }"
:style="`color: ${customerLabel === 'CORP' ? 'var(--purple-8)' : 'var(--green-9)'} `"
>
{{
$t(
customerLabel === 'CORP'
? 'customerLegalEntity'
: 'customerNaturalPerson',
)
}}
</text>
</text>
<text v-if="branchStatus">
{{ branchStatus }}
</text>
<text
v-if="badgeLabel"
class="badge-label q-px-sm text-caption"
:class="badgeClass"
>
{{ badgeLabel }}
</text>
</div>
<slot name="top-append" />
<div>
<CancelButton
icon-only
id="btn-form-close"
@click="
() => {
modal = beforeClose ? beforeClose() : !modal;
close?.();
}
"
type="reset"
resetValidation
/>
</div>
2024-08-01 08:44:40 +00:00
</div>
</div>
<!-- body -->
<div
class="col full-height column full-width"
:class="{
dark: $q.dark.isActive,
2024-10-04 09:45:05 +07:00
'surface-2': !employee,
2024-08-01 08:44:40 +00:00
'surface-tab': employee || tabsList,
}"
2024-09-30 11:37:18 +07:00
:style="`background: ${bgColor} !important`"
2024-08-01 08:44:40 +00:00
>
<div
v-if="tabsList && tabsList.length > 0"
2024-09-27 15:21:19 +07:00
class="row surface-0 q-px-md q-pt-md full-width"
2024-08-01 08:44:40 +00:00
style="border-bottom: 1px solid var(--brand-1)"
>
<q-tabs
inline-label
mobile-arrows
dense
2024-08-06 03:14:56 +00:00
class="full-width"
2024-08-01 08:44:40 +00:00
v-model="currentTab"
align="left"
>
<q-tab
v-for="tab in tabsList"
v-bind:key="tab.name"
2024-08-06 03:14:56 +00:00
:id="`tab-${tab.label}`"
class="text-capitalize"
2024-08-01 08:44:40 +00:00
:name="tab.name"
:label="$t(tab.label)"
/>
</q-tabs>
</div>
<div class="row col full-width scroll">
<!-- prepend -->
<div class="col" v-if="$slots.prepend">
<slot name="prepend"></slot>
</div>
<!-- center -->
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
<div class="col column full-height no-wrap">
2024-08-01 08:44:40 +00:00
<slot></slot>
</div>
<!-- append -->
<div class="col" v-if="$slots.append">
<slot name="append"></slot>
</div>
</div>
</div>
<!-- footer -->
<div
2024-08-09 02:10:06 +00:00
v-if="!hideFooter"
2024-09-27 15:21:19 +07:00
class="form-footer row items-center full-width justify-between surface-1"
:class="{ 'q-pa-md': $q.screen.gt.sm, 'q-pa-sm': !$q.screen.gt.sm }"
2024-08-01 08:44:40 +00:00
style="z-index: 3"
>
<div>
<slot name="footer"></slot>
</div>
2024-08-08 06:11:47 +00:00
<div class="row flex justify-end">
<CancelButton
id="btn-form-cancel"
outlined
2024-08-01 08:44:40 +00:00
@click="close"
v-close-popup
/>
2024-08-08 06:11:47 +00:00
<SaveButton
class="q-ml-md"
id="btn-form-submit"
2024-08-01 08:44:40 +00:00
type="submit"
2024-08-08 06:11:47 +00:00
solid
:disabled="disabledSubmit"
:icon="submitIcon"
2024-08-26 16:24:08 +07:00
:label="submitLabel"
2024-08-16 15:31:49 +07:00
:amount="saveAmount"
2024-08-01 08:44:40 +00:00
/>
</div>
</div>
</q-form>
</div>
</q-dialog>
</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-header {
border-bottom: 1px solid var(--border-color);
}
.form-body {
--_body-bg: var(--sand-0);
background-color: var(--_body-bg);
&.dark {
--_body-bg: var(--gray-10);
}
}
.form-footer {
border-top: 1px solid var(--border-color);
}
.badge-label {
display: inline-block;
border-radius: var(--radius-6);
background-color: var(--surface-2);
text-wrap: nowrap;
}
.text-customer {
--_var-filter: grayscale(30%);
filter: var(--_var-filter);
&.dark-text {
--_var-filter: grayscale(0%);
}
}
.active-tab {
color: var(--brand-1);
background-color: var(--surface-tab);
border-top: 1px solid var(--brand-1);
border-left: 1px solid var(--brand-1);
border-right: 1px solid var(--brand-1);
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
margin-bottom: -1.5px;
border-bottom: 3px solid var(--surface-tab);
}
.content-tab {
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
position: relative;
}
</style>