feat: views added to cycles, fix: overflowing issues
This commit is contained in:
commit
9c18f6fc71
94 changed files with 5316 additions and 2277 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import { useState } from "react";
|
||||
// hooks
|
||||
import useTheme from "./useTheme";
|
||||
import useUser from "./useUser";
|
||||
|
|
@ -7,14 +6,19 @@ import { groupBy, orderArrayBy } from "constants/common";
|
|||
// constants
|
||||
import { PRIORITIES } from "constants/";
|
||||
// types
|
||||
import type { IssueResponse, IIssue, NestedKeyOf } from "types";
|
||||
import type { IIssue } from "types";
|
||||
|
||||
const useIssuesFilter = (projectIssues?: IssueResponse) => {
|
||||
const { issueView, setIssueView, groupByProperty, setGroupByProperty } = useTheme();
|
||||
|
||||
const [orderBy, setOrderBy] = useState<NestedKeyOf<IIssue> | null>(null);
|
||||
|
||||
const [filterIssue, setFilterIssue] = useState<"activeIssue" | "backlogIssue" | null>(null);
|
||||
const useIssuesFilter = (projectIssues: IIssue[]) => {
|
||||
const {
|
||||
issueView,
|
||||
setIssueView,
|
||||
groupByProperty,
|
||||
setGroupByProperty,
|
||||
orderBy,
|
||||
setOrderBy,
|
||||
filterIssue,
|
||||
setFilterIssue,
|
||||
} = useTheme();
|
||||
|
||||
const { states } = useUser();
|
||||
|
||||
|
|
@ -27,18 +31,18 @@ const useIssuesFilter = (projectIssues?: IssueResponse) => {
|
|||
?.sort((a, b) => a.sequence - b.sequence)
|
||||
?.map((state) => [
|
||||
state.name,
|
||||
projectIssues?.results.filter((issue) => issue.state === state.name) ?? [],
|
||||
projectIssues.filter((issue) => issue.state === state.name) ?? [],
|
||||
]) ?? []
|
||||
)
|
||||
: groupByProperty === "priority"
|
||||
? Object.fromEntries(
|
||||
PRIORITIES.map((priority) => [
|
||||
priority,
|
||||
projectIssues?.results.filter((issue) => issue.priority === priority) ?? [],
|
||||
projectIssues.filter((issue) => issue.priority === priority) ?? [],
|
||||
])
|
||||
)
|
||||
: {}),
|
||||
...groupBy(projectIssues?.results ?? [], groupByProperty ?? ""),
|
||||
...groupBy(projectIssues ?? [], groupByProperty ?? ""),
|
||||
};
|
||||
|
||||
if (orderBy !== null) {
|
||||
|
|
@ -52,29 +56,29 @@ const useIssuesFilter = (projectIssues?: IssueResponse) => {
|
|||
|
||||
if (filterIssue !== null) {
|
||||
if (filterIssue === "activeIssue") {
|
||||
groupedByIssues = Object.keys(groupedByIssues).reduce((acc, key) => {
|
||||
const value = groupedByIssues[key];
|
||||
const filteredValue = value.filter(
|
||||
(issue) =>
|
||||
issue.state_detail.group === "started" || issue.state_detail.group === "unstarted"
|
||||
);
|
||||
if (filteredValue.length > 0) {
|
||||
acc[key] = filteredValue;
|
||||
}
|
||||
return acc;
|
||||
}, {} as typeof groupedByIssues);
|
||||
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") {
|
||||
groupedByIssues = Object.keys(groupedByIssues).reduce((acc, key) => {
|
||||
const value = groupedByIssues[key];
|
||||
const filteredValue = value.filter(
|
||||
(issue) =>
|
||||
issue.state_detail.group === "backlog" || issue.state_detail.group === "cancelled"
|
||||
);
|
||||
if (filteredValue.length > 0) {
|
||||
acc[key] = filteredValue;
|
||||
}
|
||||
return acc;
|
||||
}, {} as typeof groupedByIssues);
|
||||
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) ?? [],
|
||||
]) ?? []
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import useSWR from "swr";
|
|||
// api routes
|
||||
import { ISSUE_PROPERTIES_ENDPOINT } from "constants/api-routes";
|
||||
// services
|
||||
import issueServices from "lib/services/issues.services";
|
||||
import issueServices from "lib/services/issues.service";
|
||||
// hooks
|
||||
import useUser from "./useUser";
|
||||
// types
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class ProjectIssuesServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async addIssueToSprint(
|
||||
async addIssueToCycle(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
cycleId: string,
|
||||
|
|
@ -10,9 +10,12 @@ import {
|
|||
PROJECT_MEMBERS,
|
||||
PROJECT_MEMBER_DETAIL,
|
||||
USER_PROJECT_INVITATIONS,
|
||||
PROJECT_VIEW_ENDPOINT,
|
||||
} 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;
|
||||
|
||||
|
|
@ -21,8 +24,8 @@ class ProjectServices extends APIService {
|
|||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
}
|
||||
|
||||
async createProject(workspace_slug: string, data: any): Promise<any> {
|
||||
return this.post(PROJECTS_ENDPOINT(workspace_slug), data)
|
||||
async createProject(workspacSlug: string, data: Partial<IProject>): Promise<IProject> {
|
||||
return this.post(PROJECTS_ENDPOINT(workspacSlug), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -45,8 +48,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async getProjects(workspace_slug: string): Promise<any> {
|
||||
return this.get(PROJECTS_ENDPOINT(workspace_slug))
|
||||
async getProjects(workspacSlug: string): Promise<IProject[]> {
|
||||
return this.get(PROJECTS_ENDPOINT(workspacSlug))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -55,8 +58,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async getProject(workspace_slug: string, project_id: string): Promise<any> {
|
||||
return this.get(PROJECT_DETAIL(workspace_slug, project_id))
|
||||
async getProject(workspacSlug: string, projectId: string): Promise<IProject> {
|
||||
return this.get(PROJECT_DETAIL(workspacSlug, projectId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -65,8 +68,12 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async updateProject(workspace_slug: string, project_id: string, data: any): Promise<any> {
|
||||
return this.patch(PROJECT_DETAIL(workspace_slug, project_id), 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;
|
||||
})
|
||||
|
|
@ -75,8 +82,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async deleteProject(workspace_slug: string, project_id: string): Promise<any> {
|
||||
return this.delete(PROJECT_DETAIL(workspace_slug, project_id))
|
||||
async deleteProject(workspacSlug: string, projectId: string): Promise<any> {
|
||||
return this.delete(PROJECT_DETAIL(workspacSlug, projectId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -85,8 +92,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async inviteProject(workspace_slug: string, project_id: string, data: any): Promise<any> {
|
||||
return this.post(INVITE_PROJECT(workspace_slug, project_id), data)
|
||||
async inviteProject(workspacSlug: string, projectId: string, data: any): Promise<any> {
|
||||
return this.post(INVITE_PROJECT(workspacSlug, projectId), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -95,8 +102,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async joinProject(workspace_slug: string, data: any): Promise<any> {
|
||||
return this.post(JOIN_PROJECT(workspace_slug), data)
|
||||
async joinProject(workspacSlug: string, data: any): Promise<any> {
|
||||
return this.post(JOIN_PROJECT(workspacSlug), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -115,8 +122,8 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async projectMembers(workspace_slug: string, project_id: string): Promise<any> {
|
||||
return this.get(PROJECT_MEMBERS(workspace_slug, project_id))
|
||||
async projectMembers(workspacSlug: string, projectId: string): Promise<IProjectMember[]> {
|
||||
return this.get(PROJECT_MEMBERS(workspacSlug, projectId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -126,12 +133,12 @@ class ProjectServices extends APIService {
|
|||
}
|
||||
|
||||
async updateProjectMember(
|
||||
workspace_slug: string,
|
||||
project_id: string,
|
||||
workspacSlug: string,
|
||||
projectId: string,
|
||||
memberId: string,
|
||||
data: any
|
||||
): Promise<any> {
|
||||
return this.put(PROJECT_MEMBER_DETAIL(workspace_slug, project_id, memberId), data)
|
||||
data: Partial<IProjectMember>
|
||||
): Promise<IProjectMember> {
|
||||
return this.put(PROJECT_MEMBER_DETAIL(workspacSlug, projectId, memberId), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -141,11 +148,11 @@ class ProjectServices extends APIService {
|
|||
}
|
||||
|
||||
async deleteProjectMember(
|
||||
workspace_slug: string,
|
||||
project_id: string,
|
||||
workspacSlug: string,
|
||||
projectId: string,
|
||||
memberId: string
|
||||
): Promise<any> {
|
||||
return this.delete(PROJECT_MEMBER_DETAIL(workspace_slug, project_id, memberId))
|
||||
return this.delete(PROJECT_MEMBER_DETAIL(workspacSlug, projectId, memberId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -154,8 +161,11 @@ class ProjectServices extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async projectInvitations(workspace_slug: string, project_id: string): Promise<any> {
|
||||
return this.get(PROJECT_INVITATIONS(workspace_slug, project_id))
|
||||
async projectInvitations(
|
||||
workspacSlug: string,
|
||||
projectId: string
|
||||
): Promise<IProjectMemberInvitation[]> {
|
||||
return this.get(PROJECT_INVITATIONS(workspacSlug, projectId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -165,11 +175,11 @@ class ProjectServices extends APIService {
|
|||
}
|
||||
|
||||
async updateProjectInvitation(
|
||||
workspace_slug: string,
|
||||
project_id: string,
|
||||
invitation_id: string
|
||||
workspacSlug: string,
|
||||
projectId: string,
|
||||
invitationId: string
|
||||
): Promise<any> {
|
||||
return this.put(PROJECT_INVITATION_DETAIL(workspace_slug, project_id, invitation_id))
|
||||
return this.put(PROJECT_INVITATION_DETAIL(workspacSlug, projectId, invitationId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -177,12 +187,27 @@ class ProjectServices extends APIService {
|
|||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async deleteProjectInvitation(
|
||||
workspace_slug: string,
|
||||
project_id: string,
|
||||
invitation_id: string
|
||||
workspacSlug: string,
|
||||
projectId: string,
|
||||
invitationId: string
|
||||
): Promise<any> {
|
||||
return this.delete(PROJECT_INVITATION_DETAIL(workspace_slug, project_id, invitation_id))
|
||||
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: ProjectViewTheme
|
||||
): Promise<any> {
|
||||
await this.patch(PROJECT_VIEW_ENDPOINT(workspacSlug, projectId), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ class UserService extends APIService {
|
|||
};
|
||||
}
|
||||
|
||||
async userIssues(): Promise<any> {
|
||||
return this.get(USER_ISSUES_ENDPOINT)
|
||||
async userIssues(workspaceSlug: string): Promise<any> {
|
||||
return this.get(USER_ISSUES_ENDPOINT(workspaceSlug))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,18 +11,22 @@ import {
|
|||
WORKSPACE_INVITATION_DETAIL,
|
||||
USER_WORKSPACE_INVITATION,
|
||||
USER_WORKSPACE_INVITATIONS,
|
||||
LAST_ACTIVE_WORKSPACE_AND_PROJECTS,
|
||||
} 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 } from "types";
|
||||
|
||||
class WorkspaceService extends APIService {
|
||||
constructor() {
|
||||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
}
|
||||
|
||||
async userWorkspaces(): Promise<any> {
|
||||
async userWorkspaces(): Promise<IWorkspace[]> {
|
||||
return this.get(USER_WORKSPACES)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
|
|
@ -32,7 +36,7 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async createWorkspace(data: any): Promise<any> {
|
||||
async createWorkspace(data: Partial<IWorkspace>): Promise<IWorkspace> {
|
||||
return this.post(WORKSPACES_ENDPOINT, data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
|
|
@ -42,17 +46,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async updateWorkspace(workspace_slug: string, data: any): Promise<any> {
|
||||
return this.patch(WORKSPACE_DETAIL(workspace_slug), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
async deleteWorkspace(workspace_slug: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_DETAIL(workspace_slug))
|
||||
async updateWorkspace(workspaceSlug: string, data: Partial<IWorkspace>): Promise<IWorkspace> {
|
||||
return this.patch(WORKSPACE_DETAIL(workspaceSlug), data)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -61,8 +56,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async inviteWorkspace(workspace_slug: string, data: any): Promise<any> {
|
||||
return this.post(INVITE_WORKSPACE(workspace_slug), data)
|
||||
async deleteWorkspace(workspaceSlug: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_DETAIL(workspaceSlug))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -70,8 +65,19 @@ class WorkspaceService extends APIService {
|
|||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
async joinWorkspace(workspace_slug: string, InvitationId: string, data: any): Promise<any> {
|
||||
return this.post(JOIN_WORKSPACE(workspace_slug, InvitationId), 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) => {
|
||||
|
|
@ -92,7 +98,7 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async userWorkspaceInvitations(): Promise<any> {
|
||||
async userWorkspaceInvitations(): Promise<IWorkspaceMemberInvitation[]> {
|
||||
return this.get(USER_WORKSPACE_INVITATIONS)
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
|
|
@ -102,8 +108,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async workspaceMembers(workspace_slug: string): Promise<any> {
|
||||
return this.get(WORKSPACE_MEMBERS(workspace_slug))
|
||||
async workspaceMembers(workspaceSlug: string): Promise<IWorkspaceMember[]> {
|
||||
return this.get(WORKSPACE_MEMBERS(workspaceSlug))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -112,8 +118,12 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async updateWorkspaceMember(workspace_slug: string, memberId: string, data: any): Promise<any> {
|
||||
return this.put(WORKSPACE_MEMBER_DETAIL(workspace_slug, memberId), 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;
|
||||
})
|
||||
|
|
@ -122,8 +132,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async deleteWorkspaceMember(workspace_slug: string, memberId: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_MEMBER_DETAIL(workspace_slug, memberId))
|
||||
async deleteWorkspaceMember(workspaceSlug: string, memberId: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_MEMBER_DETAIL(workspaceSlug, memberId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -132,8 +142,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async workspaceInvitations(workspace_slug: string): Promise<any> {
|
||||
return this.get(WORKSPACE_INVITATIONS(workspace_slug))
|
||||
async workspaceInvitations(workspaceSlug: string): Promise<IWorkspaceMemberInvitation[]> {
|
||||
return this.get(WORKSPACE_INVITATIONS(workspaceSlug))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -142,8 +152,8 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async getWorkspaceInvitation(invitation_id: string): Promise<any> {
|
||||
return this.get(USER_WORKSPACE_INVITATION(invitation_id), { headers: {} })
|
||||
async getWorkspaceInvitation(invitationId: string): Promise<IWorkspaceMemberInvitation> {
|
||||
return this.get(USER_WORKSPACE_INVITATION(invitationId), { headers: {} })
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -152,8 +162,11 @@ class WorkspaceService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async updateWorkspaceInvitation(workspace_slug: string, invitation_id: string): Promise<any> {
|
||||
return this.put(WORKSPACE_INVITATION_DETAIL(workspace_slug, invitation_id))
|
||||
async updateWorkspaceInvitation(
|
||||
workspaceSlug: string,
|
||||
invitationId: string
|
||||
): Promise<IWorkspaceMemberInvitation> {
|
||||
return this.put(WORKSPACE_INVITATION_DETAIL(workspaceSlug, invitationId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
@ -161,8 +174,9 @@ class WorkspaceService extends APIService {
|
|||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
async deleteWorkspaceInvitations(workspace_slug: string, invitation_id: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_INVITATION_DETAIL(workspace_slug, invitation_id))
|
||||
|
||||
async deleteWorkspaceInvitations(workspaceSlug: string, invitationId: string): Promise<any> {
|
||||
return this.delete(WORKSPACE_INVITATION_DETAIL(workspaceSlug, invitationId))
|
||||
.then((response) => {
|
||||
return response?.data;
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue