mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-24 23:59:45 +02:00
refactor(frontend): 🚧 Add group/user CRUD support for admins
This commit is contained in:
parent
917177da5b
commit
695d7e96ae
46 changed files with 2015 additions and 102 deletions
|
@ -5,7 +5,7 @@ export interface CrudAPIInterface {
|
|||
|
||||
// Route Properties / Methods
|
||||
baseRoute: string;
|
||||
itemRoute(itemId: string): string;
|
||||
itemRoute(itemId: string | number): string;
|
||||
|
||||
// Methods
|
||||
}
|
||||
|
@ -21,6 +21,10 @@ export const crudMixins = <T>(
|
|||
});
|
||||
}
|
||||
|
||||
async function createOne(payload: T) {
|
||||
return await requests.post<T>(baseRoute, payload);
|
||||
}
|
||||
|
||||
async function getOne(itemId: string) {
|
||||
return await requests.get<T>(itemRoute(itemId));
|
||||
}
|
||||
|
@ -37,14 +41,14 @@ export const crudMixins = <T>(
|
|||
return await requests.delete<T>(itemRoute(itemId));
|
||||
}
|
||||
|
||||
return { getAll, getOne, updateOne, patchOne, deleteOne };
|
||||
return { getAll, getOne, updateOne, patchOne, deleteOne, createOne };
|
||||
};
|
||||
|
||||
export abstract class BaseAPIClass<T> implements CrudAPIInterface {
|
||||
export abstract class BaseAPIClass<T, U> implements CrudAPIInterface {
|
||||
requests: ApiRequestInstance;
|
||||
|
||||
abstract baseRoute: string;
|
||||
abstract itemRoute(itemId: string): string;
|
||||
abstract itemRoute(itemId: string | number): string;
|
||||
|
||||
constructor(requests: ApiRequestInstance) {
|
||||
this.requests = requests;
|
||||
|
@ -56,6 +60,10 @@ export abstract class BaseAPIClass<T> implements CrudAPIInterface {
|
|||
});
|
||||
}
|
||||
|
||||
async createOne(payload: U) {
|
||||
return await this.requests.post<T>(this.baseRoute, payload);
|
||||
}
|
||||
|
||||
async getOne(itemId: string) {
|
||||
return await this.requests.get<T>(this.itemRoute(itemId));
|
||||
}
|
||||
|
@ -68,7 +76,7 @@ export abstract class BaseAPIClass<T> implements CrudAPIInterface {
|
|||
return await this.requests.patch(this.itemRoute(itemId), payload);
|
||||
}
|
||||
|
||||
async deleteOne(itemId: string) {
|
||||
async deleteOne(itemId: string | number) {
|
||||
return await this.requests.delete<T>(this.itemRoute(itemId));
|
||||
}
|
||||
}
|
||||
|
|
26
frontend/api/class-interfaces/groups.ts
Normal file
26
frontend/api/class-interfaces/groups.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { requests } from "../requests";
|
||||
import { BaseAPIClass } from "./_base";
|
||||
import { GroupInDB } from "~/types/api-types/user";
|
||||
|
||||
const prefix = "/api";
|
||||
|
||||
const routes = {
|
||||
groups: `${prefix}/groups`,
|
||||
groupsSelf: `${prefix}/groups/self`,
|
||||
|
||||
groupsId: (id: string | number) => `${prefix}/groups/${id}`,
|
||||
};
|
||||
|
||||
export interface CreateGroup {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export class GroupAPI extends BaseAPIClass<GroupInDB, CreateGroup> {
|
||||
baseRoute = routes.groups;
|
||||
itemRoute = routes.groupsId;
|
||||
/** Returns the Group Data for the Current User
|
||||
*/
|
||||
async getCurrentUserGroup() {
|
||||
return await requests.get(routes.groupsSelf);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
import { BaseAPIClass, crudMixins } from "./_base";
|
||||
import { BaseAPIClass } from "./_base";
|
||||
import { Recipe } from "~/types/api-types/admin";
|
||||
import { ApiRequestInstance } from "~/types/api";
|
||||
import { CreateRecipe } from "~/types/api-types/recipe";
|
||||
|
||||
const prefix = "/api";
|
||||
|
||||
const routes = {
|
||||
recipesCreate: `${prefix}/recipes/create`,
|
||||
recipesBase: `${prefix}/recipes`,
|
||||
recipesSummary: `${prefix}/recipes/summary`,
|
||||
recipesTestScrapeUrl: `${prefix}/recipes/test-scrape-url`,
|
||||
recipesCreateUrl: `${prefix}/recipes/create-url`,
|
||||
recipesCreateFromZip: `${prefix}/recipes/create-from-zip`,
|
||||
|
@ -19,25 +18,10 @@ const routes = {
|
|||
recipesRecipeSlugAssets: (recipe_slug: string) => `${prefix}/recipes/${recipe_slug}/assets`,
|
||||
};
|
||||
|
||||
export class RecipeAPI extends BaseAPIClass<Recipe> {
|
||||
baseRoute: string = routes.recipesSummary;
|
||||
export class RecipeAPI extends BaseAPIClass<Recipe, CreateRecipe> {
|
||||
baseRoute: string = routes.recipesBase;
|
||||
itemRoute = routes.recipesRecipeSlug;
|
||||
|
||||
constructor(requests: ApiRequestInstance) {
|
||||
super(requests);
|
||||
const { getAll, getOne, updateOne, patchOne, deleteOne } = crudMixins<Recipe>(
|
||||
requests,
|
||||
routes.recipesSummary,
|
||||
routes.recipesRecipeSlug
|
||||
);
|
||||
|
||||
this.getAll = getAll;
|
||||
this.getOne = getOne;
|
||||
this.updateOne = updateOne;
|
||||
this.patchOne = patchOne;
|
||||
this.deleteOne = deleteOne;
|
||||
}
|
||||
|
||||
async getAllByCategory(categories: string[]) {
|
||||
return await this.requests.get<Recipe[]>(routes.recipesCategory, {
|
||||
categories,
|
||||
|
@ -56,10 +40,6 @@ export class RecipeAPI extends BaseAPIClass<Recipe> {
|
|||
return this.requests.post(routes.recipesRecipeSlugImage(slug), { url });
|
||||
}
|
||||
|
||||
async createOne(name: string) {
|
||||
return await this.requests.post<Recipe>(routes.recipesBase, { name });
|
||||
}
|
||||
|
||||
async createOneByUrl(url: string) {
|
||||
return await this.requests.post(routes.recipesCreateUrl, { url });
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
import { BaseAPIClass } from "./_base";
|
||||
import { UserOut } from "~/types/api-types/user";
|
||||
import { UserIn, UserOut } from "~/types/api-types/user";
|
||||
|
||||
// Interfaces
|
||||
|
||||
interface ChangePassword {
|
||||
currentPassword: string;
|
||||
newPassword: string;
|
||||
}
|
||||
|
||||
interface CreateAPIToken {
|
||||
name: string;
|
||||
}
|
||||
|
||||
// Code
|
||||
|
||||
const prefix = "/api";
|
||||
|
||||
|
@ -13,19 +26,45 @@ const routes = {
|
|||
usersIdPassword: (id: string) => `${prefix}/users/${id}/password`,
|
||||
usersIdFavorites: (id: string) => `${prefix}/users/${id}/favorites`,
|
||||
usersIdFavoritesSlug: (id: string, slug: string) => `${prefix}/users/${id}/favorites/${slug}`,
|
||||
|
||||
usersApiTokens: `${prefix}/users/api-tokens`,
|
||||
usersApiTokensTokenId: (token_id: string) => `${prefix}/users/api-tokens/${token_id}`,
|
||||
};
|
||||
|
||||
export class UserApi extends BaseAPIClass<UserOut> {
|
||||
baseRoute: string = routes.users;
|
||||
itemRoute = (itemid: string) => routes.usersId(itemid);
|
||||
export class UserApi extends BaseAPIClass<UserOut, UserIn> {
|
||||
baseRoute: string = routes.users;
|
||||
itemRoute = (itemid: string) => routes.usersId(itemid);
|
||||
|
||||
async addFavorite(id: string, slug: string) {
|
||||
const response = await this.requests.post(routes.usersIdFavoritesSlug(id, slug), {});
|
||||
return response.data;
|
||||
}
|
||||
async addFavorite(id: string, slug: string) {
|
||||
return await this.requests.post(routes.usersIdFavoritesSlug(id, slug), {});
|
||||
}
|
||||
|
||||
async removeFavorite(id: string, slug: string) {
|
||||
const response = await this.requests.delete(routes.usersIdFavoritesSlug(id, slug));
|
||||
return response.data;
|
||||
}
|
||||
async removeFavorite(id: string, slug: string) {
|
||||
return await this.requests.delete(routes.usersIdFavoritesSlug(id, slug));
|
||||
}
|
||||
|
||||
async getFavorites(id: string) {
|
||||
await this.requests.get(routes.usersIdFavorites(id));
|
||||
}
|
||||
|
||||
async changePassword(id: string, changePassword: ChangePassword) {
|
||||
return await this.requests.put(routes.usersIdPassword(id), changePassword);
|
||||
}
|
||||
|
||||
async resetPassword(id: string) {
|
||||
return await this.requests.post(routes.usersIdResetPassword(id), {});
|
||||
}
|
||||
|
||||
async createAPIToken(tokenName: CreateAPIToken) {
|
||||
return await this.requests.post(routes.usersApiTokens, tokenName);
|
||||
}
|
||||
|
||||
async deleteApiToken(tokenId: string) {
|
||||
return await this.requests.delete(routes.usersApiTokensTokenId(tokenId));
|
||||
}
|
||||
|
||||
userProfileImage(id: string) {
|
||||
if (!id || id === undefined) return;
|
||||
return `/api/users/${id}/image`;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue