hrms-edm/Services/client/src/components/FileForm.vue

279 lines
7.5 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
2023-12-01 15:53:38 +07:00
import { QSelect } from 'quasar'
2023-11-30 18:04:52 +07:00
2023-12-01 15:53:38 +07:00
const storesCategory: string[] = []
const filterDataCategory = ref<string[]>(storesCategory)
2023-11-30 17:13:00 +07:00
const props = withDefaults(
defineProps<{
open: boolean
error: {
fileExist?: boolean
fileName2Long?: boolean
}
mode: 'create' | 'edit'
2023-12-12 17:32:16 +07:00
fileNameLabel?: string
title?: string
description?: string
2023-12-01 09:26:34 +07:00
keyword?: string[]
category?: string[]
}>(),
{
open: false,
2023-12-01 15:53:38 +07:00
},
)
2023-12-01 11:49:55 +07:00
const inputKeyword = ref<string[]>(props.keyword || [])
const inputCategory = ref<string[]>(props.category || [])
const emit = defineEmits([
'update:open',
'update:title',
'update:description',
'update:keyword',
'update:category',
'filechange',
'reset',
'submit',
])
2023-12-07 09:42:49 +07:00
defineExpose({
reset,
})
function keydown(e: KeyboardEvent) {
if (e.key === 'Escape' && props.open === true) {
emit('update:open', false)
reset()
}
}
function reset() {
file.value = undefined
emit('update:title', '')
emit('update:description', '')
emit('update:keyword', '')
emit('update:category', '')
emit('reset')
}
function submit() {
emit('submit', {
mode: props.mode,
file: file.value,
title: props.title ?? '',
description: props.description ?? '',
2023-12-01 17:10:53 +07:00
keyword: props.keyword,
category: props.category,
})
}
2023-12-01 15:53:38 +07:00
const createKeyword = ((val, done) => {
2023-11-30 17:13:00 +07:00
if (val.length > 2) {
if (!inputKeyword.value.includes(val)) {
done(val, 'add-unique')
}
}
2023-12-01 15:53:38 +07:00
}) satisfies QSelect['onNewValue']
2023-11-30 17:13:00 +07:00
2023-12-01 15:53:38 +07:00
const createCategory = ((val, done) => {
2023-11-30 18:04:52 +07:00
if (val.length > 2) {
if (!inputCategory.value.includes(val)) {
done(val, 'add-unique')
}
}
2023-12-01 15:53:38 +07:00
}) satisfies QSelect['onNewValue']
2023-11-30 18:04:52 +07:00
2023-12-01 15:53:38 +07:00
const filterCategory = ((val, update) => {
2023-11-30 18:04:52 +07:00
update(() => {
if (val === '') {
filterDataCategory.value = storesCategory
} else {
const needle = val.toLowerCase()
filterDataCategory.value = storesCategory.filter(
2023-12-01 15:53:38 +07:00
(v) => v.toLowerCase().indexOf(needle) > -1,
2023-11-30 17:13:00 +07:00
)
}
})
2023-12-01 15:53:38 +07:00
}) satisfies QSelect['onFilter']
2023-11-30 17:13:00 +07:00
onMounted(() => window.addEventListener('keydown', keydown))
onUnmounted(() => window.addEventListener('keydown', keydown))
const file = ref<File | undefined>()
</script>
<template>
<q-drawer
overlay
bordered
class="q-pa-md"
side="right"
tabindex="0"
2023-12-13 10:52:51 +07:00
v-click-outside="
() => ($emit('update:open', false), reset(), (file = undefined))
"
:width="300"
:breakpoint="500"
:model-value="open"
@update:model-value="(v) => $emit('update:open', v)"
>
<q-form @submit.prevent="submit" v-if="open">
<q-toolbar class="q-mb-md q-pa-none">
<q-toolbar-title>
<span class="text-weight-bold" v-if="mode === 'create'">
สรางเอกสาร
</span>
<span class="text-weight-bold" v-if="mode === 'edit'">
แกไขเอกสาร
</span>
</q-toolbar-title>
<q-btn
v-close-popup
flat
round
dense
icon="close"
color="red"
@click="() => ($emit('update:open', !open), reset())"
2023-12-01 17:49:25 +07:00
id="fileFormIconClose"
/>
</q-toolbar>
<section class="q-mb-md">
2023-12-13 11:21:13 +07:00
<span class="text-weight-bold q-mb-sm block">ปโหลดไฟล</span>
<q-file
dense
outlined
v-model="file"
@update:model-value="(v) => $emit('filechange', v.name)"
2023-12-12 17:32:16 +07:00
:label="
mode === 'edit' && fileNameLabel && !file?.name
? fileNameLabel
: file?.name
? undefined
: 'เลือกไฟล์'
"
:error="!!error.fileExist || !!error.fileName2Long"
:error-message="
error.fileExist
2023-12-13 11:36:13 +07:00
? 'พบไฟล์ชื่อซ้ำในระบบ ไฟล์ชื่อนี้ภายในระบบจะถูกเขียนทับ'
: error.fileName2Long
2023-12-01 15:53:38 +07:00
? 'ไม่สามารถเพิ่มไฟล์ที่ชื่อยาวเกิน 85 ตัวอักษรได้'
: ''
"
2023-12-01 17:49:25 +07:00
id="inputFile"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
</q-file>
</section>
<section class="q-mb-md">
<span class="text-weight-bold">อเรอง</span>
<q-input
outlined
dense
class="q-my-sm"
placeholder="กรอกชื่อเรื่อง"
:model-value="title"
2023-12-01 11:49:55 +07:00
:rules="[(v) => v.length > 3 || 'ชื่อต้องยาวกว่า 3 ตัวอักษร']"
@update:model-value="(v) => $emit('update:title', v)"
2023-12-01 17:49:25 +07:00
id="inputTitle"
/>
</section>
<section class="q-mb-md">
<span class="text-weight-bold">รายละเอยดของเอกสาร</span>
<q-input
outlined
dense
class="q-mt-sm no-resize"
type="textarea"
placeholder="กรอกรายละเอียด"
:model-value="description"
@update:model-value="(v) => $emit('update:description', v)"
2023-12-01 17:49:25 +07:00
id="inputDescription"
/>
</section>
<section class="q-mb-md">
2023-12-01 11:49:55 +07:00
<span class="text-weight-bold">กล/หมวดหม</span>
2023-11-30 18:04:52 +07:00
<div class="q-mt-md">
<q-select
outlined
2023-12-06 09:08:38 +07:00
dense
2023-11-30 18:04:52 +07:00
:model-value="category"
label="กดปุ่มEnterเพื่อเพิ่ม"
2023-11-30 18:04:52 +07:00
use-input
use-chips
multiple
input-debounce="0"
@new-value="createCategory"
:options="filterDataCategory"
@filter="filterCategory"
style="width: 250px"
@update:model-value="(v) => $emit('update:category', v)"
2023-12-06 09:44:29 +07:00
data-testid="filterDataCategory"
2023-11-30 18:04:52 +07:00
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey"> No results </q-item-section>
</q-item>
</template>
</q-select>
</div>
</section>
<section class="q-mb-md">
<span class="text-weight-bold">คำสำค</span>
2023-11-30 17:13:00 +07:00
<div class="q-mt-md">
<q-select
outlined
2023-12-06 09:08:38 +07:00
dense
label="กดปุ่มEnterเพื่อเพิ่ม"
2023-11-30 17:13:00 +07:00
use-input
use-chips
multiple
2023-12-01 11:49:55 +07:00
hide-dropdown-icon
2023-11-30 17:13:00 +07:00
input-debounce="0"
style="width: 250px"
2023-12-01 11:49:55 +07:00
:model-value="props.keyword"
2023-11-30 18:04:52 +07:00
@update:model-value="(v) => $emit('update:keyword', v)"
2023-12-01 15:53:38 +07:00
@new-value="createKeyword"
2023-12-06 09:44:29 +07:00
data-testid="filterDataKeyWord"
2023-11-30 17:13:00 +07:00
>
</q-select>
</div>
</section>
<section :style="{ display: 'flex', gap: '.5rem' }">
<q-btn
label="บันทึก"
type="submit"
color="primary"
:disable="error.fileName2Long"
2023-12-01 17:49:25 +07:00
id="submitFile"
/>
<q-btn
label="ยกเลิก"
type="reset"
color="primary"
flat
@click="() => ($emit('update:open', false), reset())"
2023-12-01 17:49:25 +07:00
id="fileFormBtnClose"
/>
</section>
</q-form>
</q-drawer>
</template>
<style scoped>
.no-resize :deep(textarea) {
resize: none;
}
</style>