feat: MenuItem에 funcCall 타입 추가후 처리
This commit is contained in:
@@ -7,54 +7,71 @@
|
||||
:variant="variant"
|
||||
:href="item.url"
|
||||
:target="item.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, item)"
|
||||
>{{ item.name }}</BButton
|
||||
>
|
||||
<template v-else-if="item.type === 'multi'">
|
||||
<BDropdown :variant="variant" :text="item.name" class="col">
|
||||
<BDropdown v-else-if="item.type === 'multi'" :variant="variant" :text="item.name" class="col">
|
||||
<template v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<template v-if="subItem.type === 'item'">
|
||||
<BDropdownItem
|
||||
:variant="variant"
|
||||
:href="subItem.url"
|
||||
:target="subItem.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, subItem)"
|
||||
>{{ subItem.name }}</BDropdownItem
|
||||
>
|
||||
</template>
|
||||
<BDropdownDivider v-else />
|
||||
</template>
|
||||
</BDropdown>
|
||||
<BDropdown
|
||||
v-else-if="item.type === 'split'"
|
||||
split
|
||||
class="col"
|
||||
:variant="variant"
|
||||
:text="item.main.name"
|
||||
:splitHref="item.main.url"
|
||||
@click="menuClick($event, item.main)"
|
||||
>
|
||||
<template v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<BDropdownItem
|
||||
v-for="(subItem, subIdx) in item.subMenu"
|
||||
:key="subIdx"
|
||||
v-if="subItem.type === 'item'"
|
||||
:variant="variant"
|
||||
:href="subItem.url"
|
||||
:target="subItem.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, subItem)"
|
||||
>{{ subItem.name }}</BDropdownItem
|
||||
>
|
||||
</BDropdown>
|
||||
</template>
|
||||
<template v-else-if="item.type === 'split'">
|
||||
<BDropdown
|
||||
split
|
||||
class="col"
|
||||
:variant="variant"
|
||||
:text="item.main.name"
|
||||
:splitHref="item.main.url"
|
||||
@click="splitClick(item.main)($event)"
|
||||
>
|
||||
<BDropdownItem
|
||||
v-for="(subItem, subIdx) in item.subMenu"
|
||||
:key="subIdx"
|
||||
:href="subItem.url"
|
||||
:target="subItem.newTab ? '_blank' : undefined"
|
||||
>{{ subItem.name }}</BDropdownItem
|
||||
>
|
||||
</BDropdown>
|
||||
</template>
|
||||
<BDropdownDivider v-else />
|
||||
</template>
|
||||
</BDropdown>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { GetFrontInfoResponse, GetMenuResponse, MenuItem, MenuMulti, MenuSplit } from "@/defs/API/Global";
|
||||
import { BButton, BDropdown, BDropdownItem, type ButtonVariant } from "bootstrap-vue-next";
|
||||
import type {
|
||||
GetFrontInfoResponse,
|
||||
GetMenuResponse,
|
||||
MenuItem,
|
||||
MenuLine,
|
||||
MenuMulti,
|
||||
MenuSplit,
|
||||
} from "@/defs/API/Global";
|
||||
import { BButton, BDropdown, BDropdownItem, BDropdownDivider, type ButtonVariant } from "bootstrap-vue-next";
|
||||
import { isArray } from "lodash-es";
|
||||
import { computed, toRef } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: GetMenuResponse["menu"];
|
||||
globalInfo: GetFrontInfoResponse["global"];
|
||||
variant: ButtonVariant | 'sammo-base2',
|
||||
mobileRowSize?: number,
|
||||
desktopRowSize?: number,
|
||||
variant: ButtonVariant | "sammo-base2";
|
||||
mobileRowSize?: number;
|
||||
desktopRowSize?: number;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "reqCall", value: string): void;
|
||||
}>();
|
||||
|
||||
const mobileRowSize = computed(() => {
|
||||
@@ -72,7 +89,7 @@ const variant = computed(() => {
|
||||
const modelValue = toRef(props, "modelValue");
|
||||
const globalInfo = toRef(props, "globalInfo");
|
||||
|
||||
type MenuVariant = MenuItem | MenuSplit | MenuMulti;
|
||||
type MenuVariant = MenuItem | MenuSplit | MenuMulti | MenuLine;
|
||||
|
||||
function filterMenu(menu: MenuVariant | MenuVariant[]): MenuVariant | MenuVariant[] | undefined {
|
||||
if (isArray(menu)) {
|
||||
@@ -122,15 +139,23 @@ function filterMenu(menu: MenuVariant | MenuVariant[]): MenuVariant | MenuVarian
|
||||
|
||||
const filteredMenu = computed(() => filterMenu(modelValue.value) as GetMenuResponse["menu"]);
|
||||
|
||||
function splitClick(menu: MenuItem) {
|
||||
return (e: Event) => {
|
||||
if (!menu.newTab) {
|
||||
return;
|
||||
}
|
||||
function menuClick(e: Event, menu: MenuItem) {
|
||||
if (menu.funcCall) {
|
||||
//TODO: CTRL+클릭도 대응해야하는지 고민이 필요함
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.open(menu.url);
|
||||
};
|
||||
emit("reqCall", menu.url);
|
||||
return;
|
||||
}
|
||||
if (!menu.url) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (!menu.newTab) {
|
||||
//자동 핸들러를 따름
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
window.open(menu.url);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
<ul class="dropdown-menu dropdown-menu-start">
|
||||
<template v-for="(item, idx) in filteredMenu" :key="idx">
|
||||
<li v-if="item.type === 'item'">
|
||||
<a class="dropdown-item" :href="item.url" :target="item.newTab ? '_blank' : undefined">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
:href="item.url"
|
||||
:target="item.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</a>
|
||||
</li>
|
||||
@@ -10,30 +15,57 @@
|
||||
<li :style="{ orphans: item.subMenu.length + 1 }">
|
||||
<span class="dropdown-item disabled">{{ item.name }}</span>
|
||||
</li>
|
||||
<li v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<a class="dropdown-item subItem" :href="subItem.url" :target="subItem.newTab ? '_blank' : undefined">{{
|
||||
subItem.name
|
||||
}}</a>
|
||||
</li>
|
||||
<template v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<li v-if="subItem.type === 'item'">
|
||||
<a
|
||||
class="dropdown-item subItem"
|
||||
:href="subItem.url"
|
||||
:target="subItem.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, subItem)"
|
||||
>{{ subItem.name }}</a
|
||||
>
|
||||
</li>
|
||||
<hr v-else class="dropdown-divider" />
|
||||
</template>
|
||||
<hr class="dropdown-divider" />
|
||||
</template>
|
||||
<template v-else-if="item.type === 'split'">
|
||||
<li :style="{ orphans: item.subMenu.length + 1 }">
|
||||
<a class="dropdown-item" :href="item.main.url" :target="item.main.newTab ? '_blank' : undefined">{{
|
||||
item.main.name
|
||||
}}</a>
|
||||
</li>
|
||||
<li v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<a class="dropdown-item subItem" :href="subItem.url" :target="subItem.newTab ? '_blank' : undefined">{{
|
||||
subItem.name
|
||||
}}</a>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
:href="item.main.url"
|
||||
:target="item.main.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, item.main)"
|
||||
>{{ item.main.name }}</a
|
||||
>
|
||||
</li>
|
||||
<template v-for="(subItem, subIdx) in item.subMenu" :key="subIdx">
|
||||
<li v-if="subItem.type === 'item'">
|
||||
<a
|
||||
class="dropdown-item subItem"
|
||||
:href="subItem.url"
|
||||
:target="subItem.newTab ? '_blank' : undefined"
|
||||
@click="menuClick($event, subItem)"
|
||||
>{{ subItem.name }}</a
|
||||
>
|
||||
</li>
|
||||
<hr v-else class="dropdown-divider" />
|
||||
</template>
|
||||
<hr class="dropdown-divider" />
|
||||
</template>
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { GetFrontInfoResponse, GetMenuResponse, MenuItem, MenuMulti, MenuSplit } from "@/defs/API/Global";
|
||||
import type {
|
||||
GetFrontInfoResponse,
|
||||
GetMenuResponse,
|
||||
MenuItem,
|
||||
MenuLine,
|
||||
MenuMulti,
|
||||
MenuSplit,
|
||||
} from "@/defs/API/Global";
|
||||
import { isArray } from "lodash-es";
|
||||
import { computed, toRef } from "vue";
|
||||
|
||||
@@ -45,6 +77,10 @@ const props = defineProps<{
|
||||
columns?: number;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "reqCall", value: string): void;
|
||||
}>();
|
||||
|
||||
const columns = computed(() => {
|
||||
return props.columns ?? 3;
|
||||
});
|
||||
@@ -52,7 +88,7 @@ const columns = computed(() => {
|
||||
const modelValue = toRef(props, "modelValue");
|
||||
const globalInfo = toRef(props, "globalInfo");
|
||||
|
||||
type MenuVariant = MenuItem | MenuSplit | MenuMulti;
|
||||
type MenuVariant = MenuItem | MenuSplit | MenuMulti | MenuLine;
|
||||
|
||||
function filterMenu(menu: MenuVariant | MenuVariant[]): MenuVariant | MenuVariant[] | undefined {
|
||||
if (isArray(menu)) {
|
||||
@@ -101,6 +137,25 @@ function filterMenu(menu: MenuVariant | MenuVariant[]): MenuVariant | MenuVarian
|
||||
}
|
||||
|
||||
const filteredMenu = computed(() => filterMenu(modelValue.value) as GetMenuResponse["menu"]);
|
||||
|
||||
function menuClick(e: Event, menu: MenuItem) {
|
||||
if (menu.funcCall) {
|
||||
//TODO: CTRL+클릭도 대응해야하는지 고민이 필요함
|
||||
e.preventDefault();
|
||||
emit("reqCall", menu.url);
|
||||
return;
|
||||
}
|
||||
if (!menu.url) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (!menu.newTab) {
|
||||
//자동 핸들러를 따름
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
window.open(menu.url);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user