192 lines
4.8 KiB
JavaScript
192 lines
4.8 KiB
JavaScript
/**
|
|
* Store.js - global app state.
|
|
*
|
|
* Part of the basebox sample TODO app.
|
|
* https://basebox.io
|
|
*/
|
|
import { reactive } from 'vue'
|
|
import {gqlRequest} from "./util/net";
|
|
|
|
export const store = reactive({
|
|
|
|
/** User display name of the currently logged-in user */
|
|
userDisplayName: "stranger",
|
|
|
|
/* Unique user id of the currently logged in user */
|
|
userId: "",
|
|
|
|
/** base URL of basebox broker host */
|
|
baseboxHost: import.meta.env.BASEBOX_HOST || "http://127.0.0.1:8080",
|
|
|
|
/** User as returned from oidc-client */
|
|
user: null,
|
|
|
|
/** Fatal error message, if any */
|
|
fatalError: "",
|
|
|
|
/* array of todo lists currently known */
|
|
lists: [],
|
|
/* known tasks */
|
|
tasks: [],
|
|
|
|
});
|
|
|
|
/**
|
|
* Return true if the user is logged in.
|
|
*/
|
|
export function loggedIn() {
|
|
return store.user !== null;
|
|
}
|
|
|
|
/**
|
|
* Clear session data.
|
|
*/
|
|
export function clearSession() {
|
|
store.user = null;
|
|
store.userDisplayName = "stranger";
|
|
}
|
|
|
|
/**
|
|
* Show an error.
|
|
*/
|
|
export function showError(message) {
|
|
store.fatalError = message;
|
|
}
|
|
|
|
/**
|
|
* Clear error.
|
|
*/
|
|
export function clearError() {
|
|
store.fatalError = "";
|
|
}
|
|
|
|
/**
|
|
* Remove a task from the store.
|
|
*
|
|
* This does not remove it from the database/server!
|
|
*/
|
|
export function removeTask(task) {
|
|
const idx = store.tasks.findIndex(item => item.id === task.id);
|
|
if (idx !== -1) {
|
|
store.tasks.splice(idx, 1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize data store and database.
|
|
*
|
|
* Must be called by the OAuth login completion handler as soon as session data is available.
|
|
*
|
|
* If this is the first run, we need to create the logged on user, since he/she is so far known
|
|
* only to the OpenID Connect server (Keycloak).
|
|
*
|
|
* Additionally, we also create the default list here and save everything in the store.
|
|
*
|
|
* @param user - the user as returned from oidc-client.
|
|
*/
|
|
export async function storeInit(user) {
|
|
|
|
/* save user session in the store */
|
|
store.user = user;
|
|
|
|
store.userDisplayName = user.profile.nickname || "Logged In Stranger";
|
|
|
|
/* The unique user ID is the 'sub' field from the ID token. */
|
|
store.userId = user.profile.sub;
|
|
|
|
/* Create user and default list.
|
|
* We cannot run these requests in parallel, since the user record must exist in the database
|
|
* before we can create the default list.
|
|
*/
|
|
try {
|
|
console.info("NOTE: If next request fails, it is probably because the user already exists. In this case, the error is ignored.");
|
|
await gqlRequest(`mutation {
|
|
createUser(
|
|
username: "${store.userId}",
|
|
name: "${store.userDisplayName}"
|
|
) {
|
|
username
|
|
}
|
|
}`);
|
|
} catch(e) {
|
|
const errStr = e.toString();
|
|
if (errStr.indexOf("already exists") === -1) {
|
|
/* this is an error */
|
|
const e = `Failed to create user: ${errStr}`;
|
|
console.error(e);
|
|
showError(e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Load user info, lists and todos. */
|
|
gqlRequest(`query {
|
|
getUser(username: "${store.userId}") {
|
|
name
|
|
lists {
|
|
id
|
|
title
|
|
}
|
|
tasks {
|
|
id
|
|
title
|
|
description
|
|
completed
|
|
list {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
}`).then(data => {
|
|
store.lists = data.getUser.lists ? data.getUser.lists : [];
|
|
store.tasks = data.getUser.tasks ? data.getUser.tasks : [];
|
|
/* create default list if necessary */
|
|
if (store.lists.length === 0) {
|
|
console.info("No lists found for current user; creating default list.");
|
|
gqlRequest(`mutation {
|
|
createList(
|
|
title: "Default",
|
|
user: { username: "${store.userId}" }
|
|
) {
|
|
title
|
|
id
|
|
}
|
|
}`).then(data => {
|
|
/* Save new default list in store */
|
|
store.lists.push(data.createList);
|
|
});
|
|
}
|
|
|
|
/* fix for basebox bug: task.list is returned as an array of List objects, where we expect just a single object */
|
|
for (const task of store.tasks) {
|
|
if (Array.isArray(task.list)) {
|
|
task.list = task.list[0];
|
|
}
|
|
}
|
|
|
|
}).catch(err => {
|
|
const e = `Failed to load user/data: ${err.toString()}`;
|
|
console.error(e);
|
|
showError(e);
|
|
});
|
|
|
|
}
|
|
|
|
|
|
const testData = {
|
|
lists: [
|
|
{ id: 1, title: "Default"},
|
|
{ id: 2, title: "House" },
|
|
{ id: 3, title: "Car" },
|
|
{ id: 4, title: "Work" },
|
|
],
|
|
/* known tasks */
|
|
tasks: [
|
|
{ id: 1, completed: false, title: "Go to dentist", description: "Last time is way too long ago...", list: { id: 1 } },
|
|
{ id: 2, completed: true, title: "Change engine oil", description: "Use the good one", list: { id: 3 } },
|
|
{ id: 3, completed: false, title: "Clean windows", description: "Regualar stuff", list: { id: 1 } },
|
|
{ id: 4, completed: false, title: "Oil stove hinges", description: "They are stiff and screechy", list: { id: 2 } },
|
|
{ id: 5, completed: false, title: "Do more benchmarking", description: "Find out how fast this thing really is", list: { id: 4 } },
|
|
],
|
|
|
|
}; |