Compare commits
2 Commits
9acbc101e1
...
676ff961ed
| Author | SHA1 | Date | |
|---|---|---|---|
| 676ff961ed | |||
| b40b58f866 |
@@ -79,15 +79,15 @@ export type MainLedgerResponseTypeEnum = typeof MainLedgerResponseTypeEnum[keyof
|
||||
|
||||
export interface RuleBookResponse {
|
||||
'characterId': number;
|
||||
'ruleSets': { [key: string]: RuleSetResponse; };
|
||||
'rules': { [key: string]: RuleResponse; };
|
||||
}
|
||||
export interface RuleResponse {
|
||||
'rate': RuleResponseRateEnum;
|
||||
export interface RuleClauseResponse {
|
||||
'rate': RuleClauseResponseRateEnum;
|
||||
'fromLedgerId'?: string;
|
||||
'toLedgerId'?: string;
|
||||
}
|
||||
|
||||
export const RuleResponseRateEnum = {
|
||||
export const RuleClauseResponseRateEnum = {
|
||||
None: 'NONE',
|
||||
Value: 'VALUE',
|
||||
JitaBuy: 'JITA_BUY',
|
||||
@@ -95,13 +95,13 @@ export const RuleResponseRateEnum = {
|
||||
EveEstimate: 'EVE_ESTIMATE',
|
||||
} as const;
|
||||
|
||||
export type RuleResponseRateEnum = typeof RuleResponseRateEnum[keyof typeof RuleResponseRateEnum];
|
||||
export type RuleClauseResponseRateEnum = typeof RuleClauseResponseRateEnum[keyof typeof RuleClauseResponseRateEnum];
|
||||
|
||||
export interface RuleSetResponse {
|
||||
'rules': Array<RuleResponse>;
|
||||
export interface RuleResponse {
|
||||
'rules': Array<RuleClauseResponse>;
|
||||
}
|
||||
export interface SetCharacterRuleBookRequest {
|
||||
'ruleSets': { [key: string]: RuleSetResponse; };
|
||||
'rules': { [key: string]: RuleResponse; };
|
||||
}
|
||||
export interface UpdateCombinedLedgerRequest {
|
||||
'name': string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Character, CharacterLabel, useCharactersStore} from "@/characters";
|
||||
import {useRoute} from "vue-router";
|
||||
import {ref, watch, watchEffect} from "vue";
|
||||
import log from "loglevel";
|
||||
import {activityTypes, findByCharacterId, RuleBook, RuleSetInput, setCharacterRuleBook} from "@/rules";
|
||||
import {activityTypes, findByCharacterId, RuleBook, RuleInput, setCharacterRuleBook} from "@/rules";
|
||||
|
||||
const {findById: findCharacterById} = useCharactersStore();
|
||||
const character = ref<Character>();
|
||||
@@ -50,7 +50,7 @@ watch(useRoute(), async route => {
|
||||
<div v-if="ruleBook" class="flex-col">
|
||||
<div class="flex-col grow border-b-1" v-for="activityType in activityTypes" :key="activityType.key">
|
||||
<span>{{ activityType.name }}</span>
|
||||
<RuleSetInput v-model="ruleBook.ruleSets[activityType.key]" />
|
||||
<RuleInput v-model="ruleBook.rules[activityType.key]" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {RuleClauseResponse} from "@/generated/mammon";
|
||||
import {computed} from "vue";
|
||||
import {isMain, Ledger, LedgerSelect, systemLedger, useLedgersStore} from "@/ledger";
|
||||
import {ratesTypes} from "@/rules/rules.ts";
|
||||
|
||||
const rule = defineModel<RuleClauseResponse>();
|
||||
|
||||
const ledgersStore = useLedgersStore();
|
||||
const {findById} = ledgersStore;
|
||||
const ledgers = computed<Ledger[]>(() => [systemLedger, ...ledgersStore.ledgers.filter(isMain)]);
|
||||
|
||||
const ledgerComputed = (key: 'fromLedgerId' | 'toLedgerId') => computed<Ledger>({
|
||||
get: () => rule.value && rule.value[key] ? findById(rule.value[key]) ?? systemLedger : systemLedger,
|
||||
set: value => {
|
||||
if (value) {
|
||||
rule.value = {...rule.value, [key]: value.ledgerId.length ? value.ledgerId : undefined}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fromLedger = ledgerComputed('fromLedgerId')
|
||||
const toLedger = ledgerComputed('toLedgerId')
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
From:
|
||||
<LedgerSelect class="me-2 grow" v-model="fromLedger" :ledgers="ledgers" />
|
||||
To:
|
||||
<LedgerSelect class="me-2 grow" v-model="toLedger" :ledgers="ledgers" />
|
||||
At:
|
||||
<select class="me-2 grow" v-model="rule.rate">
|
||||
<option v-for="rateType in ratesTypes" :key="rateType.key" :value="rateType.key">{{ rateType.name }}</option>
|
||||
</select>
|
||||
</template>
|
||||
+55
-27
@@ -1,37 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {RuleResponse} from "@/generated/mammon";
|
||||
import {computed} from "vue";
|
||||
import {isMain, Ledger, LedgerSelect, systemLedger, useLedgersStore} from "@/ledger";
|
||||
import {ratesTypes} from "@/rules/rules.ts";
|
||||
import {RuleClauseResponse, RuleClauseResponseRateEnum, RuleResponse} from "@/generated/mammon";
|
||||
import RuleClauseInput from "@/rules/RuleClauseInput.vue";
|
||||
import {computed, useTemplateRef} from "vue";
|
||||
import {Bars4Icon, PlusIcon, TrashIcon} from '@heroicons/vue/24/outline';
|
||||
import {useSortable} from "@vueuse/integrations/useSortable";
|
||||
|
||||
const rule = defineModel<RuleResponse>();
|
||||
|
||||
const ledgersStore = useLedgersStore();
|
||||
const {findById} = ledgersStore;
|
||||
const ledgers = computed<Ledger[]>(() => [systemLedger, ...ledgersStore.ledgers.filter(isMain)]);
|
||||
|
||||
const ledgerComputed = (key: 'fromLedgerId' | 'toLedgerId') => computed<Ledger>({
|
||||
get: () => rule.value && rule.value[key] ? findById(rule.value[key]) ?? systemLedger : systemLedger,
|
||||
set: value => {
|
||||
if (value) {
|
||||
rule.value = {...rule.value, [key]: value.ledgerId.length ? value.ledgerId : undefined}
|
||||
}
|
||||
}
|
||||
const rules = computed<RuleClauseResponse[]>({
|
||||
get: () => rule.value && rule.value.rules ? rule.value.rules : [],
|
||||
set: value => rule.value = {rules: value}
|
||||
})
|
||||
|
||||
const fromLedger = ledgerComputed('fromLedgerId')
|
||||
const toLedger = ledgerComputed('toLedgerId')
|
||||
const addRule = () => {
|
||||
rules.value = [...rules.value, {rate: RuleClauseResponseRateEnum.None}]
|
||||
}
|
||||
|
||||
const setRule = (index: number, rule?: RuleClauseResponse) => {
|
||||
if (!rule) {
|
||||
return;
|
||||
}
|
||||
rules.value = rules.value.with(index, rule)
|
||||
}
|
||||
|
||||
const removeRule = (index: number) => {
|
||||
rules.value = rules.value.toSpliced(index, 1)
|
||||
}
|
||||
|
||||
const sortableContainer = useTemplateRef('sortable-container')
|
||||
useSortable(sortableContainer, rules, { handle: '.sortable-handle'});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
From:
|
||||
<LedgerSelect class="me-2 grow" v-model="fromLedger" :ledgers="ledgers" />
|
||||
To:
|
||||
<LedgerSelect class="me-2 grow" v-model="toLedger" :ledgers="ledgers" />
|
||||
At:
|
||||
<select class="me-2 grow" v-model="rule.rate">
|
||||
<option v-for="rateType in ratesTypes" :key="rateType.key" :value="rateType.key">{{ rateType.name }}</option>
|
||||
</select>
|
||||
</template>
|
||||
<div class="flex-col">
|
||||
<div ref="sortable-container" class="flex-col">
|
||||
<div class="flex items-end gap-2 mt-2" v-for="(rule, index) in rules" :key="index">
|
||||
<span class="sortable-handle flex">
|
||||
<Bars4Icon class="w-6"/>
|
||||
</span>
|
||||
<RuleClauseInput :modelValue="rule" @update:modelValue="v => setRule(index, v)" />
|
||||
<button class="btn-icon" @click="removeRule(index)"><TrashIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end mb-2 mt-2">
|
||||
<button class="btn-icon" @click="addRule"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.sortable-handle {
|
||||
@apply cursor-grab;
|
||||
}
|
||||
|
||||
.sortable-chosen {
|
||||
@apply cursor-grabbing;
|
||||
}
|
||||
|
||||
.sortable-chosen .sortable-handle {
|
||||
@apply cursor-grabbing;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,65 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {RuleResponse, RuleResponseRateEnum, RuleSetResponse} from "@/generated/mammon";
|
||||
import RuleInput from "@/rules/RuleInput.vue";
|
||||
import {computed, useTemplateRef} from "vue";
|
||||
import {Bars4Icon, PlusIcon, TrashIcon} from '@heroicons/vue/24/outline';
|
||||
import {useSortable} from "@vueuse/integrations/useSortable";
|
||||
|
||||
const ruleSet = defineModel<RuleSetResponse>();
|
||||
const rules = computed<RuleResponse[]>({
|
||||
get: () => ruleSet.value && ruleSet.value.rules ? ruleSet.value.rules : [],
|
||||
set: value => ruleSet.value = {rules: value}
|
||||
})
|
||||
|
||||
const addRule = () => {
|
||||
rules.value = [...rules.value, {rate: RuleResponseRateEnum.None}]
|
||||
}
|
||||
|
||||
const setRule = (index: number, rule?: RuleResponse) => {
|
||||
if (!rule) {
|
||||
return;
|
||||
}
|
||||
rules.value = rules.value.with(index, rule)
|
||||
}
|
||||
|
||||
const removeRule = (index: number) => {
|
||||
rules.value = rules.value.toSpliced(index, 1)
|
||||
}
|
||||
|
||||
const sortableContainer = useTemplateRef('sortable-container')
|
||||
useSortable(sortableContainer, rules, { handle: '.sortable-handle'});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-col">
|
||||
<div ref="sortable-container" class="flex-col">
|
||||
<div class="flex items-end gap-2 mt-2" v-for="(rule, index) in rules" :key="index">
|
||||
<span class="sortable-handle flex">
|
||||
<Bars4Icon class="w-6"/>
|
||||
</span>
|
||||
<RuleInput :modelValue="rule" @update:modelValue="v => setRule(index, v)" />
|
||||
<button class="btn-icon" @click="removeRule(index)"><TrashIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end mb-2 mt-2">
|
||||
<button class="btn-icon" @click="addRule"><PlusIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.sortable-handle {
|
||||
@apply cursor-grab;
|
||||
}
|
||||
|
||||
.sortable-chosen {
|
||||
@apply cursor-grabbing;
|
||||
}
|
||||
|
||||
.sortable-chosen .sortable-handle {
|
||||
@apply cursor-grabbing;
|
||||
}
|
||||
|
||||
</style>
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
export * from "./rules";
|
||||
|
||||
export {default as RuleSetInput} from './RuleSetInput.vue';
|
||||
export {default as RuleInput} from './RuleInput.vue';
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
import {ruleBookControllerApi} from "@/mammon";
|
||||
import {RuleBookResponse, RuleResponseRateEnum, RuleSetResponse} from "@/generated/mammon";
|
||||
import {RuleBookResponse, RuleClauseResponseRateEnum, RuleResponse} from "@/generated/mammon";
|
||||
|
||||
export const activityTypes = {
|
||||
itemBought: {key: "ITEM_BOUGHT", name: "Item Bought"},
|
||||
@@ -10,7 +10,7 @@ export const activityTypes = {
|
||||
|
||||
export type Activity = { key: ActivityType, name: string }
|
||||
export type ActivityType = typeof activityTypes[keyof typeof activityTypes]['key'];
|
||||
export type RuleBook = RuleBookResponse & { ruleSets: { [key: ActivityType]: RuleSetResponse; } }
|
||||
export type RuleBook = RuleBookResponse & { rules: { [key: ActivityType]: RuleResponse; } }
|
||||
|
||||
export const ratesTypes = {
|
||||
None: {key: "NONE", name: "0 ISK"},
|
||||
@@ -20,11 +20,11 @@ export const ratesTypes = {
|
||||
EveEstimate: {key: "EVE_ESTIMATE", name: "Eve Estimate"},
|
||||
} as const;
|
||||
|
||||
export type Rate = { key: RuleResponseRateEnum, name: string }
|
||||
export type Rate = { key: RuleClauseResponseRateEnum, name: string }
|
||||
|
||||
export const findByCharacterId = (characterId: number): Promise<RuleBook> => ruleBookControllerApi.findByCharacterId(characterId)
|
||||
.then(response => response.data)
|
||||
.catch(() => ({characterId, ruleSets: {}}));
|
||||
.catch(() => ({characterId, rules: {}}));
|
||||
|
||||
export const setCharacterRuleBook = (characterId: number, ruleBook: RuleBook): Promise<RuleBook> => ruleBookControllerApi.setCharacterRuleBook(characterId, ruleBook)
|
||||
.then(response => response.data);
|
||||
Reference in New Issue
Block a user