Basic goal editing / creation / deletion
Doesn't save yet
This commit is contained in:
parent
cc9282e661
commit
fd4adedcb3
4
components.d.ts
vendored
4
components.d.ts
vendored
@ -7,8 +7,12 @@ export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
EditGoal: typeof import('./src/composables/EditGoal.vue')['default']
|
||||
EditGoalDialog: typeof import('./src/composables/EditGoalDialog.vue')['default']
|
||||
EditorComponent: typeof import('./src/components/EditorComponent.vue')['default']
|
||||
GameList: typeof import('./src/composables/GameList.vue')['default']
|
||||
GeneratorComponent: typeof import('./src/components/GeneratorComponent.vue')['default']
|
||||
GoalEditorDialog: typeof import('./src/components/GoalEditorDialog.vue')['default']
|
||||
MarkdownRenderer: typeof import('./src/components/MarkdownRenderer.vue')['default']
|
||||
NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
@ -14,6 +14,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/extras": "^1.16.8",
|
||||
"@sindresorhus/string-hash": "^2.0.0",
|
||||
"@types/markdown-it": "^13.0.6",
|
||||
"@vue/runtime-core": "^3.3.8",
|
||||
"class-transformer": "^0.5.1",
|
||||
|
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@ -8,6 +8,9 @@ dependencies:
|
||||
'@quasar/extras':
|
||||
specifier: ^1.16.8
|
||||
version: 1.16.8
|
||||
'@sindresorhus/string-hash':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
'@types/markdown-it':
|
||||
specifier: ^13.0.6
|
||||
version: 13.0.6
|
||||
@ -791,6 +794,18 @@ packages:
|
||||
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
|
||||
dev: true
|
||||
|
||||
/@sindresorhus/fnv1a@3.1.0:
|
||||
resolution: {integrity: sha512-KV321z5m/0nuAg83W1dPLy85HpHDk7Sdi4fJbwvacWsEhAh+rZUW4ZfGcXmUIvjZg4ss2bcwNlRhJ7GBEUG08w==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/@sindresorhus/string-hash@2.0.0:
|
||||
resolution: {integrity: sha512-eNmMOd5DZkiu9LxIeHdh1XvDbcpFXV4HdBqg9hlg8YNKDvE6qmHiJ+Vy+rFrzXofRYmtheNv4A3ESad8unxwwA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dependencies:
|
||||
'@sindresorhus/fnv1a': 3.1.0
|
||||
dev: false
|
||||
|
||||
/@stylistic/eslint-plugin-js@1.2.0:
|
||||
resolution: {integrity: sha512-1Zi/AlQzOzTlTegupd3vrUYHd02ilvk7x5O9ZRFjYGtUcwHVk+WTEKk/3Nmr8yuvzEiXqUNFJ8bv8b4rLYCPRQ==}
|
||||
dependencies:
|
||||
|
@ -205,4 +205,3 @@ watch(learn_more, newValue => {
|
||||
selected_game.value = undefined;
|
||||
});
|
||||
</script>
|
||||
@/js/lib/LocalGames
|
||||
|
0
src/components/GoalEditorDialog.vue
Normal file
0
src/components/GoalEditorDialog.vue
Normal file
134
src/composables/EditGoalDialog.vue
Normal file
134
src/composables/EditGoalDialog.vue
Normal file
@ -0,0 +1,134 @@
|
||||
|
||||
<template>
|
||||
<q-card flat bordered style="min-width: 700px; max-width: 80vw; min-height: 10vh; max-height: 80vh;">
|
||||
<q-card-section class="q-gutter-y-md column">
|
||||
<q-input
|
||||
v-model="goal_name"
|
||||
square
|
||||
filled
|
||||
counter
|
||||
clearable
|
||||
maxlength="40"
|
||||
label="Name"
|
||||
type="text"
|
||||
></q-input>
|
||||
|
||||
<q-select
|
||||
label="Select Tags"
|
||||
square
|
||||
filled
|
||||
v-model="goal_tags"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
clearable
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
:options="all_tags"
|
||||
@new-value="addTag"
|
||||
></q-select>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions>
|
||||
<q-btn v-if="data.goal" flat color="red" icon="delete" :label="delete_label" @click="deleteGoal()" :disabled="!delete_enabled" />
|
||||
|
||||
<q-space/>
|
||||
|
||||
<q-btn flat color="red" icon="cancel" label="Cancel" @click="cancel()" />
|
||||
<q-btn flat color="green" icon="save" label="Save" @click="emitGoal()" :disabled="!canSave()"/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BingoGoal from '@/js/lib/BingoGoal.ts';
|
||||
import {
|
||||
stringCompare
|
||||
} from '@/js/lib/Util.ts';
|
||||
import type BingoCategory from '@/js/lib/BingoCategory.ts';
|
||||
import type BingoGoalList from '@/js/lib/BingoGoalList.ts';
|
||||
|
||||
const emit = defineEmits([
|
||||
'cancel',
|
||||
'deleteGoal',
|
||||
'emitGoal'
|
||||
]);
|
||||
|
||||
const {
|
||||
data
|
||||
} = defineProps<{
|
||||
data: {
|
||||
all_tags: string[],
|
||||
goal?: BingoGoal,
|
||||
},
|
||||
}>();
|
||||
|
||||
const goal_name = ref('');
|
||||
const all_tags: Ref<string[]> = ref([ ...data.all_tags ]);
|
||||
const goal_tags: Ref<string[]> = ref([ ]);
|
||||
|
||||
goal_name.value = data.goal?.name ?? '';
|
||||
goal_tags.value = data.goal?.tags ?? [];
|
||||
|
||||
const delete_label = ref('Delete (5)');
|
||||
const delete_enabled = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
let countdown = 5;
|
||||
let interval = setInterval(() => {
|
||||
if (--countdown <= 0) {
|
||||
clearInterval(interval);
|
||||
delete_label.value = 'Delete';
|
||||
delete_enabled.value = true;
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
delete_label.value = `Delete (${ countdown })`;
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
function canSave() {
|
||||
return goal_name.value?.length > 0;
|
||||
}
|
||||
|
||||
function addTag(value: string, done: Function) {
|
||||
// Exit if tag already exists
|
||||
if (goal_tags.value.some(tag => stringCompare(tag, value))) {
|
||||
done();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = all_tags.value.find(tag => stringCompare(tag, value));
|
||||
value = tag ?? value;
|
||||
|
||||
if (!data.all_tags.some(tag => stringCompare(tag, value))) {
|
||||
all_tags.value.push(value);
|
||||
}
|
||||
|
||||
done(value, 'toggle');
|
||||
|
||||
console.log('All tags', all_tags);
|
||||
console.log('Goal tags', goal_tags);
|
||||
}
|
||||
|
||||
function deleteGoal() {
|
||||
emit('deleteGoal', data.goal);
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
emit('cancel');
|
||||
}
|
||||
|
||||
function emitGoal() {
|
||||
const goal = new BingoGoal(goal_name.value);
|
||||
goal.tags = goal_tags.value;
|
||||
|
||||
emit('emitGoal', goal);
|
||||
}
|
||||
</script>
|
||||
|
308
src/composables/GameList.vue
Normal file
308
src/composables/GameList.vue
Normal file
@ -0,0 +1,308 @@
|
||||
<template>
|
||||
<q-tree
|
||||
:nodes="nodes"
|
||||
node-key="label"
|
||||
tick-strategy="leaf"
|
||||
v-model:selected="selected"
|
||||
v-model:ticked="ticked"
|
||||
v-model:expanded="expanded"
|
||||
>
|
||||
<template v-slot:header-goal="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn
|
||||
v-if="editMode"
|
||||
icon="edit"
|
||||
flat
|
||||
round
|
||||
size="sm"
|
||||
color="orange"
|
||||
@click="openEditGoalDialog(prop.node)"
|
||||
/>
|
||||
<div>{{ prop.node.label }}</div>
|
||||
<q-badge outline v-for="tag in prop.node.goal.tags" :key="tag" :color="getColorForString(tag)" class="q-ml-sm">
|
||||
<div class="text-weight-bold q-my-xs">{{ tag }}</div>
|
||||
</q-badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:header-goal-list="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn v-if="editMode" icon="edit" flat round size="sm" color="orange"/>
|
||||
<div>{{ prop.node.label }}</div>
|
||||
<q-badge outline color="orange" class="q-ml-sm">
|
||||
<div class="text-weight-bold q-my-xs">Goal List</div>
|
||||
</q-badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:header-category="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn v-if="editMode" icon="edit" flat round size="sm" color="orange"/>
|
||||
<div>{{ prop.node.label }}</div>
|
||||
<q-badge outline color="blue" class="q-ml-sm">
|
||||
<div class="text-weight-bold q-my-xs">Category</div>
|
||||
</q-badge>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Add Goal -->
|
||||
<template v-slot:header-add-goal="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn outline icon="add" label="Goal" color="light-blue" size="sm" @click="openEditGoalDialog(prop.node)"></q-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Add Goal List -->
|
||||
<template v-slot:header-add-goal-list="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn outline icon="add" label="Goal List" color="light-blue" size="sm"></q-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Add Category -->
|
||||
<template v-slot:header-add-category="prop">
|
||||
<div class="row items-center">
|
||||
<q-btn outline icon="add" label="Category" color="light-blue" size="sm"></q-btn>
|
||||
</div>
|
||||
</template>
|
||||
</q-tree>
|
||||
|
||||
<q-dialog v-model="edit_goal_dialog" persistent>
|
||||
<EditGoalDialog
|
||||
:data="edit_goal_data"
|
||||
@cancel="edit_goal_dialog = false"
|
||||
@delete-goal="delete_goal"
|
||||
@emit-goal="emit_goal"
|
||||
/>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Node {
|
||||
label: string;
|
||||
header?: string; // 'goal' | 'goal-list' | 'category' | 'add-goal' | 'add-goal-list' | 'add-category'
|
||||
children?: Node[];
|
||||
goal?: BingoGoal;
|
||||
parent?: BingoCategory | BingoGoalList;
|
||||
tickable?: boolean;
|
||||
noTick?: boolean;
|
||||
}
|
||||
|
||||
import {
|
||||
getColorForString
|
||||
} from '@/js/lib/Util.ts';
|
||||
|
||||
import BingoCategory from '@/js/lib/BingoCategory.ts';
|
||||
import type BingoGame from '@/js/lib/BingoGame.ts';
|
||||
import BingoGoal from '@/js/lib/BingoGoal.ts';
|
||||
import BingoGoalList from '@/js/lib/BingoGoalList.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
editMode: boolean;
|
||||
game: BingoGame | undefined;
|
||||
}>();
|
||||
|
||||
const editMode = props.editMode;
|
||||
|
||||
const selected = ref<Node[]>([]);
|
||||
const ticked = ref<Node[]>([]);
|
||||
const expanded = ref<Node[]>([]);
|
||||
|
||||
/* Edit Goal Dialog */
|
||||
interface EditGoalData {
|
||||
goal?: BingoGoal;
|
||||
all_tags: string[];
|
||||
parent_group: BingoCategory | BingoGoalList | undefined;
|
||||
}
|
||||
|
||||
const edit_goal_data = ref<EditGoalData>({
|
||||
all_tags: [] as string[],
|
||||
parent_group: undefined
|
||||
});
|
||||
const edit_goal_dialog = ref(false);
|
||||
const openEditGoalDialog = (node: Node) => {
|
||||
edit_goal_data.value.goal = node.goal;
|
||||
edit_goal_data.value.parent_group = node.parent;
|
||||
edit_goal_data.value.all_tags = props.game?.getAllTags() ?? [];
|
||||
edit_goal_dialog.value = true;
|
||||
};
|
||||
|
||||
const delete_goal = (goal: BingoGoal) => {
|
||||
// We always assume parent group is a goal list. You can't add goals to categories.
|
||||
const goal_list = edit_goal_data.value.parent_group as BingoGoalList;
|
||||
|
||||
const index = goal_list.goals.findIndex(g => g === goal);
|
||||
goal_list.goals.splice(index, 1);
|
||||
|
||||
// Reset values
|
||||
edit_goal_data.value = {
|
||||
goal: undefined,
|
||||
all_tags: [],
|
||||
parent_group: undefined
|
||||
};
|
||||
edit_goal_dialog.value = false;
|
||||
};
|
||||
|
||||
const emit_goal = (goal: BingoGoal) => {
|
||||
// We always assume parent group is a goal list. You can't add goals to categories.
|
||||
const goal_list = edit_goal_data.value.parent_group as BingoGoalList;
|
||||
|
||||
// Add new goal
|
||||
if (!edit_goal_data.value.goal) {
|
||||
goal_list.goals.push(goal);
|
||||
}
|
||||
// Replace existing goal
|
||||
else {
|
||||
const index = goal_list.goals.findIndex(g => g === edit_goal_data.value.goal);
|
||||
goal_list.goals.splice(index, 1, goal);
|
||||
}
|
||||
|
||||
// Reset values
|
||||
edit_goal_data.value = {
|
||||
goal: undefined,
|
||||
all_tags: [],
|
||||
parent_group: undefined
|
||||
};
|
||||
edit_goal_dialog.value = false;
|
||||
};
|
||||
|
||||
// const getAllGoals = (node: Node): BingoGoal[] => {
|
||||
// const goals: BingoGoal[] = [];
|
||||
// if (node.children) {
|
||||
// for (const child of node.children) {
|
||||
// goals.push(...getAllGoals(child));
|
||||
// }
|
||||
// }
|
||||
// else if (node.goal) {
|
||||
// goals.push(node.goal);
|
||||
// }
|
||||
|
||||
// return goals;
|
||||
// };
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
// const selectByTag = (tag: string) => {
|
||||
// ticked.value.length = 0;
|
||||
// ticked.value.push(...nodes.value.filter(node => {
|
||||
// return getAllGoals(node).map(goal => goal.tags.includes(tag));
|
||||
// }));
|
||||
|
||||
// console.log(ticked.value);
|
||||
// };
|
||||
|
||||
const nodes = computed(() => {
|
||||
const results: Node[] = [];
|
||||
|
||||
if (!props.game) {
|
||||
return results;
|
||||
}
|
||||
|
||||
results.push(...props.game.items.map(item => {
|
||||
const is_category = item instanceof BingoCategory;
|
||||
const is_goal_list = item instanceof BingoGoalList;
|
||||
|
||||
const group_node: Node = {
|
||||
label: item.name,
|
||||
header: is_category
|
||||
? 'category'
|
||||
: is_goal_list
|
||||
? 'goal-list'
|
||||
: '',
|
||||
children: [],
|
||||
tickable: !editMode,
|
||||
noTick: editMode
|
||||
};
|
||||
|
||||
if (is_category) {
|
||||
group_node.children = item.goal_lists.map(goal_list => {
|
||||
const goal_list_node: Node = {
|
||||
label: goal_list.name,
|
||||
header: 'goal-list',
|
||||
children: [],
|
||||
tickable: !editMode,
|
||||
noTick: editMode
|
||||
};
|
||||
|
||||
goal_list_node.children?.push(...goal_list.goals.map(goal => {
|
||||
const goal_node: Node = {
|
||||
label: goal.name,
|
||||
header: 'goal',
|
||||
goal,
|
||||
parent: goal_list,
|
||||
tickable: !editMode,
|
||||
noTick: editMode
|
||||
};
|
||||
|
||||
return goal_node;
|
||||
}));
|
||||
|
||||
if (editMode) {
|
||||
goal_list_node.children?.push({
|
||||
label: 'Add Goal',
|
||||
header: 'add-goal',
|
||||
parent: goal_list,
|
||||
tickable: false,
|
||||
noTick: true
|
||||
});
|
||||
}
|
||||
|
||||
return goal_list_node;
|
||||
});
|
||||
|
||||
if (editMode) {
|
||||
group_node.children?.push({
|
||||
label: 'Add Goal List',
|
||||
header: 'add-goal-list',
|
||||
tickable: false,
|
||||
noTick: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (is_goal_list) {
|
||||
group_node.children = item.goals.map(goal => {
|
||||
const goal_node: Node = {
|
||||
label: goal.name,
|
||||
header: 'goal',
|
||||
goal,
|
||||
parent: item,
|
||||
tickable: !editMode,
|
||||
noTick: editMode
|
||||
};
|
||||
|
||||
return goal_node;
|
||||
});
|
||||
|
||||
if (editMode) {
|
||||
group_node.children.push({
|
||||
label: 'Add Goal',
|
||||
header: 'add-goal',
|
||||
parent: item,
|
||||
tickable: false,
|
||||
noTick: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return group_node;
|
||||
}));
|
||||
|
||||
if (editMode) {
|
||||
results.push({
|
||||
label: 'Add Goal List',
|
||||
header: 'add-goal-list',
|
||||
tickable: false,
|
||||
noTick: true
|
||||
});
|
||||
|
||||
results.push({
|
||||
label: 'Add Category',
|
||||
header: 'add-category',
|
||||
tickable: false,
|
||||
noTick: true
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
});
|
||||
</script>
|
||||
|
@ -3,12 +3,14 @@ import BingoCategory from '@/js/lib/BingoCategory.ts';
|
||||
import BingoGoal from '@/js/lib/BingoGoal.ts';
|
||||
import BingoGoalList from '@/js/lib/BingoGoalList.ts';
|
||||
import SuccessResponse from '@/js/lib/SuccessResponse.ts';
|
||||
import Util from '@/js/lib/Util.ts';
|
||||
import {
|
||||
stringCompare
|
||||
} from '@/js/lib/Util.ts';
|
||||
import {
|
||||
Transform, plainToInstance, type TransformFnParams, Exclude
|
||||
} from 'class-transformer';
|
||||
|
||||
type BingoCategoryOrGoalList = BingoCategory | BingoGoalList;
|
||||
export type BingoCategoryOrGoalList = BingoCategory | BingoGoalList;
|
||||
|
||||
export default class BingoGame {
|
||||
id: string;
|
||||
@ -86,7 +88,7 @@ export default class BingoGame {
|
||||
|
||||
removeItemByName(name: string): SuccessResponse {
|
||||
const group = this.items.find(
|
||||
g => Util.stringCompare(g.name, name)
|
||||
g => stringCompare(g.name, name)
|
||||
);
|
||||
if (!group) {
|
||||
return SuccessResponse.error('Category not found');
|
||||
@ -95,6 +97,26 @@ export default class BingoGame {
|
||||
return this.removeItem(group);
|
||||
}
|
||||
|
||||
getAllTags(): string[] {
|
||||
const tags: string[] = [];
|
||||
|
||||
this.items.map(group => {
|
||||
const goal_lists = group instanceof BingoGoalList ? [ group ] : group.goal_lists;
|
||||
|
||||
goal_lists.map(subgroup => {
|
||||
subgroup.goals.map(goal => {
|
||||
goal.tags.map(tag => {
|
||||
if (!tags.includes(tag)) {
|
||||
tags.push(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
getGoalsByTags(...tags: string[]): BingoGoal[] {
|
||||
const goals: BingoGoal[] = [];
|
||||
|
||||
@ -105,7 +127,7 @@ export default class BingoGame {
|
||||
subgroup.goals.map(goal => {
|
||||
if (goal.tags.some(
|
||||
tag => tags.some(
|
||||
inputTag => Util.stringCompare(tag, inputTag)
|
||||
inputTag => stringCompare(tag, inputTag)
|
||||
)
|
||||
)) {
|
||||
goals.push(goal);
|
||||
|
@ -1,6 +1,8 @@
|
||||
|
||||
import SuccessResponse from '@/js/lib/SuccessResponse.js';
|
||||
import Util from './Util';
|
||||
import {
|
||||
stringCompare
|
||||
} from '@/js/lib/Util.ts';
|
||||
|
||||
export default class BingoGoal {
|
||||
name: string;
|
||||
@ -15,7 +17,7 @@ export default class BingoGoal {
|
||||
|
||||
addTag(tag: string): SuccessResponse {
|
||||
if (this.tags.some(
|
||||
existingTag => Util.stringCompare(existingTag, tag)
|
||||
existingTag => stringCompare(existingTag, tag)
|
||||
)) {
|
||||
return SuccessResponse.error('Tag already exists');
|
||||
}
|
||||
@ -28,13 +30,13 @@ export default class BingoGoal {
|
||||
|
||||
removeTag(tag: string): SuccessResponse {
|
||||
if (!this.tags.some(
|
||||
existingTag => Util.stringCompare(existingTag, tag)
|
||||
existingTag => stringCompare(existingTag, tag)
|
||||
)) {
|
||||
return SuccessResponse.error('Tag doesn\'t exist');
|
||||
}
|
||||
else {
|
||||
this.tags = this.tags.filter(
|
||||
existingTag => !Util.stringCompare(existingTag, tag)
|
||||
existingTag => !stringCompare(existingTag, tag)
|
||||
);
|
||||
|
||||
return SuccessResponse.success();
|
||||
|
@ -1,7 +1,33 @@
|
||||
export default class Util {
|
||||
static stringCompare(str1: string, str2: string): boolean {
|
||||
return str1.localeCompare(str2, undefined, {
|
||||
sensitivity: 'accent'
|
||||
}) === 0;
|
||||
}
|
||||
const colors = [
|
||||
'red',
|
||||
'pink',
|
||||
'purple',
|
||||
'deep-purple',
|
||||
'indigo',
|
||||
'blue',
|
||||
'light-blue',
|
||||
'cyan',
|
||||
'teal',
|
||||
'green',
|
||||
'light-green',
|
||||
'lime',
|
||||
'yellow',
|
||||
'amber',
|
||||
'orange',
|
||||
'deep-orange',
|
||||
'brown',
|
||||
'grey',
|
||||
'blue-grey'
|
||||
];
|
||||
|
||||
import stringHash from '@sindresorhus/string-hash';
|
||||
|
||||
export function stringCompare(str1: string, str2: string): boolean {
|
||||
return str1.localeCompare(str2, undefined, {
|
||||
sensitivity: 'accent'
|
||||
}) === 0;
|
||||
}
|
||||
|
||||
export function getColorForString(input: string): string {
|
||||
return colors[stringHash(input) % colors.length];
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ export const useLocalGamesStore = defineStore('localGames', () => {
|
||||
// });
|
||||
|
||||
console.info('--- Finished fetching games!');
|
||||
console.info('');
|
||||
|
||||
console.log(games.value);
|
||||
|
||||
console.info('');
|
||||
}
|
||||
|
||||
async function saveGames() {
|
||||
|
@ -1,3 +1,35 @@
|
||||
<template>
|
||||
<EditorComponent/>
|
||||
<!-- <EditorComponent/> -->
|
||||
|
||||
<GameList :game="yakuza" :edit-mode="true"/>
|
||||
|
||||
|
||||
<!-- <q-dialog v-model="dialog">
|
||||
<q-card style="min-width: 700px; max-width: 80vw; min-height: 10vh; max-height: 80vh;">
|
||||
<GoalEditorDialog :tags="tags"/>
|
||||
</q-card>
|
||||
</q-dialog> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type BingoGame from '@/js/lib/BingoGame.ts';
|
||||
|
||||
import {
|
||||
useLocalGamesStore
|
||||
} from '@/stores/local-games.ts';
|
||||
const localGames = useLocalGamesStore();
|
||||
|
||||
const yakuza = ref();
|
||||
onMounted(async() => {
|
||||
await localGames.fetchGames();
|
||||
|
||||
yakuza.value = localGames.games[0];
|
||||
console.log(yakuza.value);
|
||||
});
|
||||
|
||||
|
||||
const dialog = ref<boolean>(false);
|
||||
const selected_game = ref<BingoGame | undefined>();
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -22,7 +22,11 @@ export default defineConfig({
|
||||
plugins: [
|
||||
VueRouter(),
|
||||
Components({
|
||||
dts: true
|
||||
dts: true,
|
||||
dirs: [
|
||||
'src/components',
|
||||
'src/composables'
|
||||
]
|
||||
}),
|
||||
AutoImport({
|
||||
include: [
|
||||
|
Loading…
Reference in New Issue
Block a user