Refactoring Phase 1 (#199)

* style: added cta at the bottom of sidebar, added missing icons as well, showing dynamic workspace member count on workspace dropdown

* refractor: running parallel request,

made create/edit label function to async function

* fix: sidebar dropdown content going below kanban items

outside click detection in need help dropdown

* refractor: making parallel api calls

fix: create state input comes at bottom, create state input gets on focus automatically, form is getting submitted on enter click

* refactoring file structure and signin page

* style: changed text and added spinner for signing in loading

* refractor: removed unused type

* fix: my issue cta in profile page sending to 404 page

* fix: added new s3 bucket url in next.config.js file

increased image modal height

* packaging UI components

* eslint config

* eslint fixes

* refactoring changes

* build fixes

* minor fixes

* adding todo comments for reference

* refactor: cleared unused imports and re ordered imports

* refactor: removed unused imports

* fix: added workspace argument to useissues hook

* refactor: removed api-routes file, unnecessary constants

* refactor: created helpers folder, removed unnecessary constants

* refactor: new context for issue view

* refactoring issues page

* build fixes

* refactoring

* refactor: create issue modal

* refactor: module ui

* fix: sub-issues mutation

* fix: create more option in create issue modal

* description form debounce issue

* refactor: global component for assignees list

* fix: link module interface

* fix: priority icons and sub-issues count added

* fix: cycle mutation in issue details page

* fix: remove issue from cycle mutation

* fix: create issue modal in home page

* fix: removed unnecessary props

* fix: updated create issue form status

* fix: settings auth breaking

* refactor: issue details page

Co-authored-by: Dakshesh Jain <dakshesh.jain14@gmail.com>
Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com>
Co-authored-by: venkatesh-soulpage <venkatesh.marreboyina@soulpageit.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia1001@gmail.com>
This commit is contained in:
sriram veeraghanta 2023-01-26 23:42:20 +05:30 committed by GitHub
parent 9134b0c543
commit 9075f9441c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
322 changed files with 14149 additions and 21378 deletions

View file

@ -1,16 +1,7 @@
// cookies
import { convertCookieStringToObject } from "./cookie";
// types
import type { IProjectMember, IUser, IWorkspace, IWorkspaceMember } from "types";
// constants
import {
BASE_STAGING,
PROJECT_MEMBER_ME,
USER_ENDPOINT,
USER_WORKSPACES,
USER_WORKSPACE_INVITATIONS,
WORKSPACE_MEMBER_ME,
} from "constants/api-routes";
export const requiredAuth = async (cookie?: string) => {
const cookies = convertCookieStringToObject(cookie);
@ -18,12 +9,12 @@ export const requiredAuth = async (cookie?: string) => {
if (!token) return null;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || BASE_STAGING;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.plane.so";
let user: IUser | null = null;
try {
const data = await fetch(`${baseUrl}${USER_ENDPOINT}`, {
const data = await fetch(`${baseUrl}/api/users/me/`, {
method: "GET",
headers: {
"Content-Type": "application/json",
@ -50,17 +41,20 @@ export const requiredAdmin = async (workspaceSlug: string, projectId: string, co
const cookies = convertCookieStringToObject(cookie);
const token = cookies?.accessToken;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || BASE_STAGING;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.plane.so";
let memberDetail: IProjectMember | null = null;
try {
const data = await fetch(`${baseUrl}${PROJECT_MEMBER_ME(workspaceSlug, projectId)}`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
})
const data = await fetch(
`${baseUrl}/api/workspaces/${workspaceSlug}/projects/${projectId}/project-members/me/`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
}
)
.then((res) => res.json())
.then((data) => data);
@ -81,12 +75,12 @@ export const requiredWorkspaceAdmin = async (workspaceSlug: string, cookie?: str
const cookies = convertCookieStringToObject(cookie);
const token = cookies?.accessToken;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || BASE_STAGING;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.plane.so";
let memberDetail: IWorkspaceMember | null = null;
try {
const data = await fetch(`${baseUrl}${WORKSPACE_MEMBER_ME(workspaceSlug)}`, {
const data = await fetch(`${baseUrl}/api/workspaces/${workspaceSlug}/workspace-members/me/`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
@ -128,13 +122,13 @@ export const homePageRedirect = async (cookie?: string) => {
let workspaces: IWorkspace[] = [];
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || BASE_STAGING;
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.plane.so";
const cookies = convertCookieStringToObject(cookie);
const token = cookies?.accessToken;
try {
const data = await fetch(`${baseUrl}${USER_WORKSPACES}`, {
const data = await fetch(`${baseUrl}/api/users/me/workspaces/`, {
method: "GET",
headers: {
"Content-Type": "application/json",
@ -175,7 +169,7 @@ export const homePageRedirect = async (cookie?: string) => {
};
}
const invitations = await fetch(`${baseUrl}${USER_WORKSPACE_INVITATIONS}`, {
const invitations = await fetch(`${baseUrl}/api/users/me/invitations/workspaces/`, {
method: "GET",
headers: {
"Content-Type": "application/json",

View file

@ -3,6 +3,7 @@ export const convertCookieStringToObject = (cookieHeader: string | undefined) =>
if (!cookieHeader) return list;
cookieHeader.split(`;`).forEach(function (cookie) {
// eslint-disable-next-line prefer-const
let [name, ...rest] = cookie.split(`=`);
name = name?.trim();
if (!name) return;

View file

@ -1,33 +0,0 @@
import React from "react";
// next
import type { NextPage } from "next";
// redirect
import redirect from "lib/redirect";
const withAuth = (WrappedComponent: NextPage, getBackToSameRoute: boolean = true) => {
const Wrapper: NextPage<any> = (props) => {
return <WrappedComponent {...props} />;
};
Wrapper.getInitialProps = async (ctx) => {
const isServer = typeof window === "undefined";
const cookies = isServer ? ctx?.req?.headers.cookie : document.cookie;
const token = cookies?.split("accessToken=")?.[1]?.split(";")?.[0];
if (!token) {
if (getBackToSameRoute) redirect(ctx, "/signin?next=" + ctx?.asPath);
else redirect(ctx, "/signin");
}
const pageProps =
WrappedComponent.getInitialProps && (await WrappedComponent.getInitialProps(ctx));
return { ...pageProps };
};
return Wrapper;
};
export default withAuth;

View file

@ -1,21 +0,0 @@
import { useEffect } from "react";
// Updates the height of a <textarea> when the value changes.
const useAutosizeTextArea = (
textAreaRef: HTMLTextAreaElement | null,
value: any
) => {
useEffect(() => {
if (textAreaRef) {
// We need to reset the height momentarily to get the correct scrollHeight for the textarea
textAreaRef.style.height = "0px";
const scrollHeight = textAreaRef.scrollHeight;
// We then set the height directly, outside of the render loop
// Trying to set this with state or a ref will product an incorrect value.
textAreaRef.style.height = scrollHeight + "px";
}
}, [textAreaRef, value]);
};
export default useAutosizeTextArea;

View file

@ -1,122 +0,0 @@
// swr
import useSWR from "swr";
// services
import stateService from "lib/services/state.service";
// constants
import { STATE_LIST } from "constants/fetch-keys";
// hooks
import useTheme from "./useTheme";
// commons
import { groupBy, orderArrayBy } from "constants/common";
// constants
import { PRIORITIES } from "constants/";
// types
import type { IIssue } from "types";
import { useRouter } from "next/router";
const useIssuesFilter = (projectIssues: IIssue[]) => {
const {
issueView,
groupByProperty,
setGroupByProperty,
orderBy,
setOrderBy,
filterIssue,
setFilterIssue,
resetFilterToDefault,
setNewFilterDefaultView,
setIssueViewToKanban,
setIssueViewToList,
} = useTheme();
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { data: states } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null
);
let groupedByIssues: {
[key: string]: IIssue[];
} = {
...(groupByProperty === "state_detail.name"
? Object.fromEntries(
states
?.sort((a, b) => a.sequence - b.sequence)
?.map((state) => [
state.name,
projectIssues.filter((issue) => issue.state === state.name) ?? [],
]) ?? []
)
: groupByProperty === "priority"
? Object.fromEntries(
PRIORITIES.map((priority) => [
priority,
projectIssues.filter((issue) => issue.priority === priority) ?? [],
])
)
: {}),
...groupBy(projectIssues ?? [], groupByProperty ?? ""),
};
if (orderBy !== null) {
groupedByIssues = Object.fromEntries(
Object.entries(groupedByIssues).map(([key, value]) => [
key,
orderArrayBy(value, orderBy, "descending"),
])
);
}
if (filterIssue !== null) {
if (filterIssue === "activeIssue") {
const filteredStates = states?.filter(
(state) => state.group === "started" || state.group === "unstarted"
);
groupedByIssues = Object.fromEntries(
filteredStates
?.sort((a, b) => a.sequence - b.sequence)
?.map((state) => [
state.name,
projectIssues.filter((issue) => issue.state === state.id) ?? [],
]) ?? []
);
} else if (filterIssue === "backlogIssue") {
const filteredStates = states?.filter(
(state) => state.group === "backlog" || state.group === "cancelled"
);
groupedByIssues = Object.fromEntries(
filteredStates
?.sort((a, b) => a.sequence - b.sequence)
?.map((state) => [
state.name,
projectIssues.filter((issue) => issue.state === state.id) ?? [],
]) ?? []
);
}
}
if (groupByProperty === "priority" && orderBy === "priority") {
setOrderBy(null);
}
return {
groupedByIssues,
issueView,
groupByProperty,
setGroupByProperty,
orderBy,
setOrderBy,
filterIssue,
setFilterIssue,
resetFilterToDefault,
setNewFilterDefaultView,
setIssueViewToKanban,
setIssueViewToList,
} as const;
};
export default useIssuesFilter;

View file

@ -1,99 +0,0 @@
import { useState, useEffect, useCallback } from "react";
// swr
import useSWR from "swr";
// api routes
import { ISSUE_PROPERTIES_ENDPOINT } from "constants/api-routes";
// services
import issueServices from "lib/services/issues.service";
// hooks
import useUser from "./useUser";
// types
import { IssuePriorities, Properties } from "types";
const initialValues: Properties = {
key: true,
state: true,
assignee: true,
priority: false,
due_date: false,
cycle: false,
sub_issue_count: false,
};
const useIssuesProperties = (workspaceSlug?: string, projectId?: string) => {
const [properties, setProperties] = useState<Properties>(initialValues);
const { user } = useUser();
const { data: issueProperties, mutate: mutateIssueProperties } = useSWR<IssuePriorities>(
workspaceSlug && projectId ? ISSUE_PROPERTIES_ENDPOINT(workspaceSlug, projectId) : null,
workspaceSlug && projectId
? () => issueServices.getIssueProperties(workspaceSlug, projectId)
: null,
{
shouldRetryOnError: false,
}
);
useEffect(() => {
if (!issueProperties || !workspaceSlug || !projectId || !user) return;
setProperties({ ...initialValues, ...issueProperties.properties });
if (Object.keys(issueProperties).length === 0)
issueServices.createIssueProperties(workspaceSlug, projectId, {
properties: { ...initialValues },
user: user.id,
});
else if (Object.keys(issueProperties?.properties).length === 0)
issueServices.patchIssueProperties(workspaceSlug, projectId, issueProperties.id, {
properties: { ...initialValues },
user: user.id,
});
}, [issueProperties, workspaceSlug, projectId, user]);
const updateIssueProperties = useCallback(
(key: keyof Properties) => {
if (!workspaceSlug || !user) return;
setProperties((prev) => ({ ...prev, [key]: !prev[key] }));
if (issueProperties && projectId) {
mutateIssueProperties(
(prev) =>
({
...prev,
properties: { ...prev?.properties, [key]: !prev?.properties?.[key] },
} as IssuePriorities),
false
);
if (Object.keys(issueProperties).length > 0) {
issueServices.patchIssueProperties(workspaceSlug, projectId, issueProperties.id, {
properties: {
...issueProperties.properties,
[key]: !issueProperties.properties[key],
},
user: user.id,
});
} else {
issueServices.createIssueProperties(workspaceSlug, projectId, {
properties: { ...initialValues },
user: user.id,
});
}
}
},
[workspaceSlug, projectId, issueProperties, user, mutateIssueProperties]
);
const newProperties: Properties = {
key: properties.key,
state: properties.state,
assignee: properties.assignee,
priority: properties.priority,
due_date: properties.due_date,
cycle: properties.cycle,
sub_issue_count: properties.sub_issue_count,
};
return [newProperties, updateIssueProperties] as const;
};
export default useIssuesProperties;

View file

@ -1,38 +0,0 @@
import { useState, useEffect, useCallback } from "react";
const useLocalStorage = <T,>(
key: string,
initialValue?: T extends Function ? never : T | (() => T)
) => {
const [value, setValue] = useState<T | string>("");
useEffect(() => {
const data = window.localStorage.getItem(key);
if (data !== null && data !== "undefined") setValue(JSON.parse(data));
else setValue(typeof initialValue === "function" ? initialValue() : initialValue);
}, [key, initialValue]);
const updateState = useCallback(
(value: T) => {
if (!value) window.localStorage.removeItem(key);
else window.localStorage.setItem(key, JSON.stringify(value));
setValue(value);
window.dispatchEvent(new Event(`local-storage-change-${key}`));
},
[key]
);
const reHydrateState = useCallback(() => {
const data = window.localStorage.getItem(key);
if (data !== null) setValue(JSON.parse(data));
}, [key]);
useEffect(() => {
window.addEventListener(`local-storage-change-${key}`, reHydrateState);
return () => window.removeEventListener(`local-storage-change-${key}`, reHydrateState);
}, [reHydrateState, key]);
return [value, updateState];
};
export default useLocalStorage;

View file

@ -1,124 +0,0 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
// constants
import { STATE_LIST } from "constants/fetch-keys";
// services
import stateService from "lib/services/state.service";
// hooks
import useUser from "./useUser";
// types
import { Properties, NestedKeyOf, IIssue } from "types";
// services
import userService from "lib/services/user.service";
// common
import { groupBy } from "constants/common";
import { PRIORITIES } from "constants/";
const initialValues: Properties = {
key: true,
state: true,
assignee: true,
priority: false,
due_date: false,
cycle: false,
sub_issue_count: false,
};
const useMyIssuesProperties = (issues?: IIssue[]) => {
const [properties, setProperties] = useState<Properties>(initialValues);
const [groupByProperty, setGroupByProperty] = useState<NestedKeyOf<IIssue> | null>(null);
// FIXME: where this hook is used we may not have project id in the url
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const { user } = useUser();
const { data: states } = useSWR(
workspaceSlug && projectId ? STATE_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => stateService.getStates(workspaceSlug as string, projectId as string)
: null
);
useEffect(() => {
if (!user) return;
setProperties({ ...initialValues, ...user.my_issues_prop?.properties });
setGroupByProperty(user.my_issues_prop?.groupBy ?? null);
}, [user]);
let groupedByIssues: {
[key: string]: IIssue[];
} = {
...(groupByProperty === "state_detail.name"
? Object.fromEntries(
states
?.sort((a, b) => a.sequence - b.sequence)
?.map((state) => [
state.name,
issues?.filter((issue) => issue.state === state.name) ?? [],
]) ?? []
)
: groupByProperty === "priority"
? Object.fromEntries(
PRIORITIES.map((priority) => [
priority,
issues?.filter((issue) => issue.priority === priority) ?? [],
])
)
: {}),
...groupBy(issues ?? [], groupByProperty ?? ""),
};
const setMyIssueProperty = (key: keyof Properties) => {
if (!user) return;
userService.updateUser({ my_issues_prop: { properties, groupBy: groupByProperty } });
setProperties((prevData) => ({
...prevData,
[key]: !prevData[key],
}));
localStorage.setItem(
"my_issues_prop",
JSON.stringify({
properties: {
...properties,
[key]: !properties[key],
},
groupBy: groupByProperty,
})
);
};
const setMyIssueGroupByProperty = (groupByProperty: NestedKeyOf<IIssue> | null) => {
if (!user) return;
userService.updateUser({ my_issues_prop: { properties, groupBy: groupByProperty } });
setGroupByProperty(groupByProperty);
localStorage.setItem(
"my_issues_prop",
JSON.stringify({ properties, groupBy: groupByProperty })
);
};
useEffect(() => {
const viewProps = localStorage.getItem("my_issues_prop");
if (viewProps) {
const { properties, groupBy } = JSON.parse(viewProps);
setProperties(properties);
setGroupByProperty(groupBy);
}
}, []);
return {
filteredIssues: groupedByIssues,
groupByProperty,
properties,
setMyIssueProperty,
setMyIssueGroupByProperty,
} as const;
};
export default useMyIssuesProperties;

View file

@ -1,19 +0,0 @@
import React, { useEffect } from "react";
const useOutsideClickDetector = (ref: React.RefObject<HTMLElement>, callback: () => void) => {
const handleClick = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
callback();
}
};
useEffect(() => {
document.addEventListener("click", handleClick);
return () => {
document.removeEventListener("click", handleClick);
};
});
};
export default useOutsideClickDetector;

View file

@ -1,11 +0,0 @@
import { useContext } from "react";
import { themeContext } from "contexts/theme.context";
const useTheme = () => {
const themeContextData = useContext(themeContext);
return themeContextData;
};
export default useTheme;

View file

@ -1,11 +0,0 @@
import { useContext } from "react";
import { toastContext } from "contexts/toast.context";
const useToast = () => {
const toastContextData = useContext(toastContext);
return toastContextData;
};
export default useToast;

View file

@ -1,42 +0,0 @@
import { useContext, useEffect } from "react";
import { useRouter } from "next/router";
// context
import { UserContext } from "contexts/user.context";
interface useUserOptions {
redirectTo?: string;
}
const useUser = (options: useUserOptions = {}) => {
// props
const { redirectTo = null } = options;
// context
const contextData = useContext(UserContext);
// router
const router = useRouter();
/**
* Checks for redirect url and user details from the API.
* if the user is not authenticated, user will be redirected
* to the provided redirectTo route.
*/
useEffect(() => {
if (!contextData?.user || !redirectTo) return;
if (!contextData?.user) {
if (redirectTo) {
router?.pathname !== redirectTo && router.push(redirectTo);
}
router?.pathname !== "/signin" && router.push("/signin");
}
if (contextData?.user) {
if (redirectTo) {
router?.pathname !== redirectTo && router.push(redirectTo);
}
}
}, [contextData?.user, redirectTo, router]);
return contextData;
};
export default useUser;

View file

@ -1,6 +1,5 @@
// next imports
import type { NextPageContext } from "next";
import Router from "next/router";
import type { NextPageContext } from "next";
const redirect = (context: NextPageContext, target: any) => {
if (context.res) {

View file

@ -1,108 +0,0 @@
import axios from "axios";
import Cookies from "js-cookie";
abstract class APIService {
protected baseURL: string;
protected headers: any = {};
constructor(baseURL: string) {
this.baseURL = baseURL;
}
setRefreshToken(token: string) {
Cookies.set("refreshToken", token);
}
getRefreshToken() {
return Cookies.get("refreshToken");
}
purgeRefreshToken() {
Cookies.remove("refreshToken", { path: "/" });
}
setAccessToken(token: string) {
Cookies.set("accessToken", token);
}
getAccessToken() {
return Cookies.get("accessToken");
}
purgeAccessToken() {
Cookies.remove("accessToken", { path: "/" });
}
getHeaders() {
return {
Authorization: `Bearer ${this.getAccessToken()}`,
};
}
get(url: string, config = {}): Promise<any> {
return axios({
method: "get",
url: this.baseURL + url,
headers: this.getAccessToken() ? this.getHeaders() : {},
...config,
});
}
post(url: string, data = {}, config = {}): Promise<any> {
return axios({
method: "post",
url: this.baseURL + url,
data,
headers: this.getAccessToken() ? this.getHeaders() : {},
...config,
});
}
put(url: string, data = {}, config = {}): Promise<any> {
return axios({
method: "put",
url: this.baseURL + url,
data,
headers: this.getAccessToken() ? this.getHeaders() : {},
...config,
});
}
patch(url: string, data = {}, config = {}): Promise<any> {
return axios({
method: "patch",
url: this.baseURL + url,
data,
headers: this.getAccessToken() ? this.getHeaders() : {},
...config,
});
}
delete(url: string, data?: any, config = {}): Promise<any> {
return axios({
method: "delete",
url: this.baseURL + url,
data: data,
headers: this.getAccessToken() ? this.getHeaders() : {},
...config,
});
}
mediaUpload(url: string, data = {}, config = {}): Promise<any> {
return axios({
method: "post",
url: this.baseURL + url,
data,
headers: this.getAccessToken()
? { ...this.getHeaders(), "Content-Type": "multipart/form-data" }
: {},
...config,
});
}
request(config = {}) {
return axios(config);
}
}
export default APIService;

View file

@ -1,71 +0,0 @@
// api routes
import { SIGN_IN_ENDPOINT, SOCIAL_AUTH_ENDPOINT, MAGIC_LINK_GENERATE, MAGIC_LINK_SIGNIN } from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class AuthService extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async emailLogin(data: any) {
return this.post(SIGN_IN_ENDPOINT, data, { headers: {} })
.then((response) => {
this.setAccessToken(response?.data?.access_token);
this.setRefreshToken(response?.data?.refresh_token);
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async socialAuth(data: any) {
return this.post(SOCIAL_AUTH_ENDPOINT, data, { headers: {} })
.then((response) => {
this.setAccessToken(response?.data?.access_token);
this.setRefreshToken(response?.data?.refresh_token);
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async emailCode(data: any) {
return this.post(MAGIC_LINK_GENERATE, data, { headers: {} })
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async magicSignIn(data: any) {
const response = await this.post(MAGIC_LINK_SIGNIN, data, { headers: {} });
if (response?.status === 200) {
this.setAccessToken(response?.data?.access_token);
this.setRefreshToken(response?.data?.refresh_token);
return response?.data;
}
throw response.response.data;
}
async signOut(data = {}) {
return this.post("/api/sign-out/", data)
.then((response) => {
this.purgeAccessToken();
this.purgeRefreshToken();
return response?.data;
})
.catch((error) => {
this.purgeAccessToken();
this.purgeRefreshToken();
throw error?.response?.data;
});
}
}
export default new AuthService();

View file

@ -1,92 +0,0 @@
// api routes
import { CYCLES_ENDPOINT, CYCLE_DETAIL } from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
// types
import type { ICycle } from "types";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class ProjectCycleServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async createCycle(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(CYCLES_ENDPOINT(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getCycles(workspaceSlug: string, projectId: string): Promise<ICycle[]> {
return this.get(CYCLES_ENDPOINT(workspaceSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getCycleIssues(workspaceSlug: string, projectId: string, cycleId: string): Promise<any> {
return this.get(CYCLE_DETAIL(workspaceSlug, projectId, cycleId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateCycle(
workspaceSlug: string,
projectId: string,
cycleId: string,
data: any
): Promise<any> {
return this.put(
CYCLE_DETAIL(workspaceSlug, projectId, cycleId).replace("cycle-issues/", ""),
data
)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchCycle(
workspaceSlug: string,
projectId: string,
cycleId: string,
data: any
): Promise<any> {
return this.patch(
CYCLE_DETAIL(workspaceSlug, projectId, cycleId).replace("cycle-issues/", ""),
data
)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteCycle(workspaceSlug: string, projectId: string, cycleId: string): Promise<any> {
return this.delete(CYCLE_DETAIL(workspaceSlug, projectId, cycleId).replace("cycle-issues/", ""))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new ProjectCycleServices();

View file

@ -1,24 +0,0 @@
// api routes
import { S3_URL } from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class FileServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async uploadFile(workspaceSlug: string, file: FormData): Promise<any> {
return this.mediaUpload(S3_URL(workspaceSlug), file)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new FileServices();

View file

@ -1,294 +0,0 @@
// api routes
import {
ISSUES_ENDPOINT,
ISSUE_DETAIL,
ISSUE_ACTIVITIES,
ISSUE_COMMENTS,
ISSUE_COMMENT_DETAIL,
ISSUE_PROPERTIES_ENDPOINT,
CYCLE_DETAIL,
ISSUE_LABELS,
BULK_DELETE_ISSUES,
REMOVE_ISSUE_FROM_CYCLE,
ISSUE_LABEL_DETAILS,
} from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
// type
import type { IIssue, IIssueActivity, IIssueComment, IssueResponse } from "types";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class ProjectIssuesServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async createIssues(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(ISSUES_ENDPOINT(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssues(workspaceSlug: string, projectId: string): Promise<IssueResponse> {
return this.get(ISSUES_ENDPOINT(workspaceSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssue(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(ISSUE_DETAIL(workspaceSlug, projectId, issueId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssueActivities(
workspaceSlug: string,
projectId: string,
issueId: string
): Promise<IIssueActivity[]> {
return this.get(ISSUE_ACTIVITIES(workspaceSlug, projectId, issueId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssueComments(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(ISSUE_COMMENTS(workspaceSlug, projectId, issueId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssueProperties(workspaceSlug: string, projectId: string): Promise<any> {
return this.get(ISSUE_PROPERTIES_ENDPOINT(workspaceSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async addIssueToCycle(
workspaceSlug: string,
projectId: string,
cycleId: string,
data: {
issues: string[];
}
) {
return this.post(CYCLE_DETAIL(workspaceSlug, projectId, cycleId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async removeIssueFromCycle(
workspaceSlug: string,
projectId: string,
cycleId: string,
bridgeId: string
) {
return this.delete(REMOVE_ISSUE_FROM_CYCLE(workspaceSlug, projectId, cycleId, bridgeId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async createIssueProperties(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(ISSUE_PROPERTIES_ENDPOINT(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchIssueProperties(
workspaceSlug: string,
projectId: string,
issuePropertyId: string,
data: any
): Promise<any> {
return this.patch(
ISSUE_PROPERTIES_ENDPOINT(workspaceSlug, projectId) + `${issuePropertyId}/`,
data
)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async createIssueComment(
workspaceSlug: string,
projectId: string,
issueId: string,
data: any
): Promise<any> {
return this.post(ISSUE_COMMENTS(workspaceSlug, projectId, issueId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchIssueComment(
workspaceSlug: string,
projectId: string,
issueId: string,
commentId: string,
data: IIssueComment
): Promise<any> {
return this.patch(ISSUE_COMMENT_DETAIL(workspaceSlug, projectId, issueId, commentId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteIssueComment(
workspaceSlug: string,
projectId: string,
issueId: string,
commentId: string
): Promise<any> {
return this.delete(ISSUE_COMMENT_DETAIL(workspaceSlug, projectId, issueId, commentId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssueLabels(workspaceSlug: string, projectId: string): Promise<any> {
return this.get(ISSUE_LABELS(workspaceSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async createIssueLabel(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(ISSUE_LABELS(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchIssueLabel(
workspaceSlug: string,
projectId: string,
labelId: string,
data: any
): Promise<any> {
return this.patch(ISSUE_LABEL_DETAILS(workspaceSlug, projectId, labelId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteIssueLabel(workspaceSlug: string, projectId: string, labelId: string): Promise<any> {
return this.delete(ISSUE_LABEL_DETAILS(workspaceSlug, projectId, labelId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateIssue(
workspaceSlug: string,
projectId: string,
issueId: string,
data: any
): Promise<any> {
return this.put(ISSUE_DETAIL(workspaceSlug, projectId, issueId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchIssue(
workspaceSlug: string,
projectId: string,
issueId: string,
data: Partial<IIssue>
): Promise<any> {
return this.patch(ISSUE_DETAIL(workspaceSlug, projectId, issueId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteIssue(workspaceSlug: string, projectId: string, issuesId: string): Promise<any> {
return this.delete(ISSUE_DETAIL(workspaceSlug, projectId, issuesId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async bulkDeleteIssues(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.delete(BULK_DELETE_ISSUES(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new ProjectIssuesServices();

View file

@ -1,131 +0,0 @@
// api routes
import {
MODULES_ENDPOINT,
MODULE_DETAIL,
MODULE_ISSUES,
MODULE_ISSUE_DETAIL,
} from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
// types
import type { IModule } from "types";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class ProjectIssuesServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async getModules(workspaceSlug: string, projectId: string): Promise<IModule[]> {
return this.get(MODULES_ENDPOINT(workspaceSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async createModule(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(MODULES_ENDPOINT(workspaceSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateModule(
workspaceSlug: string,
projectId: string,
moduleId: string,
data: any
): Promise<any> {
return this.put(MODULE_DETAIL(workspaceSlug, projectId, moduleId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getModuleDetails(workspaceSlug: string, projectId: string, moduleId: string): Promise<any> {
return this.get(MODULE_DETAIL(workspaceSlug, projectId, moduleId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchModule(
workspaceSlug: string,
projectId: string,
moduleId: string,
data: any
): Promise<any> {
return this.patch(MODULE_DETAIL(workspaceSlug, projectId, moduleId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteModule(workspaceSlug: string, projectId: string, moduleId: string): Promise<any> {
return this.delete(MODULE_DETAIL(workspaceSlug, projectId, moduleId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getModuleIssues(workspaceSlug: string, projectId: string, moduleId: string): Promise<any> {
return this.get(MODULE_ISSUES(workspaceSlug, projectId, moduleId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async addIssuesToModule(
workspaceSlug: string,
projectId: string,
moduleId: string,
data: { issues: string[] }
): Promise<any> {
return this.post(MODULE_ISSUES(workspaceSlug, projectId, moduleId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async removeIssueFromModule(
workspaceSlug: string,
projectId: string,
moduleId: string,
bridgeId: string
): Promise<any> {
return this.delete(MODULE_ISSUE_DETAIL(workspaceSlug, projectId, moduleId, bridgeId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new ProjectIssuesServices();

View file

@ -1,248 +0,0 @@
// api routes
import {
CHECK_PROJECT_IDENTIFIER,
INVITE_PROJECT,
JOIN_PROJECT,
PROJECTS_ENDPOINT,
PROJECT_DETAIL,
PROJECT_INVITATIONS,
PROJECT_INVITATION_DETAIL,
PROJECT_MEMBERS,
PROJECT_MEMBER_DETAIL,
USER_PROJECT_INVITATIONS,
PROJECT_VIEW_ENDPOINT,
PROJECT_MEMBER_ME,
} from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
// types
import type { IProject, IProjectMember, IProjectMemberInvitation, ProjectViewTheme } from "types";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class ProjectServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async createProject(workspacSlug: string, data: Partial<IProject>): Promise<IProject> {
return this.post(PROJECTS_ENDPOINT(workspacSlug), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response;
});
}
async checkProjectIdentifierAvailability(workspaceSlug: string, data: string): Promise<any> {
return this.get(CHECK_PROJECT_IDENTIFIER(workspaceSlug), {
params: {
name: data,
},
})
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getProjects(workspacSlug: string): Promise<IProject[]> {
return this.get(PROJECTS_ENDPOINT(workspacSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getProject(workspacSlug: string, projectId: string): Promise<IProject> {
return this.get(PROJECT_DETAIL(workspacSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateProject(
workspacSlug: string,
projectId: string,
data: Partial<IProject>
): Promise<IProject> {
return this.patch(PROJECT_DETAIL(workspacSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteProject(workspacSlug: string, projectId: string): Promise<any> {
return this.delete(PROJECT_DETAIL(workspacSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async inviteProject(workspacSlug: string, projectId: string, data: any): Promise<any> {
return this.post(INVITE_PROJECT(workspacSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async joinProject(workspacSlug: string, data: any): Promise<any> {
return this.post(JOIN_PROJECT(workspacSlug), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async joinProjects(data: any): Promise<any> {
return this.post(USER_PROJECT_INVITATIONS, data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async projectMembers(workspacSlug: string, projectId: string): Promise<IProjectMember[]> {
return this.get(PROJECT_MEMBERS(workspacSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async projectMemberMe(workspacSlug: string, projectId: string): Promise<IProjectMember> {
return this.get(PROJECT_MEMBER_ME(workspacSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getProjectMember(
workspacSlug: string,
projectId: string,
memberId: string
): Promise<IProjectMember> {
return this.get(PROJECT_MEMBER_DETAIL(workspacSlug, projectId, memberId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateProjectMember(
workspacSlug: string,
projectId: string,
memberId: string,
data: Partial<IProjectMember>
): Promise<IProjectMember> {
return this.put(PROJECT_MEMBER_DETAIL(workspacSlug, projectId, memberId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteProjectMember(
workspacSlug: string,
projectId: string,
memberId: string
): Promise<any> {
return this.delete(PROJECT_MEMBER_DETAIL(workspacSlug, projectId, memberId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async projectInvitations(
workspacSlug: string,
projectId: string
): Promise<IProjectMemberInvitation[]> {
return this.get(PROJECT_INVITATIONS(workspacSlug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateProjectInvitation(
workspacSlug: string,
projectId: string,
invitationId: string
): Promise<any> {
return this.put(PROJECT_INVITATION_DETAIL(workspacSlug, projectId, invitationId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteProjectInvitation(
workspacSlug: string,
projectId: string,
invitationId: string
): Promise<any> {
return this.delete(PROJECT_INVITATION_DETAIL(workspacSlug, projectId, invitationId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async setProjectView(
workspacSlug: string,
projectId: string,
data: {
view_props?: ProjectViewTheme;
default_props?: ProjectViewTheme;
}
): Promise<any> {
await this.post(PROJECT_VIEW_ENDPOINT(workspacSlug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new ProjectServices();

View file

@ -1,98 +0,0 @@
// api routes
import { STATES_ENDPOINT, STATE_DETAIL, ISSUES_BY_STATE } from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
// types
import type { IState } from "types";
class ProjectStateServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async createState(workspace_slug: string, projectId: string, data: any): Promise<any> {
return this.post(STATES_ENDPOINT(workspace_slug, projectId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getStates(workspace_slug: string, projectId: string): Promise<IState[]> {
return this.get(STATES_ENDPOINT(workspace_slug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getIssuesByState(workspace_slug: string, projectId: string): Promise<any> {
return this.get(ISSUES_BY_STATE(workspace_slug, projectId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getState(workspace_slug: string, projectId: string, stateId: string): Promise<any> {
return this.get(STATE_DETAIL(workspace_slug, projectId, stateId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateState(
workspace_slug: string,
projectId: string,
stateId: string,
data: IState
): Promise<any> {
return this.put(STATE_DETAIL(workspace_slug, projectId, stateId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async patchState(
workspace_slug: string,
projectId: string,
stateId: string,
data: Partial<IState>
): Promise<any> {
return this.patch(STATE_DETAIL(workspace_slug, projectId, stateId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteState(workspace_slug: string, projectId: string, stateId: string): Promise<any> {
return this.delete(STATE_DETAIL(workspace_slug, projectId, stateId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new ProjectStateServices();

View file

@ -1,63 +0,0 @@
// services
import { USER_ENDPOINT, USER_ISSUES_ENDPOINT, USER_ONBOARD_ENDPOINT } from "constants/api-routes";
import APIService from "lib/services/api.service";
import type { IUser } from "types";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
class UserService extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
currentUserConfig() {
return {
url: `${this.baseURL}/api/users/me/`,
headers: this.getHeaders(),
};
}
async userIssues(workspaceSlug: string): Promise<any> {
return this.get(USER_ISSUES_ENDPOINT(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async currentUser(): Promise<any> {
if (!this.getAccessToken()) return null;
return this.get(USER_ENDPOINT)
.then((response) => {
return response?.data;
})
.catch((error) => {
this.purgeAccessToken();
throw error?.response?.data;
});
}
async updateUser(data: Partial<IUser>): Promise<any> {
return this.patch(USER_ENDPOINT, data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateUserOnBoard(): Promise<any> {
return this.patch(USER_ONBOARD_ENDPOINT, { is_onboarded: true })
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new UserService();

View file

@ -1,236 +0,0 @@
// api routes
import {
USER_WORKSPACES,
WORKSPACES_ENDPOINT,
INVITE_WORKSPACE,
WORKSPACE_DETAIL,
JOIN_WORKSPACE,
WORKSPACE_MEMBERS,
WORKSPACE_MEMBER_DETAIL,
WORKSPACE_INVITATIONS,
WORKSPACE_INVITATION_DETAIL,
USER_WORKSPACE_INVITATION,
USER_WORKSPACE_INVITATIONS,
LAST_ACTIVE_WORKSPACE_AND_PROJECTS,
WORKSPACE_MEMBER_ME,
WORKSPACE_SLUG_CHECK,
} from "constants/api-routes";
// services
import APIService from "lib/services/api.service";
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
// types
import {
IWorkspace,
IWorkspaceMember,
IWorkspaceMemberInvitation,
ILastActiveWorkspaceDetails,
} from "types";
class WorkspaceService extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}
async userWorkspaces(): Promise<IWorkspace[]> {
return this.get(USER_WORKSPACES)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getWorkspace(workspaceSlug: string): Promise<IWorkspace> {
return this.get(WORKSPACE_DETAIL(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response;
});
}
async createWorkspace(data: Partial<IWorkspace>): Promise<IWorkspace> {
return this.post(WORKSPACES_ENDPOINT, data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateWorkspace(workspaceSlug: string, data: Partial<IWorkspace>): Promise<IWorkspace> {
return this.patch(WORKSPACE_DETAIL(workspaceSlug), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteWorkspace(workspaceSlug: string): Promise<any> {
return this.delete(WORKSPACE_DETAIL(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async inviteWorkspace(workspaceSlug: string, data: any): Promise<any> {
return this.post(INVITE_WORKSPACE(workspaceSlug), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async joinWorkspace(workspaceSlug: string, InvitationId: string, data: any): Promise<any> {
return this.post(JOIN_WORKSPACE(workspaceSlug, InvitationId), data, {
headers: {},
})
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async joinWorkspaces(data: any): Promise<any> {
return this.post(USER_WORKSPACE_INVITATIONS, data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getLastActiveWorkspaceAndProjects(): Promise<ILastActiveWorkspaceDetails> {
return this.get(LAST_ACTIVE_WORKSPACE_AND_PROJECTS)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async userWorkspaceInvitations(): Promise<IWorkspaceMemberInvitation[]> {
return this.get(USER_WORKSPACE_INVITATIONS)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async workspaceMembers(workspaceSlug: string): Promise<IWorkspaceMember[]> {
return this.get(WORKSPACE_MEMBERS(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async workspaceMemberMe(workspaceSlug: string): Promise<IWorkspaceMember> {
return this.get(WORKSPACE_MEMBER_ME(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateWorkspaceMember(
workspaceSlug: string,
memberId: string,
data: Partial<IWorkspaceMember>
): Promise<IWorkspaceMember> {
return this.put(WORKSPACE_MEMBER_DETAIL(workspaceSlug, memberId), data)
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteWorkspaceMember(workspaceSlug: string, memberId: string): Promise<any> {
return this.delete(WORKSPACE_MEMBER_DETAIL(workspaceSlug, memberId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async workspaceInvitations(workspaceSlug: string): Promise<IWorkspaceMemberInvitation[]> {
return this.get(WORKSPACE_INVITATIONS(workspaceSlug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async getWorkspaceInvitation(invitationId: string): Promise<IWorkspaceMemberInvitation> {
return this.get(USER_WORKSPACE_INVITATION(invitationId), { headers: {} })
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async updateWorkspaceInvitation(
workspaceSlug: string,
invitationId: string
): Promise<IWorkspaceMemberInvitation> {
return this.put(WORKSPACE_INVITATION_DETAIL(workspaceSlug, invitationId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async deleteWorkspaceInvitations(workspaceSlug: string, invitationId: string): Promise<any> {
return this.delete(WORKSPACE_INVITATION_DETAIL(workspaceSlug, invitationId))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
async workspaceSlugCheck(slug: string): Promise<any> {
return this.get(WORKSPACE_SLUG_CHECK(slug))
.then((response) => {
return response?.data;
})
.catch((error) => {
throw error?.response?.data;
});
}
}
export default new WorkspaceService();