Compare commits
No commits in common. "b2c70a66573caafb21a530b2a4aa40b559969e6b" and "8e552ba5088d8bdda91e3256c7d7d06a6dbd8b4b" have entirely different histories.
b2c70a6657
...
8e552ba508
|
@ -70,11 +70,10 @@ export const useMainStore = defineStore({
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
try {
|
try {
|
||||||
const { data } = await api.post<FG.Session>('/auth', { userid, password });
|
const { data } = await api.post<FG.Session>('/auth', { userid, password });
|
||||||
this.session = fixSession(data);
|
|
||||||
this.user = await userStore.getUser(data.userid, true);
|
this.user = await userStore.getUser(data.userid, true);
|
||||||
|
this.session = fixSession(data);
|
||||||
return true;
|
return true;
|
||||||
} catch ({ response }) {
|
} catch ({ response }) {
|
||||||
this.handleLoggedOut();
|
|
||||||
return (<AxiosResponse | undefined>response)?.status || false;
|
return (<AxiosResponse | undefined>response)?.status || false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,153 +6,86 @@ export function fixUser(u?: FG.User) {
|
||||||
return !u ? u : Object.assign(u, { birthday: u.birthday ? new Date(u.birthday) : undefined });
|
return !u ? u : Object.assign(u, { birthday: u.birthday ? new Date(u.birthday) : undefined });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if state is outdated / dirty
|
|
||||||
* Value is considered outdated after 15 minutes
|
|
||||||
* @param updated Time of last updated (in milliseconds see Date.now())
|
|
||||||
* @returns True if outdated, false otherwise
|
|
||||||
*/
|
|
||||||
function isDirty(updated: number) {
|
|
||||||
return Date.now() - updated > 15 * 60 * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useUserStore = defineStore({
|
export const useUserStore = defineStore({
|
||||||
id: 'users',
|
id: 'users',
|
||||||
|
|
||||||
state: () => ({
|
state: () => ({
|
||||||
roles: [] as FG.Role[],
|
roles: [] as FG.Role[],
|
||||||
|
users: [] as FG.User[],
|
||||||
permissions: [] as FG.Permission[],
|
permissions: [] as FG.Permission[],
|
||||||
// list of all users, include deleted ones, use `users` getter for list of active ones
|
_dirty_users: true,
|
||||||
_users: [] as FG.User[],
|
_dirty_roles: true,
|
||||||
// Internal flags for deciding if lists need to force-loaded
|
|
||||||
_dirty_users: 0,
|
|
||||||
_dirty_roles: 0,
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getters: {
|
getters: {},
|
||||||
users(state) {
|
|
||||||
return state._users.filter((u) => !u.deleted);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
/** Simply filter all users by ID */
|
|
||||||
findUser(userid: string) {
|
findUser(userid: string) {
|
||||||
return this._users.find((user) => user.userid === userid);
|
return this.users.find((user) => user.userid === userid);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Retrieve user by ID
|
|
||||||
* @param userid ID of user to retrieve
|
|
||||||
* @param force If set to true the user is loaded from backend even when a local copy is available
|
|
||||||
* @returns Retrieved user (Promise) or raise an error
|
|
||||||
* @throws Probably an AxiosError if loading failed
|
|
||||||
*/
|
|
||||||
async getUser(userid: string, force = false) {
|
async getUser(userid: string, force = false) {
|
||||||
const idx = this._users.findIndex((user) => user.userid === userid);
|
const idx = this.users.findIndex((user) => user.userid === userid);
|
||||||
if (force || idx === -1 || isDirty(this._dirty_users)) {
|
if (force || this._dirty_users || idx === -1) {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get<FG.User>(`/users/${userid}`);
|
const { data } = await api.get<FG.User>(`/users/${userid}`);
|
||||||
fixUser(data);
|
fixUser(data);
|
||||||
if (idx === -1) this._users.push(data);
|
if (idx === -1) this.users.push(data);
|
||||||
else this._users[idx] = data;
|
else this.users[idx] = data;
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore 404, throw all other
|
// Ignore 404, throw all other
|
||||||
if (!isAxiosError(error, 404)) throw error;
|
if (!isAxiosError(error, 404)) throw error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return this._users[idx];
|
return this.users[idx];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Retrieve list of all users
|
|
||||||
* @param force If set to true a fresh users list is loaded from backend even when a local copy is available
|
|
||||||
* @returns Array of retrieved users (Promise)
|
|
||||||
* @throws Probably an AxiosError if loading failed
|
|
||||||
*/
|
|
||||||
async getUsers(force = false) {
|
async getUsers(force = false) {
|
||||||
if (force || isDirty(this._dirty_users)) {
|
if (force || this._dirty_users) {
|
||||||
const { data } = await api.get<FG.User[]>('/users');
|
const { data } = await api.get<FG.User[]>('/users');
|
||||||
data.forEach(fixUser);
|
data.forEach(fixUser);
|
||||||
this._users = data;
|
this.users = data;
|
||||||
this._dirty_users = Date.now();
|
this._dirty_users = false;
|
||||||
}
|
}
|
||||||
return this._users;
|
return this.users;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Save modifications of user on backend
|
|
||||||
* @param user Modified user to save
|
|
||||||
* @throws Probably an AxiosError if request failed (404 = Invalid userid, 400 = Invalid data)
|
|
||||||
*/
|
|
||||||
async updateUser(user: FG.User) {
|
async updateUser(user: FG.User) {
|
||||||
await api.put(`/users/${user.userid}`, user);
|
await api.put(`/users/${user.userid}`, user);
|
||||||
// Modifcation accepted by backend
|
|
||||||
// Save modifications back to our users list
|
|
||||||
const idx = this._users.findIndex((u) => u.userid === user.userid);
|
|
||||||
if (idx > -1) this._users[idx] = user;
|
|
||||||
// If user was current user, save modifications back to the main store
|
|
||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
if (user.userid === mainStore.user?.userid) mainStore.user = user;
|
if (user.userid === mainStore.user?.userid) mainStore.user = user;
|
||||||
|
this._dirty_users = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Register a new user
|
|
||||||
* @param user User to register (id not set)
|
|
||||||
* @returns The registered user (id set)
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async createUser(user: FG.User) {
|
async createUser(user: FG.User) {
|
||||||
const { data } = await api.post<FG.User>('/users', user);
|
const { data } = await api.post<FG.User>('/users', user);
|
||||||
this._users.push(<FG.User>fixUser(data));
|
this.users.push(data);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Delete an user
|
|
||||||
* Throws if failed and resolves void if succeed
|
|
||||||
*
|
|
||||||
* @param user User or ID of user to delete
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async deleteUser(user: FG.User | string) {
|
async deleteUser(user: FG.User | string) {
|
||||||
if (typeof user === 'object') user = user.userid;
|
if (typeof user === 'object') user = user.userid;
|
||||||
|
|
||||||
await api.delete(`/users/${user}`);
|
await api.delete(`/users/${user}`);
|
||||||
this._users = this._users.filter((u) => u.userid != user);
|
this.users = this.users.filter(u => u.userid != user);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Upload an avatar for an user
|
async uploadAvatar(user: FG.User, file: string | File) {
|
||||||
* Throws if failed and resolves void if succeed
|
|
||||||
*
|
|
||||||
* @param user User or ID of user
|
|
||||||
* @param file Avatar file to upload
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async uploadAvatar(user: FG.User | string, file: string | File) {
|
|
||||||
if (typeof user === 'object') user = user.userid;
|
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
await api.post(`/users/${user}/avatar`, formData, {
|
await api.post(`/users/${user.userid}/avatar`, formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Delete avatar of an user
|
async deleteAvatar(user: FG.User) {
|
||||||
* @param user User or ID of user
|
await api.delete(`/users/${user.userid}/avatar`);
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async deleteAvatar(user: FG.User | string) {
|
|
||||||
if (typeof user === 'object') user = user.userid;
|
|
||||||
|
|
||||||
await api.delete(`/users/${user}/avatar`);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Retrieve list of all permissions
|
|
||||||
* @param force If set to true a fresh list is loaded from backend even when a local copy is available
|
|
||||||
* @returns Array of retrieved permissions (Promise)
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async getPermissions(force = false) {
|
async getPermissions(force = false) {
|
||||||
if (force || this.permissions.length === 0) {
|
if (force || this.permissions.length === 0) {
|
||||||
const { data } = await api.get<FG.Permission[]>('/roles/permissions');
|
const { data } = await api.get<FG.Permission[]>('/roles/permissions');
|
||||||
|
@ -161,51 +94,39 @@ export const useUserStore = defineStore({
|
||||||
return this.permissions;
|
return this.permissions;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Retrieve list of all roles
|
|
||||||
* @param force If set to true a fresh list is loaded from backend even when a local copy is available
|
|
||||||
* @returns Array of retrieved roles (Promise)
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async getRoles(force = false) {
|
async getRoles(force = false) {
|
||||||
if (force || isDirty(this._dirty_roles)) {
|
if (force || this._dirty_roles) {
|
||||||
const { data } = await api.get<FG.Role[]>('/roles');
|
const { data } = await api.get<FG.Role[]>('/roles');
|
||||||
this.roles = data;
|
this.roles = data;
|
||||||
this._dirty_roles = Date.now();
|
this._dirty_roles = false;
|
||||||
}
|
}
|
||||||
return this.roles;
|
return this.roles;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Save modifications of role on the backend
|
|
||||||
* @param role role to save
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async updateRole(role: FG.Role) {
|
async updateRole(role: FG.Role) {
|
||||||
await api.put(`/roles/${role.id}`, role);
|
try {
|
||||||
|
await api.put(`/roles/${role.id}`, role);
|
||||||
const idx = this.roles.findIndex((r) => r.id === role.id);
|
} catch (error) {
|
||||||
if (idx != -1) this.roles[idx] = role;
|
console.warn(error);
|
||||||
else this._dirty_roles = 0;
|
}
|
||||||
|
this._updatePermission(role);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updatePermission(role: FG.Role) {
|
||||||
|
const idx = this.roles.findIndex((r) => r.id === role.id);
|
||||||
|
if (idx != -1) this.roles[idx] = role;
|
||||||
|
this._dirty_roles = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Create a new role
|
|
||||||
* @param role Role to create (ID not set)
|
|
||||||
* @returns Created role (ID set)
|
|
||||||
* @throws Probably an AxiosError if request failed
|
|
||||||
*/
|
|
||||||
async newRole(role: FG.Role) {
|
async newRole(role: FG.Role) {
|
||||||
const { data } = await api.post<FG.Role>('/roles', role);
|
const { data } = await api.post<FG.Role>('/roles', role);
|
||||||
this.roles.push(data);
|
this.roles.push(data);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Delete a role
|
|
||||||
* @param role Role or ID of role to delete
|
|
||||||
* @throws Probably an AxiosError if request failed (409 if role still in use)
|
|
||||||
*/
|
|
||||||
async deleteRole(role: FG.Role | number) {
|
async deleteRole(role: FG.Role | number) {
|
||||||
if (typeof role === 'object') role = role.id;
|
await api.delete(`/roles/${typeof role === 'number' ? role : role.id}`);
|
||||||
await api.delete(`/roles/${role}`);
|
this.roles = this.roles.filter((r) => r.id !== (typeof role == 'number' ? role : role.id));
|
||||||
this.roles = this.roles.filter((r) => r.id !== role);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue