
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div v-show="isModalOpen" class="modal-wrapper">
<div class="modal-container large-modal">
<div class="modal-title">
<div class="flex justify-between align-center">
<h2>데이터셋 업데이트</h2>
<button
type="button"
class="close-btn"
@click="$emit('fnCloseModal')"
>
<svg-icon
type="mdi"
:width="20"
:height="20"
:path="closePath"
></svg-icon>
</button>
</div>
</div>
<div class="modal-content-monthly">
<div class="tab-contents mt10">
<div class="content-titleZone flex justify-between align-center">
<p class="box-title">데이터셋 설정</p>
</div>
<table class="form-table">
<colgroup>
<col style="width: 15%" />
<col style="width: 85%" />
</colgroup>
<tbody>
<tr>
<th>데이터셋 설정</th>
<td>
<button
class="blue-border-btn small-btn"
@click="fnTargetDataRead"
>
타겟 데이터 조회
</button>
</td>
</tr>
<tr>
<th>기존 데이터 삭제 여부</th>
<td>
<div class="input-container flex">
<label class="radio-label mr5">
<input
type="radio"
name="radio"
:value="false"
class="custom-radiobox"
v-model="jobItm.itm_option_bool"
/>
<span>기존 데이터 삭제</span>
</label>
<label class="radio-label">
<input
type="radio"
name="radio"
:value="true"
class="custom-radiobox"
v-model="jobItm.itm_option_bool"
/>
<span>기존 데이터 미삭제</span>
</label>
</div>
</td>
</tr>
</tbody>
</table>
<div v-if="targetColumnDatas.length > 0" class="flex mt20">
<div class="flex50 pl0">
<div class="content-titleZone flex justify-between align-center">
<p class="box-title">
컬럼 매칭
<small>
( 매칭 : {{ matchs.matchCnt }}, 비매칭 :
{{ matchs.unMatchCnt }}
)
</small>
</p>
</div>
<div
class="columncontBox"
style="height: 620px; overflow-y: auto"
>
<table>
<colgroup>
<col style="width: 50%" />
</colgroup>
<tbody>
<tr v-for="(column, index) of columnMatchList" :key="index">
<td>
<p class="col-data">
{{ column.columnOriginalName }}
</p>
</td>
<td
draggable="true"
@dragstart="fnMoveStart(column)"
@dragover="fnOnDragover"
@drop="fnChangeMatchData('drop', index)"
@dblclick="fnChangeMatchData('doubleClick', index)"
>
<p class="col-data">
{{ column.columnMatchName }}
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="flex50 pr0">
<div class="content-titleZone flex justify-between align-center">
<p class="box-title">데이터 컬럼</p>
</div>
<div
class="columncontBox"
style="height: 620px; overflow-y: auto"
>
<template v-if="sourceColumnDatas.length > 0">
<ul>
<li
v-for="(source, index) of sourceColumnDatas"
:key="index"
:class="{ 'col-data': true, disabled: !source.view }"
:draggable="source.view"
@dragstart="fnOnDragstart(source.displyColumnNm, index)"
>
{{ source.displyColumnNm }}
</li>
</ul>
</template>
<p v-else class="text-ct">등록된 데이터가 없습니다.</p>
</div>
</div>
</div>
</div>
</div>
<div class="modal-end flex justify-end">
<button type="button" class="blue-btn small-btn" @click="fnSave">
저장
</button>
<button
type="button"
class="blue-border-btn small-btn"
@click="$emit('fnCloseModal')"
>
취소
</button>
</div>
</div>
<datasetSelecter
:openPopup="isSelectModalOpen"
@closePopup="fnCloseDatasetSelectModal"
@saveNodeData="fnUpdateDatasetSelect"
/>
</div>
</template>
<script>
import SvgIcon from "@jamescoyle/vue-icon";
import { mdiClose } from "@mdi/js";
import axios from "axios";
import datasetSelecter from "./datasetSelecter.vue";
export default {
components: {
SvgIcon: SvgIcon,
datasetSelecter: datasetSelecter,
},
props: {
openPopup: {
type: Boolean,
default: false,
},
jobItem: {
type: Object,
},
nodes: {
type: Array,
required: true,
},
edges: {
type: Array,
required: true,
},
},
data() {
return {
isModalOpen: this.openPopup,
closePath: mdiClose,
jobItm: this.jobItem,
nodeList: this.nodes,
edgeList: this.edges,
// 연결된 이전 노드
prevNode: {},
// 데이터셋 선택
isSelectModalOpen: false,
// 컬럼 매칭
columnMatchList: [],
sourceColumnDatas: [],
targetColumnDatas: [],
changeColList: [],
matchs: {
matchCnt: 0,
unMatchCnt: 0,
},
dragData: {
source: null,
sourceIdx: null,
},
datapostId: null,
};
},
mounted() {
this.init(); // 초기화
// 타겟 데이터가 있는 경우
if (this.jobItm.itm.hasOwnProperty("item")) {
if (this.jobItm.itm.item != null) {
this.datapostId = this.jobItm.itm.item;
this.fnSetupRead();
}
}
},
watch: {
columnMatchList: {
deep: true,
handler() {
this.fnMatchList(); // 매치 리스트
},
},
},
methods: {
// 초기화
init() {
// 연결된 노드 정보 조회(최초 1회만 실행)
for (let edge of this.edgeList) {
if (edge.target == this.jobItm.id) {
for (let node of this.nodeList) {
if (node.id == edge.source) {
this.prevNode = node;
this.fnPrevNodeDataRead(); // 노드 정보 조회 후, 컬럼 데이터 가져오기
return;
}
}
}
}
this.$showAlert(
"에러 발생",
"DATASET_UPDATE를 설정하기 전, 먼저 노드를 연결해 주세요."
);
this.$emit("fnCloseModal"); // 모달 닫기
},
// 소스 데이터 조회
fnPrevNodeDataRead() {
this.sourceColumnDatas = []; // 초기화
if (!this.$isEmpty(this.prevNode.dataTable)) {
let columnDatas = this.prevNode.dataTable.columnDatas;
for (let data of columnDatas) {
data.view = true;
}
this.sourceColumnDatas = columnDatas;
} else {
this.$showAlert(
"에러 발생",
"DATASET_UPDATE에 연결된 노드의 설정을 마쳐 주세요."
);
}
},
// 타겟 데이터 조회 후 처리
fnSetTargetData(columnDatas) {
// 타겟 컬럼의 ts_row는 조작 불가하므로 목록에서 제거
columnDatas = columnDatas.filter(
(column) => column.orginlColumnNm !== "ts_row"
);
this.targetColumnDatas = columnDatas; // 타겟 데이터 저장
this.columnMatchList = []; // 초기화
for (let i = 0; i < columnDatas.length; i++) {
this.columnMatchList.push({
targetIdx: i,
sourceIdx: null,
columnOriginalName: columnDatas[i].displyColumnNm,
columnMatchName: null,
});
}
},
// 타겟 데이터 조회
fnSetupRead() {
// 데이터 세팅
let data = {
datapost_id: this.datapostId,
};
// 실행
axios({
url: "/dataset/getDataTableInfo.json",
method: "post",
headers: { "Content-Type": "application/json; charset=UTF-8" },
data: data,
})
.then((response) => {
let columnDatas = response.data.resultData.dataTable.columnDatas;
this.fnSetTargetData(columnDatas); // 타겟 데이터 조회 후 처리
})
.catch((error) => {
this.$showAlert(
"에러 발생",
"에러가 발생했습니다. 관리자에게 문의해 주세요."
);
});
},
// 타겟 데이터 조회
fnTargetDataRead() {
this.isSelectModalOpen = true;
},
// 타겟 데이터 조회 저장 후 모달 닫기
fnUpdateDatasetSelect(jobItem) {
this.datapostId = jobItem.itm.dataset_post_id;
this.fnSetTargetData(jobItem.dataTable.columnDatas); // 타겟 데이터 조회 후 처리
this.fnCloseDatasetSelectModal(); // 타겟 데이터 조회 모달 닫기
},
// 타겟 데이터 조회 모달 닫기
fnCloseDatasetSelectModal() {
this.isSelectModalOpen = false;
},
// 매치 리스트
fnMatchList() {
// 초기화
for (let sourceColumn of this.sourceColumnDatas) {
sourceColumn.view = true;
}
// 컬럼 매칭
let matchCnt = 0;
for (let col of this.columnMatchList) {
if (
!this.$isEmpty(col.sourceIdx) &&
!this.$isEmpty(col.columnMatchName)
) {
matchCnt++; // 매칭 정보가 있는 경우 +1
this.sourceColumnDatas[col.sourceIdx].view = false; // 드래그 막기
}
}
// 컬럼 매칭 결과 조회
this.matchs.matchCnt = matchCnt;
this.matchs.unMatchCnt = this.targetColumnDatas.length - matchCnt;
},
// 드래그 이벤트
fnMoveStart(match) {
this.dragData.source = match.columnMatchName;
this.dragData.sourceIdx = match.sourceIdx;
},
fnOnDragstart(displyName, index) {
this.dragData.source = displyName;
this.dragData.sourceIdx = index;
},
fnOnDragover(event) {
event.preventDefault();
},
fnChangeMatchData(type, targetIdx) {
// 기존값 삭제
for (let match of this.columnMatchList) {
if (
match.sourceIdx == this.dragData.sourceIdx &&
match.columnMatchName == this.dragData.source
) {
match.sourceIdx = null;
match.columnMatchName = null;
}
}
// 추가
for (let match of this.columnMatchList) {
if (match.targetIdx == targetIdx) {
if (type == "drop") {
match.sourceIdx = this.dragData.sourceIdx;
match.columnMatchName = this.dragData.source;
} else if (type == "doubleClick") {
match.sourceIdx = null;
match.columnMatchName = null;
}
break;
}
}
},
// 저장 버튼
fnSave() {
var itm = Object.assign({}, this.$getDefaultJobGroup().jobItemGroup);
itm.item = this.datapostId;
itm.itemList = []; // 초기화
for (let match of this.columnMatchList) {
itm.itemList.push({
orginColumnNm:
match.targetIdx != null && match.columnOriginalName != null
? match.targetIdx + "/" + match.columnOriginalName
: null,
targetColumnNm:
match.sourceIdx != null && match.columnMatchName != null
? match.sourceIdx + "/" + match.columnMatchName
: null,
});
}
this.jobItm.itm = itm;
this.$emit("fnSaveSetup", this.jobItm);
},
},
};
</script>
<style scoped>
.columncontBox {
background: #f5f5f5;
border-radius: 10px;
}
.columncontBox tr {
padding: 8px;
}
.columncontBox ul .col-data {
margin: 8px;
}
.columncontBox .col-data {
border: 1px solid #dbdbdb;
padding: 5px 10px;
background-color: var(--color-white);
border-radius: 10px;
cursor: move;
font-size: 1.3rem;
height: 34px;
}
.columncontBox .col-data.disabled {
background-color: #f5f5f5;
}
</style>