You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
8.2 KiB

<script setup lang="ts">
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";
// import FormComponent from "@/components/device/FormComponent.vue";
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import * as monaco from "monaco-editor";
import "monaco-editor/min/vs/editor/editor.main.css";
// const store = commonStore();
const editorRef = ref<HTMLDivElement | null>(null);
let editorInstance: monaco.editor.IStandaloneCodeEditor | null = null;
const experimentInfo = ref({
modelName: "ImageClassifier",
projectName: "배터리 상태 예측 모델 프로젝트",
experimentName: "Baseline Model Training",
executionName: "run-batch32-lr0.001",
deployDate: "2025-02-06",
createdId: "ADMIN_001",
description: "기본 모델 구조로 학습 성능 측정",
});
const yamlContent = `import argparse
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import os
class SimpleNet(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu = nn.ReLU()
`;
const data = ref({
params: {
pageNum: 1,
pageSize: 10,
searchType: "",
searchText: "",
},
results: [],
totalDataLength: 0,
pageLength: 0,
modalMode: "",
selectedData: null,
allSelected: false,
selected: [],
isModalVisible: false,
isConfirmDialogVisible: false,
userOption: [],
});
const getCodeList = () => {
// UserService.search(data.value.params).then((d) => {
// if (d.status === 200) {
// data.value.userOption = d.data.userList;
// }
// });
};
const setPaginationLength = () => {
if (data.value.totalDataLength % data.value.params.pageSize === 0) {
data.value.pageLength =
data.value.totalDataLength / data.value.params.pageSize;
} else {
data.value.pageLength = Math.ceil(
data.value.totalDataLength / data.value.params.pageSize,
);
}
};
const saveData = (formData) => {
if (data.value.modalMode === "create") {
// DeviceService.add(formData).then((d) => {
// if (d.status === 200) {
// data.value.isModalVisible = false;
// store.setSnackbarMsg({
// text: "등록 되었습니다.",
// result: 200,
// });
// changePageNum(1);
// } else {
// store.setSnackbarMsg({
// text: d,
// result: 500,
// });
// }
// });
} else {
// DeviceService.update(formData.deviceKey, formData).then((d) => {
// if (d.status === 200) {
// data.value.isModalVisible = false;
// store.setSnackbarMsg({
// text: "수정 되었습니다.",
// result: 200,
// });
// changePageNum();
// } else {
// store.setSnackbarMsg({
// text: d,
// result: 500,
// });
// }
// });
}
};
const removeData = (value) => {
let removeList = value ? value : data.value.selected;
const remove = (code) => {
// return DeviceService.delete(code).then((d) => {
// if (d.status !== 200) {
// store.setSnackbarMsg({
// text: d,
// result: 500,
// });
// }
// });
};
if (removeList.length === 1) {
remove(removeList[0].deviceKey).then(() => {
// store.setSnackbarMsg({
// text: "삭제되었습니다.",
// result: 200,
// });
data.value.isConfirmDialogVisible = false;
data.value.selected = [];
data.value.allSelected = false;
});
} else {
Promise.all(removeList.map((item) => remove(item.deviceKey))).finally(
() => {
// store.setSnackbarMsg({
// text: "모두 삭제되었습니다.",
// result: 200,
// });
data.value.isConfirmDialogVisible = false;
data.value.selected = [];
data.value.allSelected = false;
},
);
}
};
const changePageNum = (page) => {
data.value.params.pageNum = page;
};
const emit = defineEmits<{
(e: "close"): void;
}>();
onMounted(() => {
getCodeList();
if (editorRef.value) {
editorInstance = monaco.editor.create(editorRef.value, {
value: yamlContent,
language: "yaml",
theme: "vs-dark",
readOnly: true,
automaticLayout: true,
minimap: { enabled: false },
lineNumbers: "on",
});
}
});
onBeforeUnmount(() => {
if (editorInstance) {
editorInstance.dispose();
editorInstance = null;
}
});
</script>
<template>
<v-container fluid class="h-100 pa-5 d-flex flex-column align-center">
<v-card
flat
class="bg-shades-transparent d-flex flex-column justify-center w-100"
>
<v-card flat class="bg-shades-transparent w-100">
<v-card-item class="text-h5 font-weight-bold pt-0 pa-5 pl-0">
<div class="d-flex flex-row justify-start align-center">
<div class="text-primary">View Details</div>
</div>
</v-card-item>
</v-card>
<v-card flat class="bordered-box mb-6 w-100 rounded-lg pa-8">
<v-card-title class="grey lighten-4 py-2 px-4">
<span class="font-weight-bold">Training Script Information </span>
</v-card-title>
<v-card-text class="px-6 pb-6 pt-4">
<!-- Experiment Name -->
<v-row align="center" class="py-2">
<v-col cols="3" class="text-h6 font-weight-bold"
>Training Script Title
</v-col>
<v-col cols="9" class="pa-2">{{ experimentInfo.modelName }}</v-col>
</v-row>
<VDivider class="my-2" />
<!-- Project Name -->
<v-row align="center" class="py-2">
<v-col cols="3" class="text-h6 font-weight-bold">File Name </v-col>
<v-col cols="9" class="pa-2">{{
experimentInfo.projectName
}}</v-col>
</v-row>
<VDivider class="my-2" />
<v-row align="center" class="py-2">
<v-col cols="3" class="text-h6 font-weight-bold">File Path </v-col>
<v-col cols="9" class="pa-2">{{
experimentInfo.experimentName
}}</v-col>
</v-row>
<VDivider class="my-2" />
<!-- Created Date / ID -->
<v-row align="center" class="py-2">
<v-col cols="3" class="text-h6 font-weight-bold"
>Created Date
</v-col>
<v-col cols="3" class="pa-2">{{ experimentInfo.deployDate }}</v-col>
<v-col cols="3" class="text-h6 font-weight-bold"
>Modified Date
</v-col>
<v-col cols="3" class="pa-2">{{ experimentInfo.createdId }}</v-col>
</v-row>
<VDivider class="my-2" />
<!-- Description -->
<v-row align="center" class="py-2">
<v-col cols="3" class="text-h6 font-weight-bold">Description</v-col>
<v-col cols="9" class="pa-2">{{
experimentInfo.description
}}</v-col>
</v-row>
</v-card-text>
</v-card>
<v-card flat class="bordered-box mb-6 w-100 rounded-lg pa-8">
<v-card-title class="grey lighten-4 py-2 px-4">
<span class="font-weight-bold">Training Script Preview </span>
</v-card-title>
<v-card-text class="px-6 pb-6 pt-4">
<div ref="editorRef" class="editor-container"></div
></v-card-text>
<v-sheet class="d-flex justify-end mb-2">
<v-btn color="primary" @click="emit('close')"> Back to List </v-btn>
</v-sheet>
</v-card>
</v-card>
</v-container>
</template>
<style scoped>
.editor-container {
width: 100%;
height: 400px; /* 원하시는 높이로 설정하세요 */
}
.v-card-text {
width: 100% !important;
border-collapse: collapse;
/* 전체 테이블 1px 테두리 */
}
.v-card-text th {
font-size: 20px;
min-width: 400px;
border: 1px solid rgba(255, 255, 255, 0.12);
background-color: rgba(255, 255, 255, 0.05);
font-weight: 600;
text-align: center;
white-space: nowrap;
}
.v-card-text td {
font-size: 16px;
min-width: 600px;
padding: 12px 16px;
text-align: left;
border: 1px solid rgba(255, 255, 255, 0.12);
}
.v-card-text tr:nth-child(odd) {
background-color: rgba(255, 255, 255, 0.02);
}
</style>