[WEB-3065] refactor: replace admin services with service packages (#6342)

* [WEB-3065] refactor: replace admin services with service packages

* chore: minor updates

* chore: error handling
This commit is contained in:
Prateek Shourya 2025-01-07 19:07:47 +05:30 committed by GitHub
parent ae657af958
commit 200be0ac7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 240 additions and 284 deletions

View File

@ -1,9 +1,9 @@
import React, { FC, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
// plane imports
import { InstanceService } from "@plane/services";
// ui
import { Button, Input } from "@plane/ui";
// services
import { InstanceService } from "@/services/instance.service";
type Props = {
isOpen: boolean;

View File

@ -2,18 +2,16 @@ import { useState, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Controller, useForm } from "react-hook-form";
// constants
// plane imports
import { WEB_BASE_URL, ORGANIZATION_SIZE, RESTRICTED_URLS } from "@plane/constants";
// types
import { InstanceWorkspaceService } from "@plane/services";
import { IWorkspace } from "@plane/types";
// components
import { Button, CustomSelect, getButtonStyling, Input, setToast, TOAST_TYPE } from "@plane/ui";
// hooks
import { useWorkspace } from "@/hooks/store";
// services
import { WorkspaceService } from "@/services/workspace.service";
const workspaceService = new WorkspaceService();
const instanceWorkspaceService = new InstanceWorkspaceService();
export const WorkspaceCreateForm = () => {
// router
@ -40,8 +38,8 @@ export const WorkspaceCreateForm = () => {
const workspaceBaseURL = encodeURI(WEB_BASE_URL || window.location.origin + "/");
const handleCreateWorkspace = async (formData: IWorkspace) => {
await workspaceService
.workspaceSlugCheck(formData.slug)
await instanceWorkspaceService
.slugCheck(formData.slug)
.then(async (res) => {
if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) {
setSlugError(false);

View File

@ -7,12 +7,11 @@ import { LogOut, UserCog2, Palette } from "lucide-react";
import { Menu, Transition } from "@headlessui/react";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import {AuthService } from "@plane/services";
import { Avatar } from "@plane/ui";
import { getFileURL, cn } from "@plane/utils";
// hooks
import { useTheme, useUser } from "@/hooks/store";
// services
import { AuthService } from "@/services/auth.service";
// service initialization
const authService = new AuthService();

View File

@ -6,12 +6,11 @@ import { useSearchParams } from "next/navigation";
import { Eye, EyeOff } from "lucide-react";
// plane internal packages
import { API_BASE_URL, E_PASSWORD_STRENGTH } from "@plane/constants";
import { AuthService } from "@plane/services";
import { Button, Checkbox, Input, Spinner } from "@plane/ui";
import { getPasswordStrength } from "@plane/utils";
// components
import { Banner, PasswordStrengthMeter } from "@/components/common";
// services
import { AuthService } from "@/services/auth.service";
// service initialization
const authService = new AuthService();

View File

@ -5,13 +5,12 @@ import { useSearchParams } from "next/navigation";
import { Eye, EyeOff } from "lucide-react";
// plane internal packages
import { API_BASE_URL, EAdminAuthErrorCodes, TAuthErrorInfo } from "@plane/constants";
import { AuthService } from "@plane/services";
import { Button, Input, Spinner } from "@plane/ui";
// components
import { Banner } from "@/components/common";
// helpers
import { authErrorHandler } from "@/lib/auth-helpers";
// services
import { AuthService } from "@/services/auth.service";
// local components
import { AuthBanner } from "../authentication";

View File

@ -1,53 +0,0 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
// store
// import { rootStore } from "@/lib/store-context";
export abstract class APIService {
protected baseURL: string;
private axiosInstance: AxiosInstance;
constructor(baseURL: string) {
this.baseURL = baseURL;
this.axiosInstance = axios.create({
baseURL,
withCredentials: true,
});
this.setupInterceptors();
}
private setupInterceptors() {
// this.axiosInstance.interceptors.response.use(
// (response) => response,
// (error) => {
// const store = rootStore;
// if (error.response && error.response.status === 401 && store.user.currentUser) store.user.reset();
// return Promise.reject(error);
// }
// );
}
get<ResponseType>(url: string, params = {}): Promise<AxiosResponse<ResponseType>> {
return this.axiosInstance.get(url, { params });
}
post<RequestType, ResponseType>(url: string, data: RequestType, config = {}): Promise<AxiosResponse<ResponseType>> {
return this.axiosInstance.post(url, data, config);
}
put<RequestType, ResponseType>(url: string, data: RequestType, config = {}): Promise<AxiosResponse<ResponseType>> {
return this.axiosInstance.put(url, data, config);
}
patch<RequestType, ResponseType>(url: string, data: RequestType, config = {}): Promise<AxiosResponse<ResponseType>> {
return this.axiosInstance.patch(url, data, config);
}
delete<RequestType>(url: string, data?: RequestType, config = {}) {
return this.axiosInstance.delete(url, { data, ...config });
}
request<T>(config: AxiosRequestConfig = {}): Promise<AxiosResponse<T>> {
return this.axiosInstance(config);
}
}

View File

@ -1,21 +0,0 @@
import { API_BASE_URL } from "@plane/constants";
// services
import { APIService } from "@/services/api.service";
type TCsrfTokenResponse = {
csrf_token: string;
};
export class AuthService extends APIService {
constructor() {
super(API_BASE_URL);
}
async requestCSRFToken(): Promise<TCsrfTokenResponse> {
return this.get<TCsrfTokenResponse>("/auth/get-csrf-token/")
.then((response) => response.data)
.catch((error) => {
throw error;
});
}
}

View File

@ -1,72 +0,0 @@
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import type {
IFormattedInstanceConfiguration,
IInstance,
IInstanceAdmin,
IInstanceConfiguration,
IInstanceInfo,
} from "@plane/types";
// helpers
import { APIService } from "@/services/api.service";
export class InstanceService extends APIService {
constructor() {
super(API_BASE_URL);
}
async getInstanceInfo(): Promise<IInstanceInfo> {
return this.get<IInstanceInfo>("/api/instances/")
.then((response) => response.data)
.catch((error) => {
throw error?.response?.data;
});
}
async getInstanceAdmins(): Promise<IInstanceAdmin[]> {
return this.get<IInstanceAdmin[]>("/api/instances/admins/")
.then((response) => response.data)
.catch((error) => {
throw error;
});
}
async updateInstanceInfo(data: Partial<IInstance>): Promise<IInstance> {
return this.patch<Partial<IInstance>, IInstance>("/api/instances/", data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async getInstanceConfigurations() {
return this.get<IInstanceConfiguration[]>("/api/instances/configurations/")
.then((response) => response.data)
.catch((error) => {
throw error;
});
}
async updateInstanceConfigurations(
data: Partial<IFormattedInstanceConfiguration>
): Promise<IInstanceConfiguration[]> {
return this.patch<Partial<IFormattedInstanceConfiguration>, IInstanceConfiguration[]>(
"/api/instances/configurations/",
data
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async sendTestEmail(receiverEmail: string): Promise<undefined> {
return this.post<{ receiver_email: string }, undefined>("/api/instances/email-credentials-check/", {
receiver_email: receiverEmail,
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
}

View File

@ -1,29 +0,0 @@
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import type { IUser } from "@plane/types";
// services
import { APIService } from "@/services/api.service";
interface IUserSession extends IUser {
isAuthenticated: boolean;
}
export class UserService extends APIService {
constructor() {
super(API_BASE_URL);
}
async authCheck(): Promise<IUserSession> {
return this.get<any>("/api/instances/admins/me/")
.then((response) => ({ ...response?.data, isAuthenticated: true }))
.catch(() => ({ isAuthenticated: false }));
}
async currentUser(): Promise<IUser> {
return this.get<IUser>("/api/instances/admins/me/")
.then((response) => response?.data)
.catch((error) => {
throw error?.response;
});
}
}

View File

@ -1,52 +0,0 @@
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import type { IWorkspace, TWorkspacePaginationInfo } from "@plane/types";
// services
import { APIService } from "@/services/api.service";
export class WorkspaceService extends APIService {
constructor() {
super(API_BASE_URL);
}
/**
* @description Fetches all workspaces
* @returns Promise<TWorkspacePaginationInfo>
*/
async getWorkspaces(nextPageCursor?: string): Promise<TWorkspacePaginationInfo> {
return this.get<TWorkspacePaginationInfo>("/api/instances/workspaces/", {
cursor: nextPageCursor,
})
.then((response) => response.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* @description Checks if a slug is available
* @param slug - string
* @returns Promise<any>
*/
async workspaceSlugCheck(slug: string): Promise<any> {
const params = new URLSearchParams({ slug });
return this.get(`/api/instances/workspace-slug-check/?${params.toString()}`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* @description Creates a new workspace
* @param data - IWorkspace
* @returns Promise<IWorkspace>
*/
async createWorkspace(data: IWorkspace): Promise<IWorkspace> {
return this.post<IWorkspace, IWorkspace>("/api/instances/workspaces/", data)
.then((response) => response.data)
.catch((error) => {
throw error?.response?.data;
});
}
}

View File

@ -2,6 +2,7 @@ import set from "lodash/set";
import { observable, action, computed, makeObservable, runInAction } from "mobx";
// plane internal packages
import { EInstanceStatus, TInstanceStatus } from "@plane/constants";
import {InstanceService} from "@plane/services";
import {
IInstance,
IInstanceAdmin,
@ -10,8 +11,6 @@ import {
IInstanceInfo,
IInstanceConfig,
} from "@plane/types";
// services
import { InstanceService } from "@/services/instance.service";
// root store
import { CoreRootStore } from "@/store/root.store";
@ -96,7 +95,7 @@ export class InstanceStore implements IInstanceStore {
try {
if (this.instance === undefined) this.isLoading = true;
this.error = undefined;
const instanceInfo = await this.instanceService.getInstanceInfo();
const instanceInfo = await this.instanceService.info();
// handling the new user popup toggle
if (this.instance === undefined && !instanceInfo?.instance?.workspaces_exist)
this.store.theme.toggleNewUserPopup();
@ -125,7 +124,7 @@ export class InstanceStore implements IInstanceStore {
*/
updateInstanceInfo = async (data: Partial<IInstance>) => {
try {
const instanceResponse = await this.instanceService.updateInstanceInfo(data);
const instanceResponse = await this.instanceService.update(data);
if (instanceResponse) {
runInAction(() => {
if (this.instance) set(this.instance, "instance", instanceResponse);
@ -144,7 +143,7 @@ export class InstanceStore implements IInstanceStore {
*/
fetchInstanceAdmins = async () => {
try {
const instanceAdmins = await this.instanceService.getInstanceAdmins();
const instanceAdmins = await this.instanceService.admins();
if (instanceAdmins) runInAction(() => (this.instanceAdmins = instanceAdmins));
return instanceAdmins;
} catch (error) {
@ -159,7 +158,7 @@ export class InstanceStore implements IInstanceStore {
*/
fetchInstanceConfigurations = async () => {
try {
const instanceConfigurations = await this.instanceService.getInstanceConfigurations();
const instanceConfigurations = await this.instanceService.configurations();
if (instanceConfigurations) runInAction(() => (this.instanceConfigurations = instanceConfigurations));
return instanceConfigurations;
} catch (error) {
@ -174,7 +173,7 @@ export class InstanceStore implements IInstanceStore {
*/
updateInstanceConfigurations = async (data: Partial<IFormattedInstanceConfiguration>) => {
try {
const response = await this.instanceService.updateInstanceConfigurations(data);
const response = await this.instanceService.updateConfigurations(data);
runInAction(() => {
this.instanceConfigurations = this.instanceConfigurations?.map((config) => {
const item = response.find((item) => item.key === config.key);

View File

@ -1,10 +1,8 @@
import { action, observable, runInAction, makeObservable } from "mobx";
// plane internal packages
import { EUserStatus, TUserStatus } from "@plane/constants";
import { AuthService, UserService } from "@plane/services";
import { IUser } from "@plane/types";
// services
import { AuthService } from "@/services/auth.service";
import { UserService } from "@/services/user.service";
// root store
import { CoreRootStore } from "@/store/root.store";
@ -58,7 +56,7 @@ export class UserStore implements IUserStore {
fetchCurrentUser = async () => {
try {
if (this.currentUser === undefined) this.isLoading = true;
const currentUser = await this.userService.currentUser();
const currentUser = await this.userService.adminDetails();
if (currentUser) {
await this.store.instance.fetchInstanceAdmins();
runInAction(() => {

View File

@ -1,8 +1,8 @@
import set from "lodash/set";
import { action, observable, runInAction, makeObservable, computed } from "mobx";
// plane imports
import { InstanceWorkspaceService } from "@plane/services";
import { IWorkspace, TLoader, TPaginationInfo } from "@plane/types";
// services
import { WorkspaceService } from "@/services/workspace.service";
// root store
import { CoreRootStore } from "@/store/root.store";
@ -29,7 +29,7 @@ export class WorkspaceStore implements IWorkspaceStore {
workspaces: Record<string, IWorkspace> = {};
paginationInfo: TPaginationInfo | undefined = undefined;
// services
workspaceService;
instanceWorkspaceService;
constructor(private store: CoreRootStore) {
makeObservable(this, {
@ -48,7 +48,7 @@ export class WorkspaceStore implements IWorkspaceStore {
// curd actions
createWorkspace: action,
});
this.workspaceService = new WorkspaceService();
this.instanceWorkspaceService = new InstanceWorkspaceService();
}
// computed
@ -84,7 +84,7 @@ export class WorkspaceStore implements IWorkspaceStore {
} else {
this.loader = "init-loader";
}
const paginatedWorkspaceData = await this.workspaceService.getWorkspaces();
const paginatedWorkspaceData = await this.instanceWorkspaceService.list();
runInAction(() => {
const { results, ...paginationInfo } = paginatedWorkspaceData;
results.forEach((workspace: IWorkspace) => {
@ -109,7 +109,7 @@ export class WorkspaceStore implements IWorkspaceStore {
if (!this.paginationInfo || this.paginationInfo.next_page_results === false) return [];
try {
this.loader = "pagination";
const paginatedWorkspaceData = await this.workspaceService.getWorkspaces(this.paginationInfo.next_cursor);
const paginatedWorkspaceData = await this.instanceWorkspaceService.list(this.paginationInfo.next_cursor);
runInAction(() => {
const { results, ...paginationInfo } = paginatedWorkspaceData;
results.forEach((workspace: IWorkspace) => {
@ -135,7 +135,7 @@ export class WorkspaceStore implements IWorkspaceStore {
createWorkspace = async (data: IWorkspace): Promise<IWorkspace> => {
try {
this.loader = "mutation";
const workspace = await this.workspaceService.createWorkspace(data);
const workspace = await this.instanceWorkspaceService.create(data);
runInAction(() => {
set(this.workspaces, [workspace.id], workspace);
});

View File

@ -18,6 +18,7 @@
"@plane/types": "*",
"@plane/ui": "*",
"@plane/utils": "*",
"@plane/services": "*",
"@sentry/nextjs": "^8.32.0",
"@tailwindcss/typography": "^0.5.9",
"@types/lodash": "^4.17.0",

View File

@ -1,7 +1,7 @@
// plane web constants
import { AI_EDITOR_TASKS, API_BASE_URL } from "@plane/constants";
// services
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Payload type for AI editor tasks

View File

@ -9,7 +9,7 @@ import { APIService } from "../api.service";
* Provides methods for user authentication, password management, and session handling
* @extends {APIService}
*/
export default class AuthService extends APIService {
export class AuthService extends APIService {
/**
* Creates an instance of AuthService
* Initializes with the base API URL

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import type { TCycleDistribution, TProgressSnapshot, TCycleEstimateDistribution } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for managing cycles within a workspace and project context.

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import { ICycle } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for managing archived cycles in a project

View File

@ -1,5 +1,5 @@
import { API_BASE_URL } from "@plane/constants";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export class CycleOperationsService extends APIService {
constructor(BASE_URL?: string) {

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import type { CycleDateCheckData, ICycle, TIssuesResponse, IWorkspaceActiveCyclesResponse } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for managing cycles within a workspace and project context.

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import { IApiToken } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export class APITokenService extends APIService {
constructor(BASE_URL?: string) {

View File

@ -1,13 +1,22 @@
// plane imports
import { API_BASE_URL } from "@plane/constants";
import type { IInstanceInfo, TPage } from "@plane/types";
import { APIService } from "@/api.service";
import type {
IFormattedInstanceConfiguration,
IInstance,
IInstanceAdmin,
IInstanceConfiguration,
IInstanceInfo,
TPage,
} from "@plane/types";
// api service
import { APIService } from "../api.service";
/**
* Service class for managing instance-related operations
* Handles retrieval of instance information and changelog
* @extends {APIService}
*/
export default class InstanceService extends APIService {
export class InstanceService extends APIService {
/**
* Creates an instance of InstanceService
* Initializes the service with the base API URL
@ -25,7 +34,7 @@ export default class InstanceService extends APIService {
return this.get("/api/instances/")
.then((response) => response.data)
.catch((error) => {
throw error;
throw error?.response?.data;
});
}
@ -38,7 +47,77 @@ export default class InstanceService extends APIService {
return this.get("/api/instances/changelog/")
.then((response) => response.data)
.catch((error) => {
throw error;
throw error?.response?.data;
});
}
/**
* Fetches the list of instance admins
* @returns {Promise<IInstanceAdmin[]>} Promise resolving to an array of instance admins
* @throws {Error} If the API request fails
*/
async admins(): Promise<IInstanceAdmin[]> {
return this.get("/api/instances/admins/")
.then((response) => response.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Updates the instance information
* @param {Partial<IInstance>} data Data to update the instance with
* @returns {Promise<IInstance>} Promise resolving to the updated instance information
* @throws {Error} If the API request fails
*/
async update(data: Partial<IInstance>): Promise<IInstance> {
return this.patch("/api/instances/", data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Fetches the list of instance configurations
* @returns {Promise<IInstanceConfiguration[]>} Promise resolving to an array of instance configurations
* @throws {Error} If the API request fails
*/
async configurations(): Promise<IInstanceConfiguration[]> {
return this.get("/api/instances/configurations/")
.then((response) => response.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Updates the instance configurations
* @param {Partial<IFormattedInstanceConfiguration>} data Data to update the instance configurations with
* @returns {Promise<IInstanceConfiguration[]>} The updated instance configurations
* @throws {Error} If the API request fails
*/
async updateConfigurations(data: Partial<IFormattedInstanceConfiguration>): Promise<IInstanceConfiguration[]> {
return this.patch("/api/instances/configurations/", data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Sends a test email to the specified receiver to test SMTP configuration
* @param {string} receiverEmail Email address to send the test email to
* @returns {Promise<void>} Promise resolving to void
* @throws {Error} If the API request fails
*/
async sendTestEmail(receiverEmail: string): Promise<void> {
return this.post("/api/instances/email-credentials-check/", {
receiver_email: receiverEmail,
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
}

View File

@ -1,5 +1,5 @@
import { API_BASE_URL } from "@plane/constants";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export default class IntakeService extends APIService {
constructor(BASE_URL?: string) {

View File

@ -1,5 +1,5 @@
import { API_BASE_URL } from "@plane/constants";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export default class IntakeIssueService extends APIService {
constructor(BASE_URL?: string) {

View File

@ -1,7 +1,7 @@
// types
import type { ILinkDetails, ModuleLink } from "@plane/types";
// services
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for handling module link related operations.

View File

@ -1,7 +1,7 @@
// types
import type { IModule, ILinkDetails, ModuleLink, TIssuesResponse } from "@plane/types";
// services
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export class ModuleService extends APIService {
constructor(baseURL: string) {

View File

@ -1,7 +1,7 @@
// types
// import type { IModule, ILinkDetails, ModuleLink, TIssuesResponse } from "@plane/types";
// services
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export class ModuleOperationService extends APIService {
constructor(baseURL: string) {

View File

@ -1 +1 @@
export * from "./view.service";
export * from "./view.service";

View File

@ -0,0 +1,14 @@
// plane imports
import { API_BASE_URL } from "@plane/constants";
// api services
import { APIService } from "../api.service";
export class ProjectViewService extends APIService {
/**
* Creates an instance of ProjectViewService
* @param {string} baseUrl - The base URL for API requests
*/
constructor(BASE_URL?: string) {
super(BASE_URL || API_BASE_URL);
}
}

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import type { IFavorite } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for managing user favorites

View File

@ -1 +1,2 @@
export * from "./favorite.service";
export * from "./user.service";

View File

@ -0,0 +1,33 @@
// plane imports
import { API_BASE_URL } from "@plane/constants";
import type { IUser } from "@plane/types";
// api service
import { APIService } from "../api.service";
/**
* Service class for managing user operations
* Handles operations for retrieving the current user's details and perform CRUD operations
* @extends {APIService}
*/
export class UserService extends APIService {
/**
* Constructor for UserService
* @param BASE_URL - Base URL for API requests
*/
constructor(BASE_URL?: string) {
super(BASE_URL || API_BASE_URL);
}
/**
* Retrieves the current instance admin details
* @returns {Promise<IUser>} Promise resolving to the current instance admin details
* @throws {Error} If the API request fails
*/
async adminDetails(): Promise<IUser> {
return this.get("/api/instances/admins/me/")
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
}

View File

@ -3,3 +3,4 @@ export * from "./member.service";
export * from "./notification.service";
export * from "./view.service";
export * from "./workspace.service";
export * from "./instance-workspace.service";

View File

@ -0,0 +1,65 @@
import { API_BASE_URL } from "@plane/constants";
import type { IWorkspace, TWorkspacePaginationInfo } from "@plane/types";
import { APIService } from "../api.service";
/**
* Service class for managing instance workspaces
* Handles CRUD operations on instance workspaces
* @extends APIService
*/
export class InstanceWorkspaceService extends APIService {
/**
* Constructor for InstanceWorkspaceService
* @param BASE_URL - Base URL for API requests
*/
constructor(BASE_URL?: string) {
super(BASE_URL || API_BASE_URL);
}
/**
* Retrieves a paginated list of workspaces for the current instance
* @param {string} nextPageCursor - Optional cursor to retrieve the next page of results
* @returns {Promise<TWorkspacePaginationInfo>} Promise resolving to a paginated list of workspaces
* @throws {Error} If the API request fails
*/
async list(nextPageCursor?: string): Promise<TWorkspacePaginationInfo> {
return this.get(`/api/instances/workspaces/`, {
params: {
cursor: nextPageCursor,
},
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Checks if a workspace slug is available
* @param {string} slug - The workspace slug to check
* @returns {Promise<any>} Promise resolving to slug availability status
* @throws {Error} If the API request fails
*/
async slugCheck(slug: string): Promise<any> {
const params = new URLSearchParams({ slug });
return this.get(`/api/instances/workspace-slug-check/?${params.toString()}`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
/**
* Creates a new workspace
* @param {Partial<IWorkspace>} data - Workspace data for creation
* @returns {Promise<IWorkspace>} Promise resolving to the created workspace
* @throws {Error} If the API request fails
*/
async create(data: Partial<IWorkspace>): Promise<IWorkspace> {
return this.post("/api/instances/workspaces/", data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
}

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import { IWorkspaceMemberInvitation, IWorkspaceBulkInviteFormData, IWorkspaceMember } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
/**
* Service class for managing workspace invitations

View File

@ -1,6 +1,6 @@
import { API_BASE_URL } from "@plane/constants";
import { IWorkspaceView, TIssuesResponse } from "@plane/types";
import { APIService } from "@/api.service";
import { APIService } from "../api.service";
export class WorkspaceViewService extends APIService {
/**

View File

@ -3,9 +3,6 @@
"compilerOptions": {
"jsx": "react",
"lib": ["esnext", "dom"],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["./src"],
"exclude": ["dist", "build", "node_modules"]