Skip to content

Commit

Permalink
Merge pull request #3 from TheAsel/multiple_parties
Browse files Browse the repository at this point in the history
Multiple parties
  • Loading branch information
TheAsel authored Nov 5, 2023
2 parents ed09629 + 53a2a39 commit 23bfa37
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/components/Encounter/CreatureList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const debouncedCall = debounce(async function () {
}
}
}
const partyLevels = party.getParty;
const partyLevels = party.getActiveParty.members;
const post = {
enemy_levels: enemyLevels,
party_levels: partyLevels
Expand Down
13 changes: 7 additions & 6 deletions src/components/Encounter/CreaturesTable/EncounterBuilder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const restoreSettings = () => {
const generateEncounter = async () => {
saveChanges();
const partyLevels = party.getParty;
const partyLevels = party.getActiveParty.members;
const post = {
traits: tmpFilters.value.traits,
alignments: tmpFilters.value.alignment,
Expand Down Expand Up @@ -219,19 +219,20 @@ defineExpose({ generateEncounter });
</q-card-section>
<q-separator />
<q-card-actions>
<q-btn-group>
<q-btn-group flat>
<q-btn
unelevated
flat
label="Save changes"
type="submit"
type="button"
class="full-width tw-text-blue-600 dark:tw-text-blue-400"
v-close-popup
@click="saveChanges"
/>
<q-separator vertical />
<q-btn
unelevated
flat
label="Generate Encounter"
type="submit"
type="button"
class="full-width tw-text-blue-600 dark:tw-text-blue-400"
v-close-popup
@click="generateEncounter"
Expand Down
221 changes: 194 additions & 27 deletions src/components/Encounter/CreaturesTable/PartyBuilder.vue
Original file line number Diff line number Diff line change
@@ -1,76 +1,235 @@
<script setup lang="ts">
import { ref } from 'vue';
import { biXLg, biPlusLg, biDashLg } from '@quasar/extras/bootstrap-icons';
import { party } from 'src/types/party';
import { biXLg, biPlusLg, biDashLg, biTrash } from '@quasar/extras/bootstrap-icons';
import { matArrowDropDown } from '@quasar/extras/material-icons';
import { partyStore } from 'stores/store';
const party = partyStore();
const tmpParty = ref(party.getParty);
const tmpParty = ref<party>({
name: party.getActiveParty.name,
members: [...party.getActiveParty.members]
});
const parties = ref(party.getParties.map((party) => party.name));
const dialog = ref(false);
const newPartyDialog = ref(false);
const partyNameInput = ref();
const newPartyName = ref('');
const removePartyDialog = ref(false);
const restoreParty = () => {
dialog.value = true;
tmpParty.value = [...party.getParty];
tmpParty.value = {
name: party.getActiveParty.name,
members: [...party.getActiveParty.members]
};
};
const validateLevel = (index: number) => {
const value = tmpParty.value[index];
const value = tmpParty.value.members[index];
if (value < 1) {
tmpParty.value[index] = 1;
tmpParty.value.members[index] = 1;
}
if (value > 20) {
tmpParty.value[index] = 20;
tmpParty.value.members[index] = 20;
}
};
const addPlayer = () => {
tmpParty.value.push(1);
tmpParty.value.members.push(1);
};
const removePlayer = (index: number) => {
if (tmpParty.value.length > 1) {
tmpParty.value.splice(index, 1);
if (tmpParty.value.members.length > 1) {
tmpParty.value.members.splice(index, 1);
}
};
const closeDialog = () => {
newPartyDialog.value = false;
removePartyDialog.value = false;
newPartyName.value = '';
};
const addParty = () => {
partyNameInput.value.validate();
if (!partyNameInput.value.hasError) {
party.addParty(newPartyName.value);
parties.value = party.getParties.map((party) => party.name);
tmpParty.value = {
name: party.getActiveParty.name,
members: [...party.getActiveParty.members]
};
saveChanges();
newPartyName.value = '';
newPartyDialog.value = false;
}
};
const removeParty = () => {
party.removeParty();
parties.value = party.getParties.map((party) => party.name);
tmpParty.value = {
name: party.getActiveParty.name,
members: [...party.getActiveParty.members]
};
saveChanges();
removePartyDialog.value = false;
};
const changeActiveParty = (selected: string) => {
party.changeActiveParty(party.getPartyIndex(selected));
tmpParty.value = {
name: party.getActiveParty.name,
members: [...party.getActiveParty.members]
};
};
const saveChanges = () => {
party.updateParty(tmpParty.value);
localStorage.setItem('party', JSON.stringify(tmpParty.value));
party.updateParty(tmpParty.value.name, tmpParty.value.members);
localStorage.setItem('parties', JSON.stringify(party.getParties));
};
</script>

<template>
<q-btn push label="Party Builder" @click="restoreParty" id="v-step-1" />
<q-dialog v-model="dialog" aria-label="Player builder">
<q-card flat bordered>
<q-card-section class="row items-center">
<div class="text-h6 tw-mr-4">Party Builder</div>
<q-space />
<q-btn
:icon="biXLg"
size="md"
padding="sm"
flat
round
dense
v-close-popup
aria-label="Close dialog"
/>
<q-card-section class="items-center">
<div class="row tw-mb-2">
<div class="text-h6 tw-mr-4 tw-my-auto">Party Builder</div>
<q-space />
<q-btn
:icon="biXLg"
size="md"
padding="sm"
flat
round
dense
v-close-popup
aria-label="Close dialog"
/>
</div>
<div class="row">
<q-select
style="width: 180px"
outlined
v-model="tmpParty.name"
:options="parties"
label="Active Party"
:dropdown-icon="matArrowDropDown"
@update:model-value="changeActiveParty(tmpParty.name)"
/>
<q-space />
<q-btn
class="tw-my-auto"
:icon="biPlusLg"
size="sm"
padding="sm"
flat
round
dense
aria-label="Add new party"
@click="newPartyDialog = true"
/>
<q-dialog
v-model="newPartyDialog"
aria-label="New party dialog"
@escape-key="closeDialog"
>
<q-card flat bordered>
<q-card-section>
<div class="text-h6">New party name</div>
</q-card-section>

<q-card-section class="q-pt-none">
<q-input
ref="partyNameInput"
dense
v-model="newPartyName"
autofocus
@keyup.enter="addParty"
:rules="[
(val) => !!val || 'Field is required',
(val) => !parties.find((name) => name === val) || 'This party already exists'
]"
:no-error-icon="true"
/>
</q-card-section>

<q-card-actions align="center" class="text-primary">
<q-btn
flat
label="Cancel"
@click="closeDialog"
class="tw-text-blue-600 dark:tw-text-blue-400"
/>
<q-btn
flat
label="Add party"
@click="addParty"
class="tw-text-blue-600 dark:tw-text-blue-400"
/>
</q-card-actions>
</q-card>
</q-dialog>
<q-space />
<q-btn
class="tw-m-auto"
:icon="biTrash"
size="sm"
padding="sm"
flat
round
dense
aria-label="Remove current party"
@click="removePartyDialog = true"
/>
<q-dialog
v-model="removePartyDialog"
aria-label="Remove party dialog"
@escape-key="closeDialog"
>
<q-card flat bordered>
<q-card-section>
<div class="text-h6">Remove this party?</div>
</q-card-section>
<q-card-actions align="center" class="text-primary">
<q-btn
flat
label="Cancel"
@click="closeDialog"
class="tw-text-blue-600 dark:tw-text-blue-400"
/>
<q-btn
flat
label="Remove"
@click="removeParty"
class="tw-text-red-600 dark:tw-text-red-400"
/>
</q-card-actions>
</q-card>
</q-dialog>
</div>
</q-card-section>

<q-separator />

<q-card-section style="max-height: 60vh" class="scroll">
<div class="tw-space-y-4">
<div v-for="(_, index) in tmpParty" :key="index" class="row no-wrap items-center">
<div v-for="(_, index) in tmpParty.members" :key="index" class="row no-wrap items-center">
<div class="col-grow">
<q-input
outlined
type="number"
min="1"
max="20"
:label="'Player ' + (index + 1)"
v-model.number="tmpParty[index]"
v-model.number="tmpParty.members[index]"
@update:model-value="validateLevel(index)"
dense
/>
Expand Down Expand Up @@ -109,7 +268,7 @@ const saveChanges = () => {
<q-btn
unelevated
label="Save changes"
type="submit"
type="button"
class="full-width tw-text-blue-600 dark:tw-text-blue-400"
v-close-popup
@click="saveChanges"
Expand All @@ -129,3 +288,11 @@ input[type='number'] {
appearance: textfield;
}
</style>

<style scoped>
.q-select:deep(.q-field__native) > span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
Loading

0 comments on commit 23bfa37

Please sign in to comment.