Merge branch 'main' into project-list
This commit is contained in:
commit
b0239bacce
@ -12,6 +12,7 @@
|
|||||||
v-model="inputValue"
|
v-model="inputValue"
|
||||||
:maxLength="maxlength"
|
:maxLength="maxlength"
|
||||||
:placeholder="title"
|
:placeholder="title"
|
||||||
|
:disabled="disabled"
|
||||||
/>
|
/>
|
||||||
<div class="invalid-feedback" :class="isAlert ? 'display-block' : ''">
|
<div class="invalid-feedback" :class="isAlert ? 'display-block' : ''">
|
||||||
{{ title }}을 확인해주세요.
|
{{ title }}을 확인해주세요.
|
||||||
@ -60,6 +61,10 @@ const props = defineProps({
|
|||||||
default: true,
|
default: true,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Emits 정의
|
// Emits 정의
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<span :class="isEssential ? 'link-danger' : 'none'">*</span>
|
<span :class="isEssential ? 'link-danger' : 'none'">*</span>
|
||||||
</label>
|
</label>
|
||||||
<div :class="isRow ? 'col-md-10' : 'col-md-12'">
|
<div :class="isRow ? 'col-md-10' : 'col-md-12'">
|
||||||
<select class="form-select" :id="name" v-model="selectData">
|
<select class="form-select" :id="name" v-model="selectData" :disabled="disabled">
|
||||||
<option v-for="(item, i) in data" :key="i" :value="isCommon ? item.value : i">
|
<option v-for="(item, i) in data" :key="i" :value="isCommon ? item.value : i">
|
||||||
{{ isCommon ? item.label : item }}
|
{{ isCommon ? item.label : item }}
|
||||||
</option>
|
</option>
|
||||||
@ -63,6 +63,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
required: false,
|
required: false,
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,9 @@ const selectAlphabet = (alphabet) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.btn {
|
||||||
|
min-width: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.alphabet-list {
|
.alphabet-list {
|
||||||
|
|||||||
@ -13,7 +13,15 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="d-flex align-items-center">
|
<input
|
||||||
|
v-if="userStore.user.role == 'ROLE_ADMIN'"
|
||||||
|
type="checkbox"
|
||||||
|
class="form-check-input admin-chk"
|
||||||
|
:name="item.WRDDICSEQ"
|
||||||
|
id=""
|
||||||
|
@change="toggleCheck($event)"
|
||||||
|
>
|
||||||
|
<div class="d-flex align-ite-center">
|
||||||
<div class="w-100 d-flex align-items-center">
|
<div class="w-100 d-flex align-items-center">
|
||||||
<span class="btn btn-primary pe-none">{{ item.category }}</span>
|
<span class="btn btn-primary pe-none">{{ item.category }}</span>
|
||||||
<strong class="mx-2 w-75">{{ item.WRDDICTTL }}</strong>
|
<strong class="mx-2 w-75">{{ item.WRDDICTTL }}</strong>
|
||||||
@ -34,7 +42,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
|
<div
|
||||||
|
v-if="item.author.createdAt !== item.lastEditor.updatedAt"
|
||||||
|
class="d-flex justify-content-between flex-wrap gap-2 mb-2"
|
||||||
|
>
|
||||||
<div class="d-flex flex-wrap align-items-center mb-50">
|
<div class="d-flex flex-wrap align-items-center mb-50">
|
||||||
<div class="avatar avatar-sm me-2">
|
<div class="avatar avatar-sm me-2">
|
||||||
<img
|
<img
|
||||||
@ -64,6 +75,11 @@ import EditBtn from '@/components/button/EditBtn.vue';
|
|||||||
import $api from '@api';
|
import $api from '@api';
|
||||||
import DictWrite from './DictWrite.vue';
|
import DictWrite from './DictWrite.vue';
|
||||||
|
|
||||||
|
import { useUserInfoStore } from '@s/useUserInfoStore';
|
||||||
|
|
||||||
|
// 유저 구분
|
||||||
|
const userStore = useUserInfoStore();
|
||||||
|
|
||||||
const toastStore = useToastStore();
|
const toastStore = useToastStore();
|
||||||
|
|
||||||
const { appContext } = getCurrentInstance();
|
const { appContext } = getCurrentInstance();
|
||||||
@ -87,7 +103,7 @@ const localCateList = ref([...props.cateList]);
|
|||||||
const selectedCategory = ref('');
|
const selectedCategory = ref('');
|
||||||
|
|
||||||
// cateList emit
|
// cateList emit
|
||||||
const emit = defineEmits(['update:cateList','refreshWordList']);
|
const emit = defineEmits(['update:cateList','refreshWordList', 'updateChecked']);
|
||||||
|
|
||||||
// 글 수정 상태
|
// 글 수정 상태
|
||||||
const isWriteVisible = ref(false);
|
const isWriteVisible = ref(false);
|
||||||
@ -171,6 +187,12 @@ const formatDate = (dateString) => new Date(dateString).toLocaleString();
|
|||||||
// 프로필 이미지
|
// 프로필 이미지
|
||||||
const getProfileImage = (imagePath) =>
|
const getProfileImage = (imagePath) =>
|
||||||
imagePath ? `${baseUrl}upload/img/profile/${imagePath}` : '/img/avatars/default-Profile.jpg';
|
imagePath ? `${baseUrl}upload/img/profile/${imagePath}` : '/img/avatars/default-Profile.jpg';
|
||||||
|
|
||||||
|
|
||||||
|
// 체크 상태 변경 시 부모로 전달
|
||||||
|
const toggleCheck = (event) => {
|
||||||
|
emit('updateChecked', event.target.checked, props.item.WRDDICSEQ, event.target.name);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -185,4 +207,12 @@ const getProfileImage = (imagePath) =>
|
|||||||
right: 0.7rem;
|
right: 0.7rem;
|
||||||
top: 1.2rem;
|
top: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.admin-chk {
|
||||||
|
position: absolute;
|
||||||
|
left: -0.5rem;
|
||||||
|
top: -0.5rem;
|
||||||
|
--bs-form-check-bg: #fff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -10,10 +10,11 @@
|
|||||||
@update:data="selectCategory = $event"
|
@update:data="selectCategory = $event"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
:value="formValue"
|
:value="formValue"
|
||||||
|
:disabled="isDisabled"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2 btn-margin">
|
<div class="col-2 btn-margin">
|
||||||
<PlusBtn @click="toggleInput"/>
|
<PlusBtn v-if="userStore.user.role == 'ROLE_ADMIN'" @click="toggleInput"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -37,6 +38,7 @@
|
|||||||
:is-alert="wordTitleAlert"
|
:is-alert="wordTitleAlert"
|
||||||
:modelValue="titleValue"
|
:modelValue="titleValue"
|
||||||
@update:modelValue="wordTitle = $event"
|
@update:modelValue="wordTitle = $event"
|
||||||
|
:disabled="isDisabled"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -56,6 +58,13 @@ import QEditor from '@/components/editor/QEditor.vue';
|
|||||||
import FormInput from '@/components/input/FormInput.vue';
|
import FormInput from '@/components/input/FormInput.vue';
|
||||||
import FormSelect from '@/components/input/FormSelect.vue';
|
import FormSelect from '@/components/input/FormSelect.vue';
|
||||||
import PlusBtn from '../button/PlusBtn.vue';
|
import PlusBtn from '../button/PlusBtn.vue';
|
||||||
|
import { useUserInfoStore } from '@s/useUserInfoStore';
|
||||||
|
|
||||||
|
// 유저 구분
|
||||||
|
const userStore = useUserInfoStore();
|
||||||
|
|
||||||
|
// 유저 상태에 따른 disabled
|
||||||
|
const isDisabled = computed(() => userStore.user.role !== 'ROLE_ADMIN');
|
||||||
|
|
||||||
const emit = defineEmits(['close','addCategory','addWord']);
|
const emit = defineEmits(['close','addCategory','addWord']);
|
||||||
|
|
||||||
@ -73,6 +82,11 @@ const addCategoryAlert = ref(false);
|
|||||||
//선택 카테고리
|
//선택 카테고리
|
||||||
const selectCategory = ref('');
|
const selectCategory = ref('');
|
||||||
|
|
||||||
|
// 제목 상태
|
||||||
|
const computedTitle = computed(() =>
|
||||||
|
wordTitle.value === '' ? props.titleValue : wordTitle.value
|
||||||
|
);
|
||||||
|
|
||||||
// 카테고리 상태
|
// 카테고리 상태
|
||||||
const selectedCategory = computed(() =>
|
const selectedCategory = computed(() =>
|
||||||
selectCategory.value === '' ? props.formValue : selectCategory.value
|
selectCategory.value === '' ? props.formValue : selectCategory.value
|
||||||
@ -104,15 +118,18 @@ const toggleInput = () => {
|
|||||||
showInput.value = !showInput.value;
|
showInput.value = !showInput.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 카테고리 저장
|
// 카테고리 저장
|
||||||
const saveInput = () => {
|
const saveInput = () => {
|
||||||
if(addCategory.value == ''){
|
if(addCategory.value == ''){
|
||||||
addCategoryAlert.value = true;
|
addCategoryAlert.value = true;
|
||||||
return;
|
return;
|
||||||
|
}else {
|
||||||
|
addCategoryAlert.value = false;
|
||||||
}
|
}
|
||||||
// console.log('입력값 저장됨!',addCategory.value);
|
// console.log('입력값 저장됨!',addCategory.value);
|
||||||
emit('addCategory', addCategory.value);
|
emit('addCategory', addCategory.value);
|
||||||
showInput.value = false;
|
// showInput.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChange = (newValue) => {
|
const onChange = (newValue) => {
|
||||||
@ -124,7 +141,7 @@ const saveWord = () => {
|
|||||||
//validation
|
//validation
|
||||||
|
|
||||||
// 용어 체크
|
// 용어 체크
|
||||||
if(wordTitle.value == ''){
|
if(computedTitle.value == '' || computedTitle.length == 0){
|
||||||
wordTitleAlert.value = true;
|
wordTitleAlert.value = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -137,7 +154,7 @@ const saveWord = () => {
|
|||||||
|
|
||||||
const wordData = {
|
const wordData = {
|
||||||
id: props.NumValue || null,
|
id: props.NumValue || null,
|
||||||
title: wordTitle.value,
|
title: computedTitle.value,
|
||||||
category: selectedCategory.value,
|
category: selectedCategory.value,
|
||||||
content: content.value,
|
content: content.value,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl flex-grow-1 container-p-y">
|
<div class="container-xxl flex-grow-1 container-p-y">
|
||||||
|
<!-- {{ userStore.user.role == 'ROLE_ADMIN' ? '관리자' : '일반인'}} -->
|
||||||
<div class="card p-5">
|
<div class="card p-5">
|
||||||
<!-- 타이틀, 검색 -->
|
<!-- 타이틀, 검색 -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -34,8 +34,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 용어 리스트 -->
|
<!-- 용어 리스트 -->
|
||||||
<div class="mt-10">
|
<div class="mt-10">
|
||||||
<!-- 로딩 중일 때 -->
|
<!-- 로딩 중일 때 -->
|
||||||
<div v-if="loading">로딩 중...</div>
|
<div v-if="loading">로딩 중...</div>
|
||||||
|
|
||||||
@ -50,16 +50,21 @@
|
|||||||
:item="item"
|
:item="item"
|
||||||
:cateList="cateList"
|
:cateList="cateList"
|
||||||
@refreshWordList="getwordList"
|
@refreshWordList="getwordList"
|
||||||
|
@updateChecked="updateCheckedItems"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- 데이터가 없을 때 -->
|
<!-- 데이터가 없을 때 -->
|
||||||
<div v-else-if="!loading && !error" class="card p-5 text-center">용어집의 용어가 없습니다.</div>
|
<div v-else-if="!loading && !error" class="card p-5 text-center">용어집의 용어가 없습니다.</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button v-if="isAnyChecked" class="btn btn-danger admin-del-btn">
|
||||||
|
<i class="bx bx-trash"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -73,6 +78,10 @@
|
|||||||
import DictAlphabetFilter from '@/components/wordDict/DictAlphabetFilter.vue';
|
import DictAlphabetFilter from '@/components/wordDict/DictAlphabetFilter.vue';
|
||||||
import commonApi from '@/common/commonApi';
|
import commonApi from '@/common/commonApi';
|
||||||
import { useToastStore } from '@s/toastStore';
|
import { useToastStore } from '@s/toastStore';
|
||||||
|
import { useUserInfoStore } from '@s/useUserInfoStore';
|
||||||
|
|
||||||
|
// 유저 구분
|
||||||
|
const userStore = useUserInfoStore();
|
||||||
|
|
||||||
const { appContext } = getCurrentInstance();
|
const { appContext } = getCurrentInstance();
|
||||||
const $common = appContext.config.globalProperties.$common;
|
const $common = appContext.config.globalProperties.$common;
|
||||||
@ -97,6 +106,11 @@
|
|||||||
const selectedCategory = ref('');
|
const selectedCategory = ref('');
|
||||||
const selectCategory = ref('');
|
const selectCategory = ref('');
|
||||||
|
|
||||||
|
// 체크박스 체크된 갯수
|
||||||
|
const checkedItems = ref([]);
|
||||||
|
// 체크박스의 name
|
||||||
|
const checkedNames = ref([]);
|
||||||
|
|
||||||
|
|
||||||
//선택된 알파벳
|
//선택된 알파벳
|
||||||
const selectedAlphabet = ref('');
|
const selectedAlphabet = ref('');
|
||||||
@ -163,7 +177,6 @@
|
|||||||
const addCategory = (data) =>{
|
const addCategory = (data) =>{
|
||||||
const lastCategory = cateList.value[cateList.value.length - 1];
|
const lastCategory = cateList.value[cateList.value.length - 1];
|
||||||
const newValue = lastCategory ? lastCategory.value + 1 : 600101;
|
const newValue = lastCategory ? lastCategory.value + 1 : 600101;
|
||||||
|
|
||||||
axios.post('worddict/insertCategory',{
|
axios.post('worddict/insertCategory',{
|
||||||
CMNCODNAM: data
|
CMNCODNAM: data
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
@ -172,6 +185,8 @@
|
|||||||
const newCategory = { label: data, value: newValue };
|
const newCategory = { label: data, value: newValue };
|
||||||
cateList.value = [newCategory, ...cateList.value];
|
cateList.value = [newCategory, ...cateList.value];
|
||||||
selectedCategory.value = newCategory.value;
|
selectedCategory.value = newCategory.value;
|
||||||
|
} else if(res.data.message == '이미 존재하는 카테고리명입니다.') {
|
||||||
|
toastStore.onToast(res.data.message, 'e');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -190,10 +205,34 @@
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 체크 상태 업데이트
|
||||||
|
const updateCheckedItems = (checked, id, name) => {
|
||||||
|
if (checked) {
|
||||||
|
checkedItems.value.push(id);
|
||||||
|
checkedNames.value.push(name);
|
||||||
|
} else {
|
||||||
|
checkedItems.value = checkedItems.value.filter(item => item !== id);
|
||||||
|
checkedNames.value = checkedNames.value.filter(item => item !== name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 콘솔에 현재 체크된 name 값 출력
|
||||||
|
console.log("현재 체크된 name 값:", checkedNames.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isAnyChecked = computed(() => checkedItems.value.length > 0);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
|
.admin-del-btn {
|
||||||
|
position: fixed;
|
||||||
|
right: 1.5rem;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: red;
|
color: red;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user