New runner #49
@@ -41,12 +41,11 @@ useEventListener('keyup', e => {
|
||||
|
||||
<template>
|
||||
<div ref="root" class="dropdown" :class="{'dropdown-open': isOpen, 'dropdown-close': !isOpen}" v-on-click-outside="[doAutoClose, { ignore: [floating] }]">
|
||||
<button @click="isOpen = !isOpen" class="cursor-pointer">
|
||||
<button @click="isOpen = !isOpen" class="flex items-center cursor-pointer border-none bg-transparent hover:bg-transparent p-0">
|
||||
<Transition
|
||||
mode="out-in"
|
||||
enter-active-class="transition-transform"
|
||||
enter-from-class="rotate-180"
|
||||
leave-active-class="hidden"
|
||||
leave-to-class="rotate-180">
|
||||
enter-from-class="rotate-180">
|
||||
<ChevronDownIcon v-if="!isOpen" class="chevron" />
|
||||
<ChevronUpIcon v-else class="chevron" />
|
||||
</Transition>
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, ref, watchEffect} from "vue";
|
||||
import {computedAsync, useEventListener} from "@vueuse/core";
|
||||
import {useEventListener} from "@vueuse/core";
|
||||
import log from "loglevel";
|
||||
import {ScriptEditor, useRuleBookStore} from "@/rules";
|
||||
import {PlusIcon, TrashIcon} from "@heroicons/vue/24/outline";
|
||||
import {Dropdown} from "@/components";
|
||||
import {isMain, Ledger, LedgerSelect, systemLedger, useLedgersStore} from "@/ledger";
|
||||
import {useCharactersStore} from "@/characters";
|
||||
import {CorporationLabel, useCorporationsStore} from "@/corporations";
|
||||
import {RuleScriptRequest} from "@/generated/mammon";
|
||||
import {toast} from "@/toast";
|
||||
import {confirm} from "@/confirm";
|
||||
|
||||
type LedgerScopeEntry = { ref: string; ledger: Ledger };
|
||||
type CharacterScopeEntry = { ref: string; characterId: number };
|
||||
@@ -33,6 +35,11 @@ const ledgersToUse = computed(() => [systemLedger, ...ledgersStore.ledgers.filte
|
||||
|
||||
const scripts = ref<ScriptDraft[]>([]);
|
||||
const selectedIndex = ref(0);
|
||||
const scopesExpanded = ref(true);
|
||||
const ledgersExpanded = ref(true);
|
||||
const charactersExpanded = ref(true);
|
||||
const corporationsExpanded = ref(true);
|
||||
const walletDivisionsExpanded = ref(true);
|
||||
const selected = computed<ScriptDraft | undefined>(() => scripts.value[selectedIndex.value]);
|
||||
|
||||
watchEffect(() => {
|
||||
@@ -71,7 +78,13 @@ const addScript = () => {
|
||||
selectedIndex.value = scripts.value.length - 1;
|
||||
};
|
||||
|
||||
const removeScript = (index: number) => {
|
||||
const removeScript = async (index: number) => {
|
||||
const script = scripts.value[index];
|
||||
|
||||
if (script?.script.trim() && !await confirm({message: `Delete script "${script.name || '(unnamed)'}"? It still has content.`, danger: true})) {
|
||||
return;
|
||||
}
|
||||
|
||||
scripts.value = scripts.value.toSpliced(index, 1);
|
||||
if (selectedIndex.value >= scripts.value.length) {
|
||||
selectedIndex.value = Math.max(0, scripts.value.length - 1);
|
||||
@@ -90,7 +103,18 @@ const removeCorporationScope = (index: number) => { if (selected.value) selected
|
||||
const addWalletDivisionScope = () => selected.value?.walletDivisions.push({ref: '', corporationId: 0, division: 1});
|
||||
const removeWalletDivisionScope = (index: number) => { if (selected.value) selected.value.walletDivisions = selected.value.walletDivisions.toSpliced(index, 1); };
|
||||
|
||||
const resolvedCorporation = (corporationId: number) => computedAsync(async () => corporationId ? await corporationsStore.findById(corporationId) : undefined, undefined);
|
||||
watchEffect(() => {
|
||||
const corporationIds = new Set([
|
||||
...(selected.value?.corporations.map(entry => entry.corporationId) ?? []),
|
||||
...(selected.value?.walletDivisions.map(entry => entry.corporationId) ?? []),
|
||||
]);
|
||||
|
||||
for (const corporationId of corporationIds) {
|
||||
if (corporationId) {
|
||||
corporationsStore.findById(corporationId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const save = () => ruleBookStore.update(
|
||||
scripts.value
|
||||
@@ -117,29 +141,29 @@ useEventListener(window, 'keydown', (event: KeyboardEvent) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex mb-2 mt-4 h-[calc(100vh-4.5rem)]">
|
||||
<div class="flex mb-2 mt-4 h-[calc(100vh-1.5rem)]">
|
||||
<div class="flex flex-col me-4 w-48 shrink-0">
|
||||
<div class="grow overflow-y-auto">
|
||||
<div v-for="(script, index) in scripts" :key="index"
|
||||
class="flex items-center mb-1 px-1 py-0.5 cursor-pointer"
|
||||
:class="{'bg-neutral-700': index === selectedIndex}"
|
||||
class="flex items-center mb-1 px-1 py-0.5 border-l-4 cursor-pointer"
|
||||
:class="index === selectedIndex ? 'border-emerald-500' : 'border-transparent'"
|
||||
@click="selectedIndex = index">
|
||||
<span class="grow truncate">{{ script.name || '(unnamed)' }}</span>
|
||||
<button class="btn-icon text-amber-700 hover:text-amber-600" @click.stop="removeScript(index)"><TrashIcon /></button>
|
||||
</div>
|
||||
<button class="btn-icon flex items-center" @click="addScript"><PlusIcon /> Add script</button>
|
||||
</div>
|
||||
<button class="btn-icon mt-2" @click="addScript"><PlusIcon /> Add script</button>
|
||||
</div>
|
||||
|
||||
<div v-if="selected" class="flex flex-col grow min-h-0">
|
||||
<div class="border-b-1 mb-2">
|
||||
<div class="border-b-1 mb-2 pb-2">
|
||||
Name: <input class="me-1" type="text" v-model="selected.name" />
|
||||
</div>
|
||||
|
||||
<div class="border-b-1">
|
||||
Scopes:
|
||||
<div class="ms-4 mt-2">
|
||||
Ledgers:
|
||||
<Dropdown inline :auto-close="false" v-model:open="scopesExpanded" class="mb-2">
|
||||
<template #button>Scopes</template>
|
||||
<Dropdown inline :auto-close="false" v-model:open="ledgersExpanded" class="ms-4 mt-2">
|
||||
<template #button>Ledgers</template>
|
||||
<div class="flex flex-wrap items-center mt-2">
|
||||
<div class="flex items-center mb-2 me-2" v-for="(entry, index) in selected.ledgers" :key="index">
|
||||
<input class="me-1" type="text" v-model="entry.ref" />
|
||||
@@ -151,10 +175,10 @@ useEventListener(window, 'keydown', (event: KeyboardEvent) => {
|
||||
<button class="btn-icon" @click="addLedgerScope"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<div class="ms-4 mt-2">
|
||||
Characters:
|
||||
<Dropdown inline :auto-close="false" v-model:open="charactersExpanded" class="ms-4 mt-2">
|
||||
<template #button>Characters</template>
|
||||
<div class="flex flex-wrap items-center mt-2">
|
||||
<div class="flex items-center mb-2 me-2" v-for="(entry, index) in selected.characters" :key="index">
|
||||
<input class="me-1" type="text" v-model="entry.ref" />
|
||||
@@ -168,55 +192,53 @@ useEventListener(window, 'keydown', (event: KeyboardEvent) => {
|
||||
<button class="btn-icon" @click="addCharacterScope"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<div class="ms-4 mt-2">
|
||||
Corporations:
|
||||
<Dropdown inline :auto-close="false" v-model:open="corporationsExpanded" class="ms-4 mt-2">
|
||||
<template #button>Corporations</template>
|
||||
<div class="flex flex-wrap items-center mt-2">
|
||||
<div class="flex items-center mb-2 me-2" v-for="(entry, index) in selected.corporations" :key="index">
|
||||
<input class="me-1" type="text" v-model="entry.ref" />
|
||||
<span class="me-1">:</span>
|
||||
<input class="me-1 w-32" type="number" v-model.number="entry.corporationId" placeholder="Corporation ID" />
|
||||
<CorporationLabel class="me-1" :corporation-id="entry.corporationId" :corporation="resolvedCorporation(entry.corporationId).value" :size="16" v-if="entry.corporationId" />
|
||||
<CorporationLabel class="me-1" :corporation-id="entry.corporationId" :corporation="corporationsStore.corporations[entry.corporationId]" :size="16" v-if="entry.corporationId" />
|
||||
<button class="btn-icon text-amber-700 hover:text-amber-600" @click="removeCorporationScope(index)"><TrashIcon /></button>
|
||||
</div>
|
||||
<div class="flex items-center mb-2">
|
||||
<button class="btn-icon" @click="addCorporationScope"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<div class="ms-4 mt-2 mb-2">
|
||||
Wallet Divisions:
|
||||
<Dropdown inline :auto-close="false" v-model:open="walletDivisionsExpanded" class="ms-4 mt-2 mb-2">
|
||||
<template #button>Wallet Divisions</template>
|
||||
<div class="flex flex-wrap items-center mt-2">
|
||||
<div class="flex items-center mb-2 me-2" v-for="(entry, index) in selected.walletDivisions" :key="index">
|
||||
<input class="me-1" type="text" v-model="entry.ref" />
|
||||
<span class="me-1">:</span>
|
||||
<input class="me-1 w-32" type="number" v-model.number="entry.corporationId" placeholder="Corporation ID" />
|
||||
<input class="me-1 w-16" type="number" min="1" max="7" v-model.number="entry.division" placeholder="Division" />
|
||||
<CorporationLabel class="me-1" :corporation-id="entry.corporationId" :corporation="resolvedCorporation(entry.corporationId).value" :division="entry.division" :size="16" v-if="entry.corporationId" />
|
||||
<CorporationLabel class="me-1" :corporation-id="entry.corporationId" :corporation="corporationsStore.corporations[entry.corporationId]" :division="entry.division" :size="16" v-if="entry.corporationId" />
|
||||
<button class="btn-icon text-amber-700 hover:text-amber-600" @click="removeWalletDivisionScope(index)"><TrashIcon /></button>
|
||||
</div>
|
||||
<div class="flex items-center mb-2">
|
||||
<button class="btn-icon" @click="addWalletDivisionScope"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</Dropdown>
|
||||
|
||||
<div class="flex flex-col grow min-h-0 border-b-1">
|
||||
Script:
|
||||
<ScriptEditor class="mt-2 mb-2" v-model="scriptText" :scope="editorScope" />
|
||||
</div>
|
||||
|
||||
<div class="mt-2 justify-end flex">
|
||||
<button @click="save">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex grow items-center justify-center text-neutral-500">
|
||||
No scripts yet
|
||||
</div>
|
||||
|
||||
<div class="mt-2 justify-end flex" v-if="selected">
|
||||
<div>
|
||||
<button @click="save">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user