text area
This commit is contained in:
+9
-75
@@ -415,66 +415,6 @@ paths:
|
|||||||
$ref: "#/components/schemas/AcquisitionResponse"
|
$ref: "#/components/schemas/AcquisitionResponse"
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
IskRuleClauseResponse:
|
|
||||||
allOf:
|
|
||||||
- $ref: "#/components/schemas/RuleClauseResponse"
|
|
||||||
- type: object
|
|
||||||
properties:
|
|
||||||
fromLedgerRef:
|
|
||||||
type: string
|
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
|
||||||
toLedgerRef:
|
|
||||||
type: string
|
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
|
||||||
required:
|
|
||||||
- fromLedgerRef
|
|
||||||
- toLedgerRef
|
|
||||||
ItemExchangeRuleClauseResponse:
|
|
||||||
allOf:
|
|
||||||
- $ref: "#/components/schemas/RuleClauseResponse"
|
|
||||||
- type: object
|
|
||||||
properties:
|
|
||||||
rate:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- NONE
|
|
||||||
- VALUE
|
|
||||||
- JITA_BUY
|
|
||||||
- JITA_SELL
|
|
||||||
- EVE_ESTIMATE
|
|
||||||
fromLedgerRef:
|
|
||||||
type: string
|
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
|
||||||
toLedgerRef:
|
|
||||||
type: string
|
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
|
||||||
required:
|
|
||||||
- fromLedgerRef
|
|
||||||
- rate
|
|
||||||
- toLedgerRef
|
|
||||||
RuleClauseResponse:
|
|
||||||
discriminator:
|
|
||||||
propertyName: type
|
|
||||||
mapping:
|
|
||||||
ISK: "#/components/schemas/IskRuleClauseResponse"
|
|
||||||
ITEM_EXCHANGE: "#/components/schemas/ItemExchangeRuleClauseResponse"
|
|
||||||
oneOf:
|
|
||||||
- $ref: "#/components/schemas/IskRuleClauseResponse"
|
|
||||||
- $ref: "#/components/schemas/ItemExchangeRuleClauseResponse"
|
|
||||||
properties:
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- type
|
|
||||||
RuleResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
clauses:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: "#/components/schemas/RuleClauseResponse"
|
|
||||||
required:
|
|
||||||
- clauses
|
|
||||||
UpdateRuleBookRequest:
|
UpdateRuleBookRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -487,14 +427,12 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
pattern: "[a-z]+(-[a-z]+)*"
|
||||||
rules:
|
script:
|
||||||
type: object
|
type: string
|
||||||
additionalProperties:
|
|
||||||
$ref: "#/components/schemas/RuleResponse"
|
|
||||||
required:
|
required:
|
||||||
- ledgerRefs
|
- ledgerRefs
|
||||||
- name
|
- name
|
||||||
- rules
|
- script
|
||||||
- usedForAcquisitions
|
- usedForAcquisitions
|
||||||
RuleBookResponse:
|
RuleBookResponse:
|
||||||
type: object
|
type: object
|
||||||
@@ -511,15 +449,13 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
pattern: "[a-z]+(-[a-z]+)*"
|
||||||
rules:
|
script:
|
||||||
type: object
|
type: string
|
||||||
additionalProperties:
|
|
||||||
$ref: "#/components/schemas/RuleResponse"
|
|
||||||
required:
|
required:
|
||||||
- ledgerRefs
|
- ledgerRefs
|
||||||
- name
|
- name
|
||||||
- ruleBookId
|
- ruleBookId
|
||||||
- rules
|
- script
|
||||||
- usedForAcquisitions
|
- usedForAcquisitions
|
||||||
UpdateMainLedgerRequest:
|
UpdateMainLedgerRequest:
|
||||||
type: object
|
type: object
|
||||||
@@ -623,14 +559,12 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
pattern: "[a-z]+(-[a-z]+)*"
|
pattern: "[a-z]+(-[a-z]+)*"
|
||||||
rules:
|
script:
|
||||||
type: object
|
type: string
|
||||||
additionalProperties:
|
|
||||||
$ref: "#/components/schemas/RuleResponse"
|
|
||||||
required:
|
required:
|
||||||
- ledgerRefs
|
- ledgerRefs
|
||||||
- name
|
- name
|
||||||
- rules
|
- script
|
||||||
- usedForAcquisitions
|
- usedForAcquisitions
|
||||||
CreateMainLedgerRequest:
|
CreateMainLedgerRequest:
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const modelValue = defineModel({ default: false });
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@reference "@/style.css";
|
@reference "@/style.css";
|
||||||
|
|
||||||
input:checked ~ span:last-child {
|
input:checked ~ span:last-child {
|
||||||
--tw-translate-x: 1.25rem;
|
transform: translateX(1.25rem);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -71,14 +71,8 @@ export interface CreateRuleBookRequest {
|
|||||||
'name': string;
|
'name': string;
|
||||||
'usedForAcquisitions': boolean;
|
'usedForAcquisitions': boolean;
|
||||||
'ledgerRefs': Array<string>;
|
'ledgerRefs': Array<string>;
|
||||||
'rules': { [key: string]: RuleResponse; };
|
'script': string;
|
||||||
}
|
}
|
||||||
export interface IskRuleClauseResponse extends RuleClauseResponse {
|
|
||||||
'fromLedgerRef': string;
|
|
||||||
'toLedgerRef': string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface IskTransferResponse extends TransferResponse {
|
export interface IskTransferResponse extends TransferResponse {
|
||||||
'fromLedgerId': string;
|
'fromLedgerId': string;
|
||||||
'toLedgerId': string;
|
'toLedgerId': string;
|
||||||
@@ -88,22 +82,6 @@ export interface ItemBalanceResponse {
|
|||||||
'typeId': number;
|
'typeId': number;
|
||||||
'quantity': number;
|
'quantity': number;
|
||||||
}
|
}
|
||||||
export interface ItemExchangeRuleClauseResponse extends RuleClauseResponse {
|
|
||||||
'rate': ItemExchangeRuleClauseResponseRateEnum;
|
|
||||||
'fromLedgerRef': string;
|
|
||||||
'toLedgerRef': string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ItemExchangeRuleClauseResponseRateEnum = {
|
|
||||||
None: 'NONE',
|
|
||||||
Value: 'VALUE',
|
|
||||||
JitaBuy: 'JITA_BUY',
|
|
||||||
JitaSell: 'JITA_SELL',
|
|
||||||
EveEstimate: 'EVE_ESTIMATE',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type ItemExchangeRuleClauseResponseRateEnum = typeof ItemExchangeRuleClauseResponseRateEnum[keyof typeof ItemExchangeRuleClauseResponseRateEnum];
|
|
||||||
|
|
||||||
export interface ItemTransferResponse extends TransferResponse {
|
export interface ItemTransferResponse extends TransferResponse {
|
||||||
'fromLedgerId': string;
|
'fromLedgerId': string;
|
||||||
'toLedgerId': string;
|
'toLedgerId': string;
|
||||||
@@ -125,15 +103,7 @@ export interface RuleBookResponse {
|
|||||||
'name': string;
|
'name': string;
|
||||||
'usedForAcquisitions': boolean;
|
'usedForAcquisitions': boolean;
|
||||||
'ledgerRefs': Array<string>;
|
'ledgerRefs': Array<string>;
|
||||||
'rules': { [key: string]: RuleResponse; };
|
'script': string;
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @type RuleClauseResponse
|
|
||||||
*/
|
|
||||||
export type RuleClauseResponse = { type: 'ISK' } & IskRuleClauseResponse | { type: 'ITEM_EXCHANGE' } & ItemExchangeRuleClauseResponse;
|
|
||||||
|
|
||||||
export interface RuleResponse {
|
|
||||||
'clauses': Array<RuleClauseResponse>;
|
|
||||||
}
|
}
|
||||||
export interface SetCharacterRuleBookRequest {
|
export interface SetCharacterRuleBookRequest {
|
||||||
'ruleBookId': string;
|
'ruleBookId': string;
|
||||||
@@ -162,7 +132,7 @@ export interface UpdateRuleBookRequest {
|
|||||||
'name': string;
|
'name': string;
|
||||||
'usedForAcquisitions': boolean;
|
'usedForAcquisitions': boolean;
|
||||||
'ledgerRefs': Array<string>;
|
'ledgerRefs': Array<string>;
|
||||||
'rules': { [key: string]: RuleResponse; };
|
'script': string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ watch(useRoute(), async route => {
|
|||||||
<div class="flex flex-wrap items-center mb-2 mt-2">
|
<div class="flex flex-wrap items-center mb-2 mt-2">
|
||||||
<div class="me-2" v-for="ref in ledgerRefs" :ref="ref">
|
<div class="me-2" v-for="ref in ledgerRefs" :ref="ref">
|
||||||
<span class="me-1">{{ref}}:</span>
|
<span class="me-1">{{ref}}:</span>
|
||||||
<LedgerSelect :ledgers="ledgersToUse" :modelValue="bindings[ref] ?? systemLedger" @update:modelValue="value => bindings[ref] = value" />
|
<LedgerSelect :ledgers="ledgersToUse" :modelValue="bindings[ref] ?? systemLedger" @update:modelValue="value => { if (value) bindings[ref] = value }" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ import {useRoute, useRouter} from "vue-router";
|
|||||||
import {ref, watch} from "vue";
|
import {ref, watch} from "vue";
|
||||||
import {useDebounceFn} from "@vueuse/core";
|
import {useDebounceFn} from "@vueuse/core";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import {activityTypes, RuleInput, Rules, useRuleBooksStore} from "@/rules";
|
import {useRuleBooksStore} from "@/rules";
|
||||||
import {PlusIcon, TrashIcon} from "@heroicons/vue/24/outline";
|
import {PlusIcon, TrashIcon} from "@heroicons/vue/24/outline";
|
||||||
import {routeNames} from "@/routes";
|
import {routeNames} from "@/routes";
|
||||||
import {Dropdown} from "@/components";
|
import {SliderCheckbox} from "@/components";
|
||||||
|
|
||||||
const ruleBookId = ref<string>();
|
const ruleBookId = ref<string>();
|
||||||
const name = ref<string>('');
|
const name = ref<string>('');
|
||||||
|
const usedForAcquisitions = ref<boolean>(false);
|
||||||
const ledgerRefs = ref<string[]>([]);
|
const ledgerRefs = ref<string[]>([]);
|
||||||
const rules = ref<Rules>({});
|
const script = ref<string>('');
|
||||||
|
|
||||||
const {findById, create, update, refresh} = useRuleBooksStore();
|
const {findById, create, update, refresh} = useRuleBooksStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -20,16 +21,18 @@ const save = async () => {
|
|||||||
if (!ruleBookId.value) {
|
if (!ruleBookId.value) {
|
||||||
const created = await create({
|
const created = await create({
|
||||||
name: name.value,
|
name: name.value,
|
||||||
|
usedForAcquisitions: usedForAcquisitions.value,
|
||||||
ledgerRefs: ledgerRefs.value,
|
ledgerRefs: ledgerRefs.value,
|
||||||
rules: rules.value
|
script: script.value
|
||||||
})
|
})
|
||||||
await router.push({ name: routeNames.editRuleBook, params: {ruleBookId: created.ruleBookId}})
|
await router.push({ name: routeNames.editRuleBook, params: {ruleBookId: created.ruleBookId}})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await update(ruleBookId.value, {
|
await update(ruleBookId.value, {
|
||||||
name: name.value,
|
name: name.value,
|
||||||
|
usedForAcquisitions: usedForAcquisitions.value,
|
||||||
ledgerRefs: ledgerRefs.value,
|
ledgerRefs: ledgerRefs.value,
|
||||||
rules: rules.value
|
script: script.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,14 +60,16 @@ watch(useRoute(), async route => {
|
|||||||
|
|
||||||
ruleBookId.value = id;
|
ruleBookId.value = id;
|
||||||
name.value = ruleBook?.name ?? '';
|
name.value = ruleBook?.name ?? '';
|
||||||
ledgerRefs.value = [...ruleBook?.ledgerRefs];
|
usedForAcquisitions.value = ruleBook?.usedForAcquisitions ?? false;
|
||||||
rules.value = {...ruleBook?.rules}; // TODO fully clone rules
|
ledgerRefs.value = [...(ruleBook?.ledgerRefs ?? [])];
|
||||||
|
script.value = ruleBook?.script ?? '';
|
||||||
log.info('Loaded rule book:', ruleBook);
|
log.info('Loaded rule book:', ruleBook);
|
||||||
} else {
|
} else {
|
||||||
ruleBookId.value = undefined;
|
ruleBookId.value = undefined;
|
||||||
name.value = '';
|
name.value = '';
|
||||||
|
usedForAcquisitions.value = false;
|
||||||
ledgerRefs.value = [];
|
ledgerRefs.value = [];
|
||||||
rules.value = {};
|
script.value = '';
|
||||||
log.info('No rule book to load');
|
log.info('No rule book to load');
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
@@ -76,12 +81,16 @@ watch(useRoute(), async route => {
|
|||||||
<div class="flex grow border-b-1">
|
<div class="flex grow border-b-1">
|
||||||
Name:
|
Name:
|
||||||
<input class="mb-2 ms-2" type="text" v-model="name" />
|
<input class="mb-2 ms-2" type="text" v-model="name" />
|
||||||
|
<label class="flex items-center ms-2 mb-2">
|
||||||
|
<SliderCheckbox class="me-2" v-model="usedForAcquisitions" />
|
||||||
|
Used for acquisitions
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-b-1">
|
<div class="border-b-1">
|
||||||
Ledgers References:
|
Ledgers References:
|
||||||
<div class="flex flex-wrap items-center">
|
<div class="flex flex-wrap items-center mt-2">
|
||||||
<div class="flex items-center mb-2" v-for="(ledgerRef, index) in ledgerRefs" :key="index">
|
<div class="flex items-center mb-2" v-for="(ledgerRef, index) in ledgerRefs" :key="index">
|
||||||
<input class="me-1" type="text" :value="ledgerRefs[index]" @input="updateLedgerRef(index, ($event.target as HTMLInputElement).value)" />
|
<input class="me-1" type="text" :value="ledgerRef" @input="updateLedgerRef(index, ($event.target as HTMLInputElement).value)" />
|
||||||
<button class="btn-icon me-2" @click="removeLedgerRef(index)"><TrashIcon /></button>
|
<button class="btn-icon me-2" @click="removeLedgerRef(index)"><TrashIcon /></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-2">
|
<div class="flex items-center mb-2">
|
||||||
@@ -89,14 +98,10 @@ watch(useRoute(), async route => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col grow border-b-1" v-for="activityType in activityTypes" :key="activityType.key">
|
<div class="flex flex-col grow border-b-1">
|
||||||
<Dropdown :inline="true" :autoClose="false" class="rule-dropdown">
|
Script:
|
||||||
<template #button>
|
<textarea class="script-editor mt-2 mb-2" spellcheck="false" v-model="script" rows="20"
|
||||||
<span>{{ activityType.name }}</span>
|
placeholder="// activity, transaction, ledgers are available — branch on activity.type"></textarea>
|
||||||
</template>
|
|
||||||
<RuleInput :ledgerRefs="ledgerRefs" :activityType="activityType.key" v-model="rules[activityType.key]" />
|
|
||||||
</Dropdown>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 justify-end flex">
|
<div class="mt-2 justify-end flex">
|
||||||
@@ -110,11 +115,8 @@ watch(useRoute(), async route => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
@reference "@/style.css";
|
@reference "@/style.css";
|
||||||
|
|
||||||
.rule-dropdown :deep(>button) {
|
.script-editor {
|
||||||
@apply bg-slate-800 hover:bg-slate-800 border-none flex items-center w-full;
|
@apply bg-slate-900 text-slate-100 font-mono text-sm p-2 rounded w-full resize-y;
|
||||||
}
|
tab-size: 2;
|
||||||
|
|
||||||
.rule-dropdown.dropdown-open :deep(>button) {
|
|
||||||
@apply bg-slate-800 rounded-b-none;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
import {systemLedger, systemLedgerRef} from "@/ledger";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
ledgerRefs: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
defineProps<Props>()
|
|
||||||
|
|
||||||
const ledgerRef = defineModel<string>();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<select v-model="ledgerRef" :class="{'system-ledger': ledgerRef === systemLedgerRef}">
|
|
||||||
<option v-for="l in ledgerRefs" :key="l" :value="l" :class="{'system-ledger': l === systemLedgerRef}">{{ l === systemLedgerRef ? systemLedger.name : l }}</option>
|
|
||||||
</select>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
@reference "@/style.css";
|
|
||||||
|
|
||||||
.system-ledger {
|
|
||||||
@apply text-emerald-400;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
import {ItemExchangeRuleClauseResponse, ItemExchangeRuleClauseResponseRateEnum, RuleClauseResponse} from "@/generated/mammon";
|
|
||||||
import {computed, watch} from "vue";
|
|
||||||
import {systemLedgerRef} from "@/ledger";
|
|
||||||
import {ratesTypes} from "@/rules/rules.ts";
|
|
||||||
import LedgerRefSelect from "./LedgerRefSelect.vue";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
ledgerRefs: string[];
|
|
||||||
hasRate: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
|
||||||
|
|
||||||
const rule = defineModel<RuleClauseResponse>({ default: {
|
|
||||||
type: 'ITEM_EXCHANGE',
|
|
||||||
rate: ItemExchangeRuleClauseResponseRateEnum.None,
|
|
||||||
fromLedgerRef: systemLedgerRef,
|
|
||||||
toLedgerRef: systemLedgerRef,
|
|
||||||
}});
|
|
||||||
|
|
||||||
// Only item-exchange clauses carry a rate; narrow for the rate <select>.
|
|
||||||
const itemRule = computed(() => rule.value as ItemExchangeRuleClauseResponse)
|
|
||||||
|
|
||||||
const ledgerRefsWithSystem = computed<string[]>(() => [systemLedgerRef, ...props.ledgerRefs])
|
|
||||||
|
|
||||||
watch(ledgerRefsWithSystem, (newVal, oldVal) => {
|
|
||||||
if (newVal.length !== oldVal.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rule.value.fromLedgerRef && rule.value.fromLedgerRef !== systemLedgerRef) {
|
|
||||||
rule.value.fromLedgerRef = newVal[oldVal.findIndex(v => v === rule.value.fromLedgerRef)]
|
|
||||||
}
|
|
||||||
if (rule.value.toLedgerRef && rule.value.toLedgerRef !== systemLedgerRef) {
|
|
||||||
rule.value.toLedgerRef = newVal[oldVal.findIndex(v => v === rule.value.toLedgerRef)]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
From:
|
|
||||||
<LedgerRefSelect class="me-2 grow" v-model="rule.fromLedgerRef" :ledger-refs="ledgerRefsWithSystem"/>
|
|
||||||
To:
|
|
||||||
<LedgerRefSelect class="me-2 grow" v-model="rule.toLedgerRef" :ledger-refs="ledgerRefsWithSystem"/>
|
|
||||||
<template v-if="hasRate">
|
|
||||||
At:
|
|
||||||
<select class="me-2 grow" v-model="itemRule.rate">
|
|
||||||
<option v-for="rateType in ratesTypes" :key="rateType.key" :value="rateType.key">{{ rateType.name }}</option>
|
|
||||||
</select>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
import {ItemExchangeRuleClauseResponseRateEnum, RuleClauseResponse, 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";
|
|
||||||
import {systemLedgerRef} from "@/ledger";
|
|
||||||
import {ActivityType, activityTypeHasRate} from "@/rules/rules.ts";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
ledgerRefs: string[];
|
|
||||||
activityType: ActivityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
|
||||||
|
|
||||||
const hasRate = computed<boolean>(() => activityTypeHasRate(props.activityType));
|
|
||||||
|
|
||||||
const rule = defineModel<RuleResponse>({default: {clauses:[]}});
|
|
||||||
const clauses = computed<RuleClauseResponse[]>({
|
|
||||||
get: () => rule.value && rule.value.clauses ? rule.value.clauses : [],
|
|
||||||
set: value => rule.value = {clauses: value}
|
|
||||||
})
|
|
||||||
|
|
||||||
const addClause = () => {
|
|
||||||
const clause: RuleClauseResponse = hasRate.value
|
|
||||||
? {type: 'ITEM_EXCHANGE', rate: ItemExchangeRuleClauseResponseRateEnum.None, fromLedgerRef: systemLedgerRef, toLedgerRef: systemLedgerRef}
|
|
||||||
: {type: 'ISK', fromLedgerRef: systemLedgerRef, toLedgerRef: systemLedgerRef};
|
|
||||||
clauses.value = [...clauses.value, clause]
|
|
||||||
}
|
|
||||||
|
|
||||||
const setClause = (index: number, clause?: RuleClauseResponse) => {
|
|
||||||
if (!clause) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clauses.value = clauses.value.with(index, clause)
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeClause = (index: number) => {
|
|
||||||
clauses.value = clauses.value.toSpliced(index, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortableContainer = useTemplateRef('sortable-container')
|
|
||||||
useSortable(sortableContainer, clauses, { 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="(clause, index) in clauses" :key="index">
|
|
||||||
<span class="sortable-handle flex">
|
|
||||||
<Bars4Icon class="w-6"/>
|
|
||||||
</span>
|
|
||||||
<RuleClauseInput :ledgerRefs="ledgerRefs" :hasRate="hasRate" :modelValue="clause" @update:modelValue="v => setClause(index, v)" />
|
|
||||||
<button class="btn-icon" @click="removeClause(index)"><TrashIcon /></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-end mb-2 mt-2">
|
|
||||||
<button class="btn-icon" @click="addClause"><PlusIcon /></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
@reference "@/style.css";
|
|
||||||
|
|
||||||
.sortable-handle {
|
|
||||||
@apply cursor-grab;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sortable-chosen {
|
|
||||||
@apply cursor-grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sortable-chosen .sortable-handle {
|
|
||||||
@apply cursor-grabbing;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,3 +1 @@
|
|||||||
export * from "./rules";
|
export * from "./rules";
|
||||||
|
|
||||||
export {default as RuleInput} from './RuleInput.vue';
|
|
||||||
+3
-29
@@ -2,39 +2,13 @@ import {characterRuleBookApi, ruleBookApi} from "@/mammon";
|
|||||||
import {
|
import {
|
||||||
CharacterRuleBookResponse,
|
CharacterRuleBookResponse,
|
||||||
CreateRuleBookRequest,
|
CreateRuleBookRequest,
|
||||||
ItemExchangeRuleClauseResponseRateEnum,
|
|
||||||
RuleBookResponse,
|
RuleBookResponse,
|
||||||
RuleResponse,
|
|
||||||
SetCharacterRuleBookRequest
|
SetCharacterRuleBookRequest
|
||||||
} from "@/generated/mammon";
|
} from "@/generated/mammon";
|
||||||
import {defineStore} from "pinia";
|
import {defineStore} from "pinia";
|
||||||
import {ref, triggerRef} from "vue";
|
import {ref, triggerRef} from "vue";
|
||||||
|
|
||||||
export const activityTypes = {
|
export type RuleBook = RuleBookResponse;
|
||||||
itemBought: {key: "ITEM_BOUGHT", name: "Item Bought"},
|
|
||||||
itemSold: {key: "ITEM_SOLD", name: "Item Sold"},
|
|
||||||
itemAcquiredManually: {key: "ITEM_ACQUIRED_MANUALLY", name: "Item Acquired Manually"},
|
|
||||||
itemConsumedManually: {key: "ITEM_CONSUME_MANUALLY", name: "Item Consumed Manually"},
|
|
||||||
bountyEarned: {key: "BOUNTY_EARNED", name: "Bounty Earned"},
|
|
||||||
// itemManufactured: {id: "ITEM_MANUFACTURED", name: "Item Manufactured"}
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type Activity = { key: ActivityType, name: string }
|
|
||||||
export type ActivityType = typeof activityTypes[keyof typeof activityTypes]['key'];
|
|
||||||
export type Rules = { [key: ActivityType]: RuleResponse; };
|
|
||||||
export type RuleBook = RuleBookResponse & { rules: Rules }
|
|
||||||
|
|
||||||
export const activityTypeHasRate = (key: ActivityType): boolean => key !== activityTypes.bountyEarned.key;
|
|
||||||
|
|
||||||
export const ratesTypes = {
|
|
||||||
None: {key: "NONE", name: "0 ISK"},
|
|
||||||
Value: {key: "VALUE", name: "Value"},
|
|
||||||
JitaBuy: {key: "JITA_BUY", name: "Jita Buy Order"},
|
|
||||||
JitaSell: {key: "JITA_SELL", name: "Jita Sell Order"},
|
|
||||||
EveEstimate: {key: "EVE_ESTIMATE", name: "Eve Estimate"},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type Rate = { key: ItemExchangeRuleClauseResponseRateEnum, name: string }
|
|
||||||
|
|
||||||
export const useRuleBooksStore = defineStore('rule-books', () => {
|
export const useRuleBooksStore = defineStore('rule-books', () => {
|
||||||
const ruleBooks = ref<RuleBook[]>([]);
|
const ruleBooks = ref<RuleBook[]>([]);
|
||||||
@@ -59,7 +33,7 @@ export const useRuleBooksStore = defineStore('rule-books', () => {
|
|||||||
const create = (ruleBook: CreateRuleBookRequest) => ruleBookApi.createRuleBook(ruleBook).then(response => addRuleBook(response.data));
|
const create = (ruleBook: CreateRuleBookRequest) => ruleBookApi.createRuleBook(ruleBook).then(response => addRuleBook(response.data));
|
||||||
const update = (ruleBookId: string, ruleBook: CreateRuleBookRequest) => ruleBookApi.updateRuleBook(ruleBookId, ruleBook).then(response => replaceRuleBook(response.data));
|
const update = (ruleBookId: string, ruleBook: CreateRuleBookRequest) => ruleBookApi.updateRuleBook(ruleBookId, ruleBook).then(response => replaceRuleBook(response.data));
|
||||||
|
|
||||||
const refresh = () => ruleBookApi.findAllRuleBooks().then(response => ruleBooks.value = response.data as RuleBook[]);
|
const refresh = () => ruleBookApi.findAllRuleBooks().then(response => ruleBooks.value = response.data);
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
@@ -68,7 +42,7 @@ export const useRuleBooksStore = defineStore('rule-books', () => {
|
|||||||
|
|
||||||
export const findCharacterRuleBookByCharacterId = (characterId: number): Promise<CharacterRuleBookResponse> => characterRuleBookApi.findCharacterRuleBookByCharacterId(characterId)
|
export const findCharacterRuleBookByCharacterId = (characterId: number): Promise<CharacterRuleBookResponse> => characterRuleBookApi.findCharacterRuleBookByCharacterId(characterId)
|
||||||
.then(response => response.data)
|
.then(response => response.data)
|
||||||
.catch(() => ({characterId, rules: {}}));
|
.catch(() => ({characterId, ruleBookId: '', bindings: {}}));
|
||||||
|
|
||||||
export const setCharacterRuleBookForCharacter = (characterId: number, ruleBook: SetCharacterRuleBookRequest): Promise<CharacterRuleBookResponse> => characterRuleBookApi.setCharacterRuleBookForCharacter(characterId, ruleBook)
|
export const setCharacterRuleBookForCharacter = (characterId: number, ruleBook: SetCharacterRuleBookRequest): Promise<CharacterRuleBookResponse> => characterRuleBookApi.setCharacterRuleBookForCharacter(characterId, ruleBook)
|
||||||
.then(response => response.data);
|
.then(response => response.data);
|
||||||
Reference in New Issue
Block a user