diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 1782de2..0b069bd 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -198,6 +198,31 @@ module.exports = {
lang: 'ts'
}
}
+ ],
+ 'vue/max-attributes-per-line': [
+ 'error',
+ {
+ singleline: {
+ max: 2
+ },
+ multiline: {
+ max: 1
+ }
+ }
+ ],
+ 'vue/first-attribute-linebreak': [
+ 'error',
+ {
+ singleline: 'beside',
+ multiline: 'below'
+ }
+ ],
+ 'vue/html-closing-bracket-newline': [
+ 'error',
+ {
+ singleline: 'never',
+ multiline: 'always'
+ }
]
}
};
diff --git a/components.d.ts b/components.d.ts
index 7e7b9f4..fa30f35 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -7,13 +7,18 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
+ copy: typeof import('./src/composables/EditGoalDialog copy.vue')['default']
EditGoal: typeof import('./src/composables/EditGoal.vue')['default']
EditGoalDialog: typeof import('./src/composables/EditGoalDialog.vue')['default']
+ EditGoalListDialog: typeof import('./src/composables/EditGoalListDialog.vue')['default']
EditorComponent: typeof import('./src/components/EditorComponent.vue')['default']
+ GameEditor: typeof import('./src/composables/GameEditor.vue')['default']
+ GameEditorDialog: typeof import('./src/composables/GameEditorDialog.vue')['default']
GameList: typeof import('./src/composables/GameList.vue')['default']
+ GameListDialog__UNUSED_NEEDS_EDITS: typeof import('./src/composables/GameListDialog__UNUSED_NEEDS_EDITS.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']
+ MarkdownRenderer: typeof import('./src/composables/MarkdownRenderer.vue')['default']
NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
diff --git a/src/components/EditorComponent.vue b/src/components/EditorComponent.vue
index eeb14ed..ffbd3df 100644
--- a/src/components/EditorComponent.vue
+++ b/src/components/EditorComponent.vue
@@ -22,11 +22,20 @@
-
+
-
+
@@ -37,16 +46,29 @@
-
+
-
+
Local Game
@@ -72,18 +94,34 @@
-
+
Learn more...
-
+
Edit
-
+
Delete
@@ -91,10 +129,22 @@
-
+
-
+
Copy to local
@@ -110,7 +160,11 @@
-
+
+
+
+
+
diff --git a/src/components/GeneratorComponent.vue b/src/components/GeneratorComponent.vue
index 6dba776..615f90f 100644
--- a/src/components/GeneratorComponent.vue
+++ b/src/components/GeneratorComponent.vue
@@ -9,9 +9,22 @@
>
-
+
{{ prop.node.label }}
-
+
{{ tag }}
@@ -19,9 +32,20 @@
-
+
{{ prop.node.label }}
-
+
Goal List
@@ -29,9 +53,20 @@
-
+
{{ prop.node.label }}
-
+
Category
@@ -40,21 +75,39 @@
-
+
-
+
-
+
@@ -126,8 +179,6 @@ const selectByTag = (tag: string) => {
ticked.value.push(...nodes.value.filter(node => {
return getAllGoals(node).map(goal => goal.tags.includes(tag));
}));
-
- console.log(ticked.value);
};
const nodes = computed(() => {
diff --git a/src/components/GoalEditorDialog.vue b/src/components/GoalEditorDialog.vue
deleted file mode 100644
index e69de29..0000000
diff --git a/src/composables/EditGoalDialog.vue b/src/composables/EditGoalDialog.vue
index 82055e4..0b5efb3 100644
--- a/src/composables/EditGoalDialog.vue
+++ b/src/composables/EditGoalDialog.vue
@@ -1,6 +1,10 @@
-
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/EditGoalListDialog.vue b/src/composables/EditGoalListDialog.vue
new file mode 100644
index 0000000..cbc5026
--- /dev/null
+++ b/src/composables/EditGoalListDialog.vue
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/GameEditorDialog.vue b/src/composables/GameEditorDialog.vue
new file mode 100644
index 0000000..45df176
--- /dev/null
+++ b/src/composables/GameEditorDialog.vue
@@ -0,0 +1,517 @@
+
+
+
+
+
+
+
+
{{ prop.node.item?.name || prop.node.label }}
+
+
+ {{ tag }}
+
+
+
+
+
+
+
openEditGoalListDialog(prop.node, event)"
+ />
+ {{ prop.node.item?.name || prop.node.label }}
+
+ Goal List
+
+
+
+
+
+
+
openEditCategoryDialog(prop.node, event)"
+ />
+ {{ prop.node.item?.name || prop.node.label }}
+
+ Category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ openEditGoalListDialog(prop.node, event)"
+ >
+
+
+
+
+
+
+ openEditCategoryDialog(prop.node, event)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/composables/GameList.vue b/src/composables/GameList.vue
deleted file mode 100644
index 2a5a944..0000000
--- a/src/composables/GameList.vue
+++ /dev/null
@@ -1,308 +0,0 @@
-
-
-
-
-
-
{{ prop.node.label }}
-
- {{ tag }}
-
-
-
-
-
-
-
-
{{ prop.node.label }}
-
- Goal List
-
-
-
-
-
-
-
-
{{ prop.node.label }}
-
- Category
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/composables/GameListDialog__UNUSED_NEEDS_EDITS.vue b/src/composables/GameListDialog__UNUSED_NEEDS_EDITS.vue
new file mode 100644
index 0000000..0b44164
--- /dev/null
+++ b/src/composables/GameListDialog__UNUSED_NEEDS_EDITS.vue
@@ -0,0 +1,355 @@
+
+ TODO: Show a big list with all games and let user tick things. Use that for generation.
+
+
+
+
+
diff --git a/src/components/MarkdownRenderer.vue b/src/composables/MarkdownRenderer.vue
similarity index 100%
rename from src/components/MarkdownRenderer.vue
rename to src/composables/MarkdownRenderer.vue
diff --git a/src/js/lib/BingoGame.ts b/src/js/lib/BingoGame.ts
index 33daf2a..707aa48 100644
--- a/src/js/lib/BingoGame.ts
+++ b/src/js/lib/BingoGame.ts
@@ -51,6 +51,24 @@ export default class BingoGame {
this.description = description;
}
+ get reserved_names(): string[] {
+ const names: string[] = [];
+
+ this.items.map(group => {
+ const goal_lists = group instanceof BingoGoalList ? [ group ] : group.goal_lists;
+
+ goal_lists.map(subgroup => {
+ subgroup.goals.map(goal => {
+ if (goal.name) {
+ names.push(goal.name);
+ }
+ });
+ });
+ });
+
+ return names;
+ }
+
addItem(group: BingoCategoryOrGoalList): SuccessResponse {
const existingGroup = this.items.find(g => g === group);
if (existingGroup) {
diff --git a/src/js/lib/BingoGoal.ts b/src/js/lib/BingoGoal.ts
index 25a6ba1..902a97b 100644
--- a/src/js/lib/BingoGoal.ts
+++ b/src/js/lib/BingoGoal.ts
@@ -7,6 +7,8 @@ import {
export default class BingoGoal {
name: string;
+ description: string = '';
+
tags: string[] = [];
possible_spaces: number[] = [];
diff --git a/src/js/lib/Parser.ts b/src/js/lib/Parser.ts
index 8d143df..bc0be0c 100644
--- a/src/js/lib/Parser.ts
+++ b/src/js/lib/Parser.ts
@@ -17,9 +17,16 @@ export default class Parser {
return game;
}
- static to_json(game: BingoGame): Record {
+ static to_json(game: BingoGame): JSON {
const json = instanceToPlain(game);
- return json;
+ return json as JSON;
+ }
+
+ static getCopy(game: BingoGame): BingoGame {
+ const json: JSON = this.to_json(game);
+ const copy = this.from_json_raw(json);
+
+ return copy;
}
}
diff --git a/src/stores/local-games.ts b/src/stores/local-games.ts
index 541ca83..b53ecd8 100644
--- a/src/stores/local-games.ts
+++ b/src/stores/local-games.ts
@@ -24,7 +24,6 @@ export const useLocalGamesStore = defineStore('localGames', () => {
games.value.length = 0;
- console.log(games_array);
games.value = games_array.map(game => {
const bingo_game = Parser.from_json_raw(game);
@@ -42,7 +41,6 @@ export const useLocalGamesStore = defineStore('localGames', () => {
// });
console.info('--- Finished fetching games!');
- console.log(games.value);
console.info('');
}
@@ -62,7 +60,7 @@ export const useLocalGamesStore = defineStore('localGames', () => {
return games.value.some(game => game.id === id);
}
- function addGame(game: BingoGame) {
+ async function addGame(game: BingoGame) {
if (hasGame(game.id)) {
console.error(`Failed to clone game with ID ${ game.id } because it already exists`);
@@ -76,10 +74,27 @@ export const useLocalGamesStore = defineStore('localGames', () => {
cloned_game.is_local = true;
games.value.push(cloned_game);
- saveGames();
+
+ await saveGames();
}
- function deleteGame(id: string) {
+ async function updateGame(game: BingoGame) {
+ if (!hasGame(game.id)) {
+ console.error(`Failed to update game with ID ${ game.id } because it doesn't exist`);
+
+ return;
+ }
+
+ console.info(`--- Updating game with ID '${ game.id }' ...`);
+
+ const index = games.value.findIndex(g => g.id === game.id);
+
+ games.value[index] = game;
+
+ await saveGames();
+ }
+
+ async function deleteGame(id: string) {
if (hasGame(id)) {
console.error(`Failed to delete game with ID ${ id } because it doesn't exist`);
@@ -89,7 +104,8 @@ export const useLocalGamesStore = defineStore('localGames', () => {
console.info(`--- Deleting game with ID '${ id }' ...`);
games.value = games.value.filter(game => game.id !== id);
- saveGames();
+
+ await saveGames();
}
return {
@@ -100,6 +116,7 @@ export const useLocalGamesStore = defineStore('localGames', () => {
hasGame,
addGame,
+ updateGame,
deleteGame
};
}, {
diff --git a/src/views/EditorPage.vue b/src/views/EditorPage.vue
index b76ce6c..5ffedf6 100644
--- a/src/views/EditorPage.vue
+++ b/src/views/EditorPage.vue
@@ -1,7 +1,7 @@
-
+
-
+