feat: 기능 완성

This commit is contained in:
2022-03-23 20:12:59 +09:00
parent cb53eef4a2
commit f1e2b5c960
3 changed files with 179 additions and 30 deletions
+116 -16
View File
@@ -3,20 +3,28 @@
<div class="col alert alert-dark m-0 p-1 center">
<h4 class="m-0">명령 목록</h4>
</div>
<div class="row gx-0 commandSelectFormAnchor">
<div class="col-3 d-grid">
<BButton variant="primary">편집</BButton>
</div>
<div class="col-6 d-grid">
<BButton variant="light" @click="toggleForm($event)" :style="{color: 'black'}">{{ selectedCommand.simpleName }} </BButton>
</div>
<div class="col-3 d-grid">
<BButton @click="reserveCommand()" variant="primary">실행</BButton>
<div class="commandSelectFormAnchor">
<div v-if="isEditMode" class="row gx-0">
<div class="col-3 d-grid">
<BButton variant="warning" @click="isEditMode = !isEditMode">취소</BButton>
</div>
<div class="col-6 d-grid">
<BButton
variant="light"
@click="toggleForm($event)"
:style="{ color: 'black' }"
>{{ selectedCommand.simpleName }} </BButton>
</div>
<div class="col-3 d-grid">
<BButton @click="reserveCommand()" variant="primary">실행</BButton>
</div>
</div>
</div>
<div class="row gx-1">
<div class="col d-grid">
<BDropdown left text="턴 선택">
<BButton v-if="!isEditMode" variant="secondary" @click="isEditMode = !isEditMode">고급 모드</BButton>
<BDropdown v-else left text="턴 선택">
<BDropdownItem @click="selectTurn()">해제</BDropdownItem>
<BDropdownItem @click="selectAll(true)">모든턴</BDropdownItem>
<BDropdownItem @click="selectStep(0, 2)">홀수턴</BDropdownItem>
@@ -57,9 +65,24 @@
</div>
</div>
<div class="commandTable">
<div :style="{ position: 'relative' }">
<div
class="commandQuickReserveFormAnchor bg-dark"
:style="{
position: 'absolute',
top: `${29.4 * currentQuickReserveTarget + 30}px`,
width: '100%',
zIndex: 9,
}"
></div>
</div>
<div :class="{
commandTable: true,
isEditMode,
}">
<DragSelect
:style="rowGridStyle"
:disabled="!isEditMode"
attribute="turnIdx"
@dragStart="isDragToggle = true"
@dragDone="
@@ -78,6 +101,7 @@ toggleTurn(...$event);
class="idx_pad center d-grid"
>
<BButton
v-if="isEditMode"
size="sm"
:variant="
(isDragToggle && selected.has(`${turnIdx}`)) ? 'light' :
@@ -88,11 +112,13 @@ toggleTurn(...$event);
: 'primary'
"
>{{ turnIdx + 1 }}</BButton>
<div v-else class="plain-center">{{ turnIdx + 1 }}</div>
</div>
</DragSelect>
<DragSelect
:style="rowGridStyle"
attribute="turnIdx"
:disabled="!isEditMode"
@dragStart="isDragSingle = true"
@dragDone="
isDragSingle = false;
@@ -158,10 +184,27 @@ selectTurn(...$event);
></span>
</div>
</div>
<div v-if="!isEditMode" :style="rowGridStyle">
<div
v-for="(turnObj, turnIdx) in reservedCommandList.slice(
0,
viewMaxTurn
)"
:key="turnIdx"
class="action_pad d-grid"
>
<BButton
:variant="(turnIdx % 2 == 0) ? 'secondary' : 'dark'"
size="sm"
class="simple_action_btn bi bi-pencil"
@click="toggleQuickReserveForm(turnIdx)"
></BButton>
</div>
</div>
</div>
<div class="row gx-1">
<div class="col d-grid">
<BDropdown right split text="당기기" @click="pullGeneralCommandSingle">
<BDropdown text="당기기">
<BDropdownItem
v-for="turnIdx in maxPushTurn"
:key="turnIdx"
@@ -170,7 +213,7 @@ selectTurn(...$event);
</BDropdown>
</div>
<div class="col d-grid">
<BDropdown right split text="미루기" @click="pushGeneralCommandSingle">
<BDropdown text="미루기">
<BDropdownItem
v-for="turnIdx in maxPushTurn"
:key="turnIdx"
@@ -193,6 +236,13 @@ selectTurn(...$event);
ref="commandSelectForm"
@on-close="chooseCommand($event)"
/>
<CommandSelectForm
:commandList="commandList"
anchor=".commandQuickReserveFormAnchor"
ref="commandQuickReserveForm"
@on-close="chooseQuickReserveCommand($event)"
:hideClose="false"
/>
</template>
<script lang="ts">
@@ -276,11 +326,11 @@ for (const commandCategories of commandList) {
}
}
function toggleForm($event: Event): void{
function toggleForm($event: Event): void {
$event.preventDefault();
const form = commandSelectForm.value;
if(!form){
if (!form) {
return;
}
form.toggle();
@@ -323,6 +373,7 @@ const emptyTurn: TurnObjWithTime[] = Array.from<TurnObjWithTime>({
const prevTurnList = ref(new Set([0]));
const turnList = ref(new Set<number>());
const reservedCommandList = ref(emptyTurn);
const isEditMode = ref(false);
const flippedMaxTurn = 15;
const viewMaxTurn = ref(flippedMaxTurn);
@@ -431,6 +482,7 @@ async function pushGeneralCommand(amount: number) {
await reloadCommandList();
}
/*
function pushGeneralCommandSingle(e: Event) {
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
if (isDropdownChildren(e)) {
@@ -446,6 +498,7 @@ function pullGeneralCommandSingle(e: Event) {
}
void pushGeneralCommand(-1);
}
*/
async function reloadCommandList() {
let result: ReservedCommandResponse;
@@ -561,10 +614,42 @@ function chooseCommand(val?: string) {
selectedCommand.value = invCommandMap[val];
}
const commandQuickReserveForm = ref<InstanceType<typeof CommandSelectForm> | null>(null);
const currentQuickReserveTarget = ref(-1);
function chooseQuickReserveCommand(val?: string) {
if (!val) {
return;
}
selectedCommand.value = invCommandMap[val];
turnList.value.clear();
turnList.value.add(currentQuickReserveTarget.value);
void reserveCommand();
}
function toggleQuickReserveForm(turnIdx: number) {
if (turnIdx == currentQuickReserveTarget.value) {
commandQuickReserveForm.value?.toggle();
return;
}
currentQuickReserveTarget.value = turnIdx;
commandQuickReserveForm.value?.show();
}
onMounted(() => {
void reloadCommandList();
});
watch(isEditMode, newEditMode => {
if (newEditMode) {
commandQuickReserveForm.value?.close();
currentQuickReserveTarget.value = -1;
}
else {
commandSelectForm.value?.close();
}
});
</script>
<style lang="scss">
@use "sass:color";
@@ -576,9 +661,19 @@ onMounted(() => {
.commandPad {
background-color: $gray-900;
position: relative;
}
.commandTable {
width: 100%;
display: grid;
grid-template-columns:
minmax(20px, 0.8fr) minmax(75px, 2.4fr) minmax(40px, 0.9fr)
4.8fr minmax(28px, 0.8fr);
//30, 70, 37.65, 160
}
.commandTable.isEditMode {
width: 100%;
display: grid;
grid-template-columns: minmax(30px, 1fr) minmax(75px, 2.5fr) minmax(40px, 1fr) 5fr;
@@ -628,11 +723,16 @@ onMounted(() => {
}
}
.month_pad:hover {
.isEditMode .month_pad:hover {
text-decoration: underline;
cursor: pointer;
}
.plain-center {
background-color: black;
}
.plain-center,
.month_pad,
.time_pad,
.turn_pad {
+18 -3
View File
@@ -22,7 +22,17 @@
@click="close(commandItem.value)"
>
<div class="commandItem">
<p class="center my-0">{{ commandItem.simpleName }}</p>
<p :class="['center', 'my-0', commandItem.possible ? '' : 'commandImpossible']">
{{ commandItem.simpleName }}
<span
class="compensatePositive"
v-if="commandItem.compensation > 0"
></span>
<span
class="compensateNegative"
v-else-if="commandItem.compensation < 0"
></span>
</p>
<small class="center" :style="{ display: 'block' }">
{{
commandItem.title.startsWith(commandItem.simpleName)
@@ -33,11 +43,11 @@
</div>
</div>
</div>
<!--<div class="commandBottom row mt-1 mb-1">
<div v-if="!hideClose" class="commandBottom row mt-1 mb-1">
<div class="offset-8 col-4 d-grid">
<BButton @click="close()">닫기</BButton>
</div>
</div>-->
</div>
</div>
</teleport>
</template>
@@ -86,6 +96,11 @@ const props = defineProps({
type: String,
required: false,
default: '.commandSelectFormAnchor',
},
hideClose: {
type: Boolean,
required: false,
default: true,
}
})
+45 -11
View File
@@ -1,12 +1,14 @@
<template>
<div
ref="container"
style="
position: relative;
user-select: none;
overflow: hidden;
touch-action: none;
:style="{
position: 'relative',
userSelect: disabled ? undefined : 'none',
overflow: 'hidden',
touchAction: disabled ? undefined : 'none',
}
"
:class="{ disabledDrag: disabled }"
>
<slot :selected="intersected" />
</div>
@@ -58,6 +60,11 @@ export default defineComponent({
required: false,
default: () => ref(new Set()),
},
disabled: {
type: Boolean,
required: false,
default: false,
}
},
emits: ["update:modelValue", "dragDone", "dragStart"],
setup(props, { emit }) {
@@ -138,6 +145,9 @@ export default defineComponent({
let isMine = false;
function startDrag(e: MouseEvent | Touch) {
if (props.disabled) {
return;
}
containerRect = uContainer.getBoundingClientRect();
children = uContainer.children;
start = getCoords(e);
@@ -152,6 +162,9 @@ export default defineComponent({
emit("dragStart");
}
function drag(e: MouseEvent | Touch) {
if (props.disabled) {
return;
}
end = getCoords(e);
const dimensions = getDimensions(start, end);
if (end.x < start.x) {
@@ -165,6 +178,9 @@ export default defineComponent({
intersection();
}
function endDrag() {
if (props.disabled) {
return;
}
start = { x: 0, y: 0 };
end = { x: 0, y: 0 };
box.style.width = "0";
@@ -172,16 +188,34 @@ export default defineComponent({
document.removeEventListener("mousemove", drag);
document.removeEventListener("touchmove", touchMove);
box.remove();
if(isMine){
emit("dragDone", intersected.value);
if (isMine) {
emit("dragDone", intersected.value);
}
isMine = false;
}
uContainer.addEventListener("mousedown", startDrag);
uContainer.addEventListener("touchstart", touchStart);
document.addEventListener("mouseup", endDrag);
document.addEventListener("touchend", endDrag);
watch(() => props.disabled, disabledNext => {
if (disabledNext) {
uContainer.removeEventListener("mousedown", startDrag);
uContainer.removeEventListener("touchstart", touchStart);
document.removeEventListener("mouseup", endDrag);
document.removeEventListener("touchend", endDrag);
}
else {
uContainer.addEventListener("mousedown", startDrag);
uContainer.addEventListener("touchstart", touchStart);
document.addEventListener("mouseup", endDrag);
document.addEventListener("touchend", endDrag);
}
});
if (!props.disabled) {
uContainer.addEventListener("mousedown", startDrag);
uContainer.addEventListener("touchstart", touchStart);
document.addEventListener("mouseup", endDrag);
document.addEventListener("touchend", endDrag);
}
onBeforeUnmount(() => {
uContainer.removeEventListener("mousedown", startDrag);