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.
autoflow-web-console/src/components/common/LayoutComponent.vue

211 lines
5.2 KiB

<script setup>
import { useRoute, useRouter } from "vue-router";
import { storage } from "@/utils/storage.js";
import DrawerComponent from "@/components/common/DrawerComponent.vue";
import { ref, watchEffect } from "vue";
import Select from "@/views/Select.vue";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { storeToRefs } from "pinia";
import { useAutoflowStore } from "@/stores/autoflowStore";
const route = useRoute();
const router = useRouter();
const username = ref("");
const autoflow = useAutoflowStore();
const showPasswordModal = ref(false);
const selectedUserData = ref({});
const menu = ref([]);
const projectName = ref(localStorage.getItem("projectName") || "");
const updateUsername = () => {
// storage 구조: { userInfo: { username, ... }, ... } 라고 가정
const auth = storage.getAuth?.() ?? null;
username.value =
auth?.userInfo?.username ??
auth?.username ?? // 혹시 평문으로 저장한 경우
""; // 없으면 빈값
};
const menuItems = [
{
title: "Select Project",
click: () => {
goSelect();
},
},
{
title: "Change Password",
click: () => {
showPasswordModal.value = true;
},
},
{
title: "Logout",
icon: "mdi-logout",
click: () => {
logOut();
},
},
];
const userMenuItems = [
{
title: "Select Project",
},
{
title: "Change Password",
},
{
title: "Logout",
icon: "mdi-logout",
click: () => {
logOut();
},
},
];
const drawer = ref(null);
const pageTitle = computed(() => {
return route.meta.title;
});
const pagePath = computed(() => {
return route.path;
});
const refreshProjectName = () => {
const v = localStorage.getItem("projectName");
projectName.value = v ? v : "";
};
const goSelect = () => {
router.push("/select");
};
const logOut = () => {
UserManagerService.signOut()
.catch(console.error)
.finally(() => {
localStorage.removeItem("autoflow-auth");
localStorage.removeItem("projectName");
localStorage.removeItem("projectId");
username.value = "";
projectName.value = "";
sessionStorage.removeItem("initialRedirectDone");
router.push("/login");
});
};
onMounted(() => {
updateUsername();
refreshProjectName();
menu.value = menuItems;
// 다른 탭에서 projectName이 바뀌면 반영
window.addEventListener("storage", (e) => {
if (!e.key || e.key === "projectName") refreshProjectName();
if (!e.key || e.key === "autoflow-auth" || e.key === "auth")
updateUsername();
});
});
onMounted(() => {
updateUsername();
// 다른 탭/창에서 로그인 상태가 바뀔 때도 반영
window.addEventListener("storage", (e) => {
if (!e.key || e.key === "auth") updateUsername();
});
});
onBeforeUnmount(() => {
window.removeEventListener("storage", updateUsername);
});
watch(
() => route.fullPath,
() => refreshProjectName(),
);
watchEffect(() => {
// const auth = storage.getAuth().auth;
// if (auth === "ADMIN") {
menu.value = menuItems;
// } else {
// menu.value = userMenuItems;
// }
});
</script>
<template>
<v-app>
<v-navigation-drawer
v-model="drawer"
border="0"
hide-overlay
permanent
v-if="!route.meta.hideSidebar"
>
<DrawerComponent />
</v-navigation-drawer>
<v-app-bar class="bg-shades-transparent" flat>
<v-spacer></v-spacer>
<v-menu location="bottom end">
<template v-slot:activator="{ props }">
<v-tooltip location="bottom" text="Settings">
<template #activator="{ props }">
<v-btn icon color="primary" class="mr-3" v-bind="props">
<v-icon>mdi-cog</v-icon>
</v-btn>
</template>
</v-tooltip>
<v-tooltip location="bottom" text="Projact">
<template #activator="{ props }">
<v-btn
icon
color="primary"
class="mr-3"
@click="goSelect"
v-bind="props"
>
<v-icon>mdi-home</v-icon>
</v-btn>
</template>
</v-tooltip>
<div style="min-width: 180px" class="d-flex flex-column align-end">
<div class="font-weight-black">{{ username || "GUEST" }}</div>
<div class="text-subtitle-2">
{{ projectName || "No Project Selected" }}
</div>
</div>
<v-btn icon color="primary" v-bind="props" class="mr-3">
<v-icon>mdi-arrow-down-drop-circle-outline</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in menu"
:key="index"
:value="index"
@click="item.click"
:prepend-icon="item.icon"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app-bar>
<v-main>
<v-container
fluid
class="pa-16 background d-flex justify-center"
style="width: 100%"
>
<slot></slot>
</v-container>
</v-main>
</v-app>
</template>
<style scoped lang="sass"></style>