276 lines
7.4 KiB
Vue
276 lines
7.4 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, onUnmounted, ref } from 'vue'
|
|
|
|
import { QSelect } from 'quasar'
|
|
|
|
const storesCategory: string[] = []
|
|
const filterDataCategory = ref<string[]>(storesCategory)
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
open: boolean
|
|
error: {
|
|
fileExist?: boolean
|
|
fileName2Long?: boolean
|
|
}
|
|
mode: 'create' | 'edit'
|
|
fileNameLabel?: string
|
|
title?: string
|
|
description?: string
|
|
keyword?: string[]
|
|
category?: string[]
|
|
}>(),
|
|
{
|
|
open: false,
|
|
},
|
|
)
|
|
|
|
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',
|
|
])
|
|
|
|
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 ?? '',
|
|
keyword: props.keyword,
|
|
category: props.category,
|
|
})
|
|
}
|
|
|
|
const createKeyword = ((val, done) => {
|
|
if (val.length > 2) {
|
|
if (!inputKeyword.value.includes(val)) {
|
|
done(val, 'add-unique')
|
|
}
|
|
}
|
|
}) satisfies QSelect['onNewValue']
|
|
|
|
const createCategory = ((val, done) => {
|
|
if (val.length > 2) {
|
|
if (!inputCategory.value.includes(val)) {
|
|
done(val, 'add-unique')
|
|
}
|
|
}
|
|
}) satisfies QSelect['onNewValue']
|
|
|
|
const filterCategory = ((val, update) => {
|
|
update(() => {
|
|
if (val === '') {
|
|
filterDataCategory.value = storesCategory
|
|
} else {
|
|
const needle = val.toLowerCase()
|
|
filterDataCategory.value = storesCategory.filter(
|
|
(v) => v.toLowerCase().indexOf(needle) > -1,
|
|
)
|
|
}
|
|
})
|
|
}) satisfies QSelect['onFilter']
|
|
|
|
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"
|
|
v-click-outside="() => $emit('update:open', false)"
|
|
: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())"
|
|
id="fileFormIconClose"
|
|
/>
|
|
</q-toolbar>
|
|
|
|
<section class="q-mb-md">
|
|
<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)"
|
|
:label="
|
|
mode === 'edit' && fileNameLabel && !file?.name
|
|
? fileNameLabel
|
|
: file?.name
|
|
? undefined
|
|
: 'เลือกไฟล์'
|
|
"
|
|
:error="!!error.fileExist || !!error.fileName2Long"
|
|
:error-message="
|
|
error.fileExist
|
|
? 'พบไฟล์ในระบบ ข้อมูลในระบบจะถูกเขียนทับ'
|
|
: error.fileName2Long
|
|
? 'ไม่สามารถเพิ่มไฟล์ที่ชื่อยาวเกิน 85 ตัวอักษรได้'
|
|
: ''
|
|
"
|
|
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"
|
|
:rules="[(v) => v.length > 3 || 'ชื่อต้องยาวกว่า 3 ตัวอักษร']"
|
|
@update:model-value="(v) => $emit('update:title', v)"
|
|
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)"
|
|
id="inputDescription"
|
|
/>
|
|
</section>
|
|
|
|
<section class="q-mb-md">
|
|
<span class="text-weight-bold">กลุ่ม/หมวดหมู่</span>
|
|
<div class="q-mt-md">
|
|
<q-select
|
|
outlined
|
|
dense
|
|
:model-value="category"
|
|
label="กดปุ่มEnterเพื่อเพิ่ม"
|
|
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)"
|
|
data-testid="filterDataCategory"
|
|
>
|
|
<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>
|
|
<div class="q-mt-md">
|
|
<q-select
|
|
outlined
|
|
dense
|
|
label="กดปุ่มEnterเพื่อเพิ่ม"
|
|
use-input
|
|
use-chips
|
|
multiple
|
|
hide-dropdown-icon
|
|
input-debounce="0"
|
|
style="width: 250px"
|
|
:model-value="props.keyword"
|
|
@update:model-value="(v) => $emit('update:keyword', v)"
|
|
@new-value="createKeyword"
|
|
data-testid="filterDataKeyWord"
|
|
>
|
|
</q-select>
|
|
</div>
|
|
</section>
|
|
|
|
<section :style="{ display: 'flex', gap: '.5rem' }">
|
|
<q-btn
|
|
label="บันทึก"
|
|
type="submit"
|
|
color="primary"
|
|
:disable="error.fileName2Long"
|
|
id="submitFile"
|
|
/>
|
|
<q-btn
|
|
label="ยกเลิก"
|
|
type="reset"
|
|
color="primary"
|
|
flat
|
|
@click="() => ($emit('update:open', false), reset())"
|
|
id="fileFormBtnClose"
|
|
/>
|
|
</section>
|
|
</q-form>
|
|
</q-drawer>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.no-resize :deep(textarea) {
|
|
resize: none;
|
|
}
|
|
</style>
|