fix: 파일명 수정

main
jschoi 9 months ago
parent a11ff9c1d3
commit 3ee69ea5ac

@ -2,7 +2,7 @@
import { computed, ref, watch, onMounted, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia";
import { useAutoflowStore } from "@/stores/autoflowStore";
import { AttachmentsService } from "@/components/service/management/attachmentsService";
import { AttachmentsService } from "@/components/service/management/AttachmentsService";
import type { AxiosError } from "axios";
const props = defineProps<{ editData: any; mode: "create" | "edit" }>();

@ -4,12 +4,12 @@ import IconArrowUp from "@/components/atoms/button/IconArrowUp.vue";
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";
import { computed, onBeforeUnmount, onMounted, watch, ref } from "vue";
import { WorkflowService } from "@/components/service/management/workflowService";
import { WorkflowService } from "@/components/service/management/WorkflowService";
import { storage } from "@/utils/storage";
import type { Workflow } from "@/components/models/management/Workflow";
import { storeToRefs } from "pinia";
import { useAutoflowStore } from "@/stores/autoflowStore";
import { kubeflowService } from "@/components/service/management/kubeflowService";
import { kubeflowService } from "@/components/service/management/KubeflowService";
import {
toKubeflowForm,
type KubeflowUploadDto,

@ -4,8 +4,8 @@ import { storage } from "@/utils/storage";
import { storeToRefs } from "pinia";
import { useAutoflowStore } from "@/stores/autoflowStore";
import type { AxiosError } from "axios";
import { WorkflowStepService } from "@/components/service/management/workflowStepService";
import { WorkflowService } from "@/components/service/management/workflowService"; //
import { WorkflowStepService } from "@/components/service/management/WorkflowStepService";
import { WorkflowService } from "@/components/service/management/WorkflowService"; //
const props = defineProps<{ editData: any; mode: "create" | "edit" }>();
const emit = defineEmits<{

@ -3,7 +3,7 @@ import { useRoute, useRouter } from "vue-router";
import { storage } from "@/utils/storage.js";
import DrawerComponent from "@/components/common/DrawerComponent.vue";
import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
import SidebarHeader from "@/components/common/SidebarHeader.vue";
const route = useRoute();

@ -0,0 +1,6 @@
export interface RunsSearchParams {
page_token?: string;
page_size?: number;
sort_by?: "created_at_desc" | string;
filter?: string;
}

@ -0,0 +1,7 @@
import { RunsSearchParams } from "@/components/models/management/Exeucutios";
import { request } from "@/components/service/index";
export const ExecutionsService = {
search: (payload: RunsSearchParams) => {
return request.get("/api/runs/runs", { params: payload });
},
};

@ -7,4 +7,7 @@ export const kubeflowService = {
run: (payload: kubeflow) => {
return request.post("/pipelines/runs", payload);
},
kubeflowSize: (payload: kubeflow) => {
return request.post("/pipelines/experiments", payload);
},
};

@ -1,7 +1,7 @@
<script setup lang="ts">
import { onMounted, ref, computed, watch } from "vue";
import Plotly from "plotly.js-dist-min";
import { WorkflowService } from "@/components/service/management/workflowService";
import { WorkflowService } from "@/components/service/management/WorkflowService";
import { useAutoflowStore } from "@/stores/autoflowStore";
const store = useAutoflowStore();

@ -3,7 +3,7 @@ import { ref, onMounted, watch, computed } from "vue";
import { commonStore } from "@/stores/commonStore";
import { storage } from "@/utils/storage.js";
import { ProjectService } from "@/components/service/project/projectService";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
import type { Permission } from "@/components/models/project/Project";
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";

@ -1,14 +1,28 @@
<script setup lang="ts">
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import { onMounted, ref, watch } from "vue";
import { ref, onMounted, watch } from "vue";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import tz from "dayjs/plugin/timezone";
import IconDownloadBtn from "@/components/atoms/button/IconDownloadBtn.vue";
import IconInfoBtn from "@/components/atoms/button/IconInfoBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";
import CompareComponent from "@/components/templates/run/executions/CompareComponent.vue";
import ViewComponent from "@/components/templates/run/executions/ViewComponent.vue";
import ExecutionBaseDialog from "@/components/atoms/organisms/ExecutionBaseDialog.vue";
// const store = commonStore();
import { ExecutionsService } from "@/components/service/management/ExecutionsService";
import type { RunsSearchParams } from "@/components/models/management/Exeucutios";
dayjs.extend(utc);
dayjs.extend(tz);
const KST = "Asia/Seoul";
/* ===== UI 상태 ===== */
const openCompare = ref(false);
const openView = ref(false);
const tableHeader = [
{ label: "No", width: "5%", style: "word-break: keep-all;" },
{ label: "Execution Name", width: "20%", style: "word-break: keep-all;" },
@ -36,7 +50,6 @@ const execMode = ref<"create" | "edit" | "clone">("create");
const execSelected = ref<any>(null);
const searchExperimentOptions = [{ searchType: "Experiment", searchText: "" }];
const searchWorkflowOptions = [{ searchType: "Workflow", searchText: "" }];
const workflowList = ref(["pipeline-a", "pipeline-b", "pipeline-c"]);
const executionTypes = ref(["One-off", "Recurring"]);
@ -46,6 +59,18 @@ const pageSizeOptions = [
{ text: "100 페이지", value: 100 },
];
type UiRow = {
no: number;
name: string;
status: string;
duration: string;
experiment: string;
workflow: string;
startTime: string;
registryStatus: string;
deviceKey: string; // run_id
};
const data = ref({
params: {
pageNum: 1,
@ -53,251 +78,205 @@ const data = ref({
searchType: "",
searchText: "",
},
results: [],
results: [] as UiRow[],
totalDataLength: 0,
pageLength: 0,
modalMode: "",
selectedData: null,
selectedData: null as any,
allSelected: false,
selected: [],
selected: [] as Array<{ deviceKey: string }>,
isModalVisible: false,
isConfirmDialogVisible: false,
userOption: [],
userOption: [] as any[],
});
const getCodeList = () => {
// UserService.search(data.value.params).then((d) => {
// if (d.status === 200) {
// data.value.userOption = d.data.userList;
// }
// });
};
/* ===== page_token 기반 페이지네이션 캐시 ===== */
const pageTokens = ref<string[]>([""]); // index=0 ( )
const nextPageToken = ref<string | undefined>();
const getData = () => {
const params = { ...data.value.params };
if (params.searchType === "" || params.searchText === "") {
delete params.searchType;
delete params.searchText;
/* ===== 헬퍼 ===== */
const mapState = (s?: string) => {
switch ((s || "").toUpperCase()) {
case "SUCCEEDED":
return "Succeeded";
case "FAILED":
return "Failed";
case "RUNNING":
return "Running";
case "PENDING":
return "Pending";
default:
return s || "";
}
data.value.results = [
{
no: 11,
name: "run-batch32-lr0.001",
status: "Succeeded",
duration: "0:00:21",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-20 10:12",
registryStatus: "Registered",
},
{
no: 10,
name: "run-batch64-lr0.001",
status: "Failed",
duration: "0:00:20",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-20 09:10",
registryStatus: "Not Registered",
},
{
no: 9,
name: "run-batch32-lr0.0005",
status: "Succeeded",
duration: "0:00:21",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-19 10:12",
registryStatus: "Registered",
},
{
no: 8,
name: "run-batch64-lr0.0005",
status: "Running",
duration: "0:00:20",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-18 11:50",
registryStatus: "Not Registered",
},
{
no: 7,
name: "run-augmented-data",
status: "Succeeded",
duration: "0:00:20",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-17 09:12",
registryStatus: "Registered",
},
{
no: 6,
name: "run-augmented-data",
status: "Succeeded",
duration: "0:00:20",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-17 09:12",
registryStatus: "Registered",
},
{
no: 5,
name: "run-augmented-data",
status: "Succeeded",
duration: "0:00:20",
experiment: "Baseline Model Training",
workflow: "baseline_train_pipeline",
startTime: "2025-05-17 09:12",
registryStatus: "Registered",
},
];
data.value.totalDataLength = data.value.results.length;
setPaginationLength();
// DeviceService.search(params).then((d) => {
// if (d.status === 200) {
// data.value.results = d.data.deviceList;
// data.value.totalDataLength = d.data.totalCount;
// setTimeout(() => {
// setPaginationLength();
// }, 200);
// } else {
// store.setSnackbarMsg({
// text: " ",
// color: "error",
// });
// }
// });
// DeviceService.search().then((d) => {
// data.value.totalDataLength = d.data.totalCount;
// setTimeout(() => {
// setPaginationLength();
// }, 200);
// });
};
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 formatRegistry = (v?: string) => {
const s = (v || "").toUpperCase();
if (s === "AVAILABLE") return "Registered";
if (s === "ARCHIVED") return "Archived";
return v || "";
};
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 kst = (v?: string | number | Date) =>
v ? dayjs(v).tz(KST).format("YYYY-MM-DD HH:mm:ss") : "";
const duration = (start?: string, end?: string) => {
if (!start) return "";
const s = dayjs(start);
const e = end ? dayjs(end) : dayjs();
const diff = dayjs.duration(e.diff(s));
const h = Math.floor(diff.asHours());
const m = String(diff.minutes()).padStart(2, "0");
const sec = String(diff.seconds()).padStart(2, "0");
return `${h}:${m}:${sec}`;
};
const toRow = (run: any, no: number): UiRow => ({
no,
name: run?.display_name ?? run?.name ?? run?.run_id ?? "-",
status: mapState(run?.state),
duration: duration(run?.created_at, run?.finished_at),
experiment: run?.experiment_id ?? "",
workflow:
run?.pipeline_version_reference?.pipeline_id ??
run?.pipeline_version_reference?.pipeline_version_id ??
"",
startTime: kst(run?.created_at),
registryStatus: formatRegistry(run?.storage_state),
deviceKey: run?.run_id,
});
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,
// });
// }
// });
};
/* ===== 모든 페이지 콘솔 덤프 + 첫 페이지(최대 1000건) 테이블 반영 ===== */
const dumpAllRunsToConsole = async () => {
let token: string | undefined = undefined;
let page = 1;
const pageSize = 10;
const all: any[] = [];
let totalSizeFromServer: number | undefined;
do {
const payload: RunsSearchParams = {
page_token: token,
page_size: pageSize,
sort_by: "created_at_desc",
};
const res = await ExecutionsService.search(payload);
const body = res?.data ?? {};
const runs: any[] = Array.isArray(body.runs) ? body.runs : [];
const next = body.next_page_token as string | undefined;
if (page === 1) {
totalSizeFromServer =
Number(body.total_size ?? runs.length) || runs.length;
console.log(`[Runs] total_size (server): ${totalSizeFromServer}`);
}
console.log(
`[Runs] page ${page} — count: ${runs.length}, next_page_token: ${
next ? "YES" : "NO"
}`,
);
console.table(
runs.map((r: any, i: number) => ({
i,
run_id: r.run_id,
name: r.display_name ?? r.name,
state: r.state,
created_at: r.created_at,
finished_at: r.finished_at,
})),
);
all.push(...runs);
token = next;
page += 1;
} while (token);
if (removeList.length === 1) {
remove(removeList[0].deviceKey).then(() => {
// store.setSnackbarMsg({
// text: ".",
// result: 200,
// });
changePageNum();
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,
// });
changePageNum();
data.value.isConfirmDialogVisible = false;
data.value.selected = [];
data.value.allSelected = false;
},
console.log(`[Runs] aggregated count (fetched): ${all.length}`);
if (typeof totalSizeFromServer === "number") {
console.log(
`[Runs] server total_size vs fetched: ${totalSizeFromServer} vs ${all.length}`,
);
}
// ( 1000)
const firstPage = all.slice(0, pageSize);
const firstNoStart = totalSizeFromServer ?? all.length;
data.value.results = firstPage.map((r, i) => toRow(r, firstNoStart - i));
data.value.totalDataLength = totalSizeFromServer ?? all.length;
data.value.pageLength = Math.max(
1,
Math.ceil((totalSizeFromServer ?? all.length) / pageSize),
);
// ( )
pageTokens.value = [""];
nextPageToken.value = undefined;
};
const handleRemoveData = () => {
if (data.value.selected.length === 0) {
// store.setSnackbarMsg({
// text: " . ",
// result: 500,
// });
return;
}
if (data.value.allSelected || data.value.selected.length !== 1) {
data.value.isConfirmDialogVisible = true;
return;
/* ===== (옵션) 단일 페이지 가져오기 — 테이블 재조회 필요 시 사용 ===== */
const fetchPage = async (pageIndex: number) => {
const token = pageTokens.value[pageIndex - 1] || undefined;
const payload: RunsSearchParams = {
page_token: token,
page_size: data.value.params.pageSize, // 1000
sort_by: "created_at_desc",
};
const res = await ExecutionsService.search(payload);
const body = res?.data ?? {};
const runs: any[] = Array.isArray(body.runs) ? body.runs : [];
const total = Number(body.total_size ?? runs.length) || runs.length;
console.log(
`[Runs] total_size: ${total}, pageIndex: ${pageIndex}, page_size: ${data.value.params.pageSize}, this_page: ${runs.length}, next_page_token:`,
body.next_page_token || "(none)",
);
console.table(
runs.map((r, i) => ({
i,
run_id: r.run_id,
name: r.display_name ?? r.name,
state: r.state,
created_at: r.created_at,
finished_at: r.finished_at,
})),
);
const pageOffset = (pageIndex - 1) * data.value.params.pageSize;
const firstNo = Math.max(total - pageOffset, 1);
data.value.results = runs.map((r, i) => toRow(r, firstNo - i));
data.value.totalDataLength = total;
data.value.pageLength = Math.max(
1,
Math.ceil(total / data.value.params.pageSize),
);
nextPageToken.value = body.next_page_token;
if (nextPageToken.value && !pageTokens.value[pageIndex]) {
pageTokens.value[pageIndex] = nextPageToken.value;
}
//
removeData(undefined);
};
const handleTerminate = () => {
alert("Terminate 작업 진행중...");
};
const handleRetry = () => {
alert("Retry 작업 진행중...");
};
const handleClone = () => {
alert("Clone 작업 진행중...");
/* ===== 템플릿 이벤트에 맞춘 함수들 ===== */
const getData = async (newPage?: number) => {
if (typeof newPage === "number") data.value.params.pageNum = newPage;
// page_size 1000 1
await fetchPage(1);
};
const changePageNum = (page) => {
const changePageNum = async (page: number) => {
data.value.params.pageNum = page;
getData();
await getData(page);
};
const openCreateExecution = () => {
execMode.value = "create";
execSelected.value = null;
execDialogOpen.value = true;
};
const openComparePage = () => {
openCompare.value = true;
openView.value = false;
@ -306,39 +285,42 @@ const openInfoModal = () => {
openView.value = true;
openCompare.value = false;
};
const openModifyModal = (selectedItem) => {
const openModifyModal = () => {
execMode.value = "edit";
execDialogOpen.value = true;
};
const openDownloadModal = () => {
data.value.selectedData = null;
data.value.modalMode = "download";
};
function closeCompare() {
openCompare.value = false;
}
function closeView() {
openView.value = false;
}
const closeModal = () => {
data.value.isModalVisible = false;
data.value.selectedData = null;
};
const handleTerminate = () => alert("Terminate 작업 진행중...");
const handleRetry = () => alert("Retry 작업 진행중...");
const handleClone = () => alert("Clone 작업 진행중...");
const getSelectedAllData = () => {
data.value.selected = data.value.allSelected
? data.value.results.map((item) => {
return {
deviceKey: item.deviceKey,
};
})
? data.value.results.map((x) => ({ deviceKey: x.deviceKey }))
: [];
};
onMounted(() => {
getData();
getCodeList();
// 1000
watch(
() => data.value.params.pageSize,
async (v) => {
if (v !== 1000) data.value.params.pageSize = 1000;
pageTokens.value = [""];
nextPageToken.value = undefined;
await getData(1);
},
);
/* 초기 로드 */
onMounted(async () => {
// 1)
await dumpAllRunsToConsole();
// 2) () getData(1)
// await getData(1);
});
</script>

@ -8,7 +8,7 @@ import IconInfoBtn from "@/components/atoms/button/IconInfoBtn.vue";
import ViewComponent from "@/components/templates/stepconfig/ViewComponent.vue";
import StapComfigDialog from "@/components/atoms/organisms/WorklfowStepBaseDialog.vue";
import { WorkflowStepService } from "@/components/service/management/workflowStepService";
import { WorkflowStepService } from "@/components/service/management/WorkflowStepService";
import type { WorkflowStep } from "@/components/models/management/WorkflowStep";
const store = commonStore();

@ -1,7 +1,7 @@
<script setup lang="ts">
import { defineProps, onMounted, watch, ref, computed } from "vue";
import { WorkflowStepService } from "@/components/service/management/workflowStepService";
import { WorkflowService } from "@/components/service/management/workflowService"; //
import { WorkflowStepService } from "@/components/service/management/WorkflowStepService";
import { WorkflowService } from "@/components/service/management/WorkflowService"; //
const props = defineProps<{ id: number | string }>();
const emit = defineEmits<{ (e: "close"): void }>();

@ -6,7 +6,7 @@ import { onMounted, ref } from "vue";
import { storage } from "@/utils/storage";
import ViewComponent from "@/components/templates/trainingscript/ViewComponent.vue";
import TrainingScriptBaseDoalog from "@/components/atoms/organisms/TrainingScriptBaseDoalog.vue";
import { AttachmentsService } from "@/components/service/management/attachmentsService";
import { AttachmentsService } from "@/components/service/management/AttachmentsService";
import { commonStore } from "@/stores/commonStore";
const store = commonStore();

@ -10,7 +10,7 @@ import {
} from "vue";
import * as monaco from "monaco-editor";
import "monaco-editor/min/vs/editor/editor.main.css";
import { AttachmentsService } from "@/components/service/management/attachmentsService";
import { AttachmentsService } from "@/components/service/management/AttachmentsService";
const props = defineProps<{ id: number | string }>();
const emit = defineEmits<{ (e: "close"): void }>();

@ -3,7 +3,7 @@ import { ref, onMounted, watch, computed } from "vue";
import { commonStore } from "@/stores/commonStore";
import { storage } from "@/utils/storage.js";
import { ProjectService } from "@/components/service/project/projectService";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";

@ -5,7 +5,7 @@ import utc from "dayjs/plugin/utc";
import tz from "dayjs/plugin/timezone";
import { commonStore } from "@/stores/commonStore";
import { WorkflowService } from "@/components/service/management/workflowService";
import { WorkflowService } from "@/components/service/management/WorkflowService";
import ViewComponent from "@/components/templates/workflow/ViewComponent.vue";
import WorkflowsBaseDialog from "@/components/atoms/organisms/WorkflowsBaseDialog.vue";

@ -2,7 +2,7 @@
import { onMounted, ref, watch, onBeforeUnmount } from "vue";
import * as monaco from "monaco-editor";
import "monaco-editor/min/vs/editor/editor.main.css";
import { WorkflowService } from "@/components/service/management/workflowService";
import { WorkflowService } from "@/components/service/management/WorkflowService";
type TabKey = "details" | "yaml";

@ -5,7 +5,7 @@ import { storage } from "@/utils/storage";
import logo from "@/assets/wordmark.png";
import logo2 from "@/assets/workflow.png";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
import { TokenService } from "@/components/service/token/tokenService";
const API_URL = import.meta.env.VITE_APP_API_SERVER_URL;
const router = useRouter();

@ -5,7 +5,7 @@ import { storage } from "@/utils/storage";
import logo from "@/assets/wordmark.png";
import logo2 from "@/assets/workflow.png";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
const router = useRouter();
const ROLE_ITEMS = ["ROLE_USER", "ROLE_MODERATOR", "ROLE_ADMIN"];

@ -8,7 +8,7 @@ import type {
Permission,
} from "@/components/models/project/Project";
import { ProjectService } from "@/components/service/project/projectService";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { UserManagerService } from "@/components/service/management/UserManagerService";
import { storage } from "@/utils/storage.js";
/** ===== 상수 & 기본 권한 ===== */

Loading…
Cancel
Save