Files
core/hwe/ts/components/CommandSelectForm.vue
T

135 lines
3.8 KiB
Vue

<template>
<teleport to="body">
<div v-if="showForm">
<div class="commandCategory">
<div
class="categoryItem"
v-for="[categoryKey, { deco: categoryDeco }] of commandList"
:key="categoryKey"
><BButton @click="chosenCategory=categoryKey">{{ categoryDeco.altName ?? categoryDeco.name }}</BButton></div>
</div>
<div class="commandList">
<div
class="commandItem"
v-for="commandItem of chosenSubList"
:key="commandItem.value"
@click="close(commandItem.value)"
>
{{ commandItem.simpleName }}
<br />
<small>{{ commandItem.title }}</small>
</div>
</div>
<div class="commandBottom">
<BButton @click="close()">닫기</BButton>
</div>
</div>
</teleport>
</template>
<script setup lang="ts">
/*
<template v-if="props.option.title">
<span class="compensatePositive" v-if="props.option.compensation > 0">▲</span>
<span class="compensateNegative" v-else-if="props.option.compensation < 0">▼</span>
<span class="compensateNeutral" v-else></span>
<span
:class="[props.option.possible ? '' : 'commandImpossible']"
>{{ props.option.title }}</span>
</template>
<template v-else-if="props.option.category">{{ props.option.category }}</template>
</template>
<template v-slot:singleLabel="props">{{ props.option.simpleName }}</template>
*/
import type { CommandItem } from "@/defs";
import { BButton } from "bootstrap-vue-3";
import { ref, defineProps, defineEmits, defineExpose, type PropType, watch } from "vue";
const chosenCategory = ref<string>("");
const chosenSubList = ref<CommandItem[]>([]);
interface CategoryDecoration {
name: string,
altName?: string,
//icon?: string,
//color?: string,
//backgroundColor?: string,
}
const props = defineProps({
categoryInfo: {
type: Object as PropType<Record<string, Omit<CategoryDecoration, 'name'>>>,
required: false,
},
commandList: {
type: Object as PropType<{
category: string;
values: CommandItem[];
}[]>,
required: true,
}
})
const showForm = ref(false);
function convCategoryDeco(category: string): CategoryDecoration {
const itemInfo = props.categoryInfo?.[category];
if (!itemInfo) {
return {
name: category,
}
}
return {
name: category,
...itemInfo
};
}
const commandList = ref(new Map<string, {
deco: CategoryDecoration,
values: CommandItem[],
}>());
function updateCommandList(rawCommandList: typeof props.commandList) {
commandList.value.clear();
for (const { category, values } of rawCommandList) {
commandList.value.set(category, {
deco: convCategoryDeco(category),
values
});
}
}
watch(() => props.commandList, updateCommandList);
updateCommandList(props.commandList);
watch(chosenCategory, (category) => {
console.log('sel', category);
const itemInfo = commandList.value?.get(category);
if (itemInfo === undefined) {
console.error(`category 없음: ${category}`);
return;
}
chosenSubList.value = itemInfo.values;
});
function show(): void {
showForm.value = true;
}
function close(category?: string): void {
showForm.value = false;
emits('onClose', category);
}
const emits = defineEmits<{
(event: 'onClose', command?: string): void,
}>();
defineExpose({
show,
close
})
</script>