220 lines
5.6 KiB
Vue
220 lines
5.6 KiB
Vue
<template>
|
|
<div>
|
|
<div class="row">
|
|
<div class="col-10">
|
|
<FormSelect
|
|
name="cate"
|
|
title="카테고리 선택"
|
|
:data="dataList"
|
|
:is-common="true"
|
|
@update:data="selectCategory = $event"
|
|
@change="onChange"
|
|
:value="formValue"
|
|
:disabled="isDisabled"
|
|
:isEssential="true"
|
|
/>
|
|
</div>
|
|
<div class="col-2 btn-margin" v-if="!isDisabled">
|
|
<PlusBtn @click="toggleInput"/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" v-if="showInput">
|
|
<div class="col-10">
|
|
<FormInput
|
|
ref="categoryInputRef"
|
|
title="카테고리 입력"
|
|
name="카테고리"
|
|
@update:modelValue="addCategory = $event"
|
|
:is-cate-alert="addCategoryAlert"
|
|
@focusout="handleCategoryFocusout(addCategory)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="dict-w">
|
|
<FormInput
|
|
title="용어"
|
|
type="text"
|
|
name="word"
|
|
:is-essential="true"
|
|
:is-alert="wordTitleAlert"
|
|
:modelValue="titleValue"
|
|
@update:modelValue="wordTitle = $event"
|
|
:disabled="isDisabled"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<QEditor @update:data="content = $event" @update:imageUrls="imageUrls = $event" :is-alert="wordContentAlert" :initialData="contentValue"/>
|
|
<div class="text-end mt-5">
|
|
<button class="btn btn-primary" @click="saveWord">
|
|
<i class="bx bx-check"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { defineProps, computed, ref, defineEmits } from 'vue';
|
|
|
|
import QEditor from '@/components/editor/QEditor.vue';
|
|
import FormInput from '@/components/input/FormInput.vue';
|
|
import FormSelect from '@/components/input/FormSelect.vue';
|
|
import PlusBtn from '../button/PlusBtn.vue';
|
|
|
|
const emit = defineEmits(['close','addCategory','addWord']);
|
|
|
|
//용어제목
|
|
const wordTitle = ref('');
|
|
const addCategory = ref('');
|
|
const content = ref('');
|
|
const imageUrls = ref([]);
|
|
|
|
//용어 Vaildation용
|
|
const wordTitleAlert = ref(false);
|
|
const wordContentAlert = ref(false);
|
|
const addCategoryAlert = ref(false);
|
|
|
|
//선택 카테고리
|
|
const selectCategory = ref('');
|
|
|
|
// 제목 상태
|
|
const computedTitle = computed(() =>
|
|
wordTitle.value === '' ? props.titleValue : wordTitle.value
|
|
);
|
|
|
|
// 카테고리 상태
|
|
const selectedCategory = computed(() =>
|
|
selectCategory.value === '' ? props.formValue : selectCategory.value
|
|
|
|
);
|
|
|
|
// 카테고리 입력 중복 ref
|
|
const categoryInputRef = ref(null);
|
|
|
|
const props = defineProps({
|
|
dataList: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
NumValue : {
|
|
type: Number
|
|
},
|
|
formValue : {
|
|
type:[String, Number]
|
|
},
|
|
titleValue : {
|
|
type:String,
|
|
},contentValue : {
|
|
type:String,
|
|
},
|
|
isDisabled: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
});
|
|
|
|
// 카테고리 입력 창
|
|
const showInput = ref(false);
|
|
|
|
// 카테고리 입력 토글
|
|
const toggleInput = () => {
|
|
showInput.value = !showInput.value;
|
|
};
|
|
|
|
const onChange = (newValue) => {
|
|
selectCategory.value = newValue.target.value;
|
|
};
|
|
|
|
//용어 등록
|
|
const saveWord = () => {
|
|
//validation
|
|
let computedTitleTrim;
|
|
|
|
if(computedTitle.value != undefined){
|
|
computedTitleTrim = computedTitle.value.trim()
|
|
}
|
|
|
|
// 용어 체크
|
|
if(computedTitleTrim == undefined || computedTitleTrim == ''){
|
|
wordTitleAlert.value = true;
|
|
return;
|
|
} else {
|
|
wordTitleAlert.value = false;
|
|
}
|
|
|
|
// 내용 확인
|
|
let inserts = [];
|
|
if (inserts.length === 0 && content.value?.ops?.length > 0) {
|
|
inserts = content.value.ops.map(op =>
|
|
typeof op.insert === 'string' ? op.insert.trim() : op.insert
|
|
);
|
|
}
|
|
|
|
// 내용 체크
|
|
if(content.value == '' || inserts.join('') === ''){
|
|
wordContentAlert.value = true;
|
|
return;
|
|
}
|
|
const wordData = {
|
|
id: props.NumValue || null,
|
|
title: computedTitle.value,
|
|
category: selectedCategory.value,
|
|
content: content.value,
|
|
};
|
|
emit('addWord', wordData, addCategory.value === ''
|
|
? (isNaN(selectedCategory.value) ? selectedCategory.value : Number(selectedCategory.value))
|
|
: addCategory.value);
|
|
}
|
|
|
|
|
|
// 카테고리 focusout 이벤트 핸들러 추가
|
|
const handleCategoryFocusout = (value) => {
|
|
const valueTrim = value.trim();
|
|
|
|
const existingCategory = props.dataList.find(item => item.label === valueTrim);
|
|
|
|
// 카테고리 입력시 공백
|
|
if(valueTrim == ''){
|
|
addCategoryAlert.value = true;
|
|
|
|
// 공백시 강제 focus
|
|
setTimeout(() => {
|
|
const inputElement = categoryInputRef.value?.$el?.querySelector('input');
|
|
if (inputElement) {
|
|
inputElement.focus();
|
|
}
|
|
}, 0);
|
|
|
|
|
|
}else if (existingCategory) {
|
|
addCategoryAlert.value = true;
|
|
|
|
// 중복시 강제 focus
|
|
setTimeout(() => {
|
|
const inputElement = categoryInputRef.value?.$el?.querySelector('input');
|
|
if (inputElement) {
|
|
inputElement.focus();
|
|
}
|
|
}, 0);
|
|
|
|
} else {
|
|
addCategoryAlert.value = false;
|
|
}
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.dict-w {
|
|
width: 83%;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.btn-margin {
|
|
margin-top: 2.5rem
|
|
}
|
|
}
|
|
</style>
|