chore: kanban drag drop logic

This commit is contained in:
gurusainath 2023-09-15 15:37:54 +05:30
parent d88a0885d5
commit 7b04adf03a
14 changed files with 530 additions and 475 deletions

View File

@ -1,5 +1,5 @@
{
"printWidth": 100,
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "es5"
}

View File

@ -23,9 +23,9 @@ export const FilterSelection = observer(() => {
const handleFilterSectionVisibility = (section_key: string) =>
issueFilterStore?.issueView &&
issueFilterStore?.issueLayout &&
issueFilterVisibilityData[
issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"
]?.filters?.[issueFilterStore?.issueLayout]?.includes(section_key);
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"]?.filters?.[
issueFilterStore?.issueLayout
]?.includes(section_key);
return (
<div className="w-full h-full overflow-hidden select-none relative flex flex-col divide-y divide-custom-border-200">

View File

@ -14,11 +14,7 @@ export const IssueContent = ({ columnId, issues }: IssueContentProps) => {
{issues && issues.length > 0 ? (
<>
{issues.map((issue: any, index: any) => (
<Draggable
draggableId={issue.id}
index={index}
key={`issue-blocks-${columnId}-${issue.id}`}
>
<Draggable draggableId={issue.id} index={index} key={`issue-blocks-${columnId}-${issue.id}`}>
{(provided: any, snapshot: any) => (
<div
key={issue.id}
@ -29,14 +25,10 @@ export const IssueContent = ({ columnId, issues }: IssueContentProps) => {
>
<div
className={`min-h-[106px] text-sm rounded p-2 px-3 shadow-md space-y-[4px] border transition-all hover:cursor-grab ${
snapshot.isDragging
? `border-blue-500 bg-blue-50`
: `border-transparent bg-white`
snapshot.isDragging ? `border-blue-500 bg-blue-50` : `border-transparent bg-white`
}`}
>
<div className="text-xs line-clamp-1 text-gray-500">
ONE-{issue.sequence_id}-{issue.sort_order}
</div>
<div className="text-xs line-clamp-1 text-gray-500">ONE-{issue.sequence_id}</div>
<div className="line-clamp-2 h-[40px] text-sm font-medium">{issue.name}</div>
<div className="h-[22px]">Footer</div>
</div>

View File

@ -4,18 +4,14 @@ import { Plus } from "lucide-react";
export const IssueHeader = () => (
<div className="relative flex items-center w-full h-full gap-1">
{/* default layout */}
<div className=" border border-red-500 flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center">
I
</div>
<div className=" border border-red-500 line-clamp-1 font-medium">Kanban Issue Heading</div>
<div className=" border border-red-500 flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center">
0
</div>
<div className="flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center">I</div>
<div className="line-clamp-1 font-medium">Kanban Issue Heading</div>
<div className="flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center">0</div>
<div className=" border border-red-500 ml-auto flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center cursor-pointer rounded-sm hover:bg-gray-100 transition-all">
<div className="ml-auto flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center cursor-pointer rounded-sm hover:bg-gray-100 transition-all">
M
</div>
<div className=" border border-red-500 flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center cursor-pointer rounded-sm hover:bg-gray-100 transition-all text-blue-800">
<div className="flex-shrink-0 w-[24px] h-[24px] flex justify-center items-center cursor-pointer rounded-sm hover:bg-gray-100 transition-all text-blue-800">
<Plus size={16} strokeWidth={2} />
</div>
</div>

View File

@ -11,8 +11,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
export const IssueKanBanViewRoot = observer(() => {
const store: RootStore = useMobxStore();
const { issueView: issueViewStore } = store;
const { issueView: issueViewStore, issueKanBanView: issueKanBanViewStore }: RootStore = useMobxStore();
const onDragEnd = (result: any) => {
if (!result) return;
@ -25,7 +24,7 @@ export const IssueKanBanViewRoot = observer(() => {
)
return;
console.log("result", result);
issueKanBanViewStore?.handleDragDrop(result.source, result.destination);
};
return (
@ -38,10 +37,7 @@ export const IssueKanBanViewRoot = observer(() => {
<DragDropContext onDragEnd={onDragEnd}>
<div className="relative w-full h-full overflow-hidden !overflow-x-scroll flex">
{Object.keys(issueViewStore?.getIssues).map((_issueStateKey: any) => (
<div
key={`${_issueStateKey}`}
className="flex-shrink-0 w-[380px] h-full relative flex flex-col"
>
<div key={`${_issueStateKey}`} className="flex-shrink-0 w-[380px] h-full relative flex flex-col">
<div className="flex-shrink-0 w-full p-2">
<IssueHeader />
</div>

View File

@ -19,8 +19,7 @@ const KanBanViewRoot = () => {
React.useEffect(() => {
console.log("request init--->");
const init = async () =>
await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug);
const init = async () => await issueViewStore.getProjectIssuesAsync(workspace_slug, project_slug);
if (workspace_slug && project_slug) init();
console.log("request completed--->");
}, [workspace_slug, project_slug, issueViewStore]);

View File

@ -63,14 +63,8 @@ export class ProjectIssuesServices extends APIService {
});
}
async getIssueActivities(
workspaceSlug: string,
projectId: string,
issueId: string
): Promise<IIssueActivity[]> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`
)
async getIssueActivities(workspaceSlug: string, projectId: string, issueId: string): Promise<IIssueActivity[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -78,9 +72,7 @@ export class ProjectIssuesServices extends APIService {
}
async getIssueComments(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`
)
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -104,10 +96,7 @@ export class ProjectIssuesServices extends APIService {
},
user: ICurrentUserResponse | undefined
) {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, data)
.then((response) => {
trackEventServices.trackIssueMovedToCycleOrModuleEvent(
{
@ -129,12 +118,7 @@ export class ProjectIssuesServices extends APIService {
});
}
async removeIssueFromCycle(
workspaceSlug: string,
projectId: string,
cycleId: string,
bridgeId: string
) {
async removeIssueFromCycle(workspaceSlug: string, projectId: string, cycleId: string, bridgeId: string) {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/${bridgeId}/`
)
@ -156,10 +140,7 @@ export class ProjectIssuesServices extends APIService {
}>;
}
) {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/`, data)
.then((response) => {
trackEventServices.trackIssueRelationEvent(response.data, "ISSUE_RELATION_CREATE", user);
return response?.data;
@ -189,10 +170,7 @@ export class ProjectIssuesServices extends APIService {
}
async createIssueProperties(workspaceSlug: string, projectId: string, data: any): Promise<any> {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/`, data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -206,8 +184,7 @@ export class ProjectIssuesServices extends APIService {
data: any
): Promise<any> {
return this.patch(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/` +
`${issuePropertyId}/`,
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-properties/` + `${issuePropertyId}/`,
data
)
.then((response) => response?.data)
@ -223,10 +200,7 @@ export class ProjectIssuesServices extends APIService {
data: Partial<IIssueComment>,
user: ICurrentUserResponse | undefined
): Promise<any> {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`, data)
.then((response) => {
trackEventServices.trackIssueCommentEvent(response.data, "ISSUE_COMMENT_CREATE", user);
return response?.data;
@ -335,10 +309,7 @@ export class ProjectIssuesServices extends APIService {
data: any,
user: ICurrentUserResponse | undefined
): Promise<any> {
return this.patch(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`,
data
)
return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`, data)
.then((response) => {
trackEventServices.trackIssueLabelEvent(
{
@ -367,9 +338,7 @@ export class ProjectIssuesServices extends APIService {
labelId: string,
user: ICurrentUserResponse | undefined
): Promise<any> {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`
)
return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`)
.then((response) => {
trackEventServices.trackIssueLabelEvent(
{
@ -393,10 +362,7 @@ export class ProjectIssuesServices extends APIService {
data: Partial<IIssue>,
user: ICurrentUserResponse | undefined
): Promise<any> {
return this.patch(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/`,
data
)
return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/`, data)
.then((response) => {
trackEventServices.trackIssueEvent(response.data, "ISSUE_UPDATE", user);
return response?.data;
@ -428,10 +394,7 @@ export class ProjectIssuesServices extends APIService {
data: any,
user: ICurrentUserResponse | undefined
): Promise<any> {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/bulk-delete-issues/`,
data
)
return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/bulk-delete-issues/`, data)
.then((response) => {
trackEventServices.trackIssueBulkDeleteEvent(data, user);
return response?.data;
@ -441,14 +404,8 @@ export class ProjectIssuesServices extends APIService {
});
}
async subIssues(
workspaceSlug: string,
projectId: string,
issueId: string
): Promise<ISubIssueResponse> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`
)
async subIssues(workspaceSlug: string, projectId: string, issueId: string): Promise<ISubIssueResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -461,10 +418,7 @@ export class ProjectIssuesServices extends APIService {
issueId: string,
data: { sub_issue_ids: string[] }
): Promise<any> {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/sub-issues/`, data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -481,10 +435,7 @@ export class ProjectIssuesServices extends APIService {
url: string;
}
): Promise<any> {
return this.post(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`,
data
)
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`, data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response;
@ -512,12 +463,7 @@ export class ProjectIssuesServices extends APIService {
});
}
async deleteIssueLink(
workspaceSlug: string,
projectId: string,
issueId: string,
linkId: string
): Promise<any> {
async deleteIssueLink(workspaceSlug: string, projectId: string, issueId: string, linkId: string): Promise<any> {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/${linkId}/`
)
@ -527,12 +473,7 @@ export class ProjectIssuesServices extends APIService {
});
}
async uploadIssueAttachment(
workspaceSlug: string,
projectId: string,
issueId: string,
file: FormData
): Promise<any> {
async uploadIssueAttachment(workspaceSlug: string, projectId: string, issueId: string, file: FormData): Promise<any> {
return this.mediaUpload(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/`,
file
@ -543,14 +484,8 @@ export class ProjectIssuesServices extends APIService {
});
}
async getIssueAttachment(
workspaceSlug: string,
projectId: string,
issueId: string
): Promise<any> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/`
)
async getIssueAttachment(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-attachments/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -590,28 +525,16 @@ export class ProjectIssuesServices extends APIService {
});
}
async retrieveArchivedIssue(
workspaceSlug: string,
projectId: string,
issueId: string
): Promise<any> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issueId}/`
)
async retrieveArchivedIssue(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issueId}/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async deleteArchivedIssue(
workspaceSlug: string,
projectId: string,
issuesId: string
): Promise<any> {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issuesId}/`
)
async deleteArchivedIssue(workspaceSlug: string, projectId: string, issuesId: string): Promise<any> {
return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/${issuesId}/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@ -648,10 +571,7 @@ export class ProjectIssuesServices extends APIService {
data: any,
user: ICurrentUserResponse
): Promise<any> {
return this.patch(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`,
data
)
return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`, data)
.then((response) => response?.data)
.catch((error) => {
throw error?.response;
@ -659,9 +579,7 @@ export class ProjectIssuesServices extends APIService {
}
async deleteDraftIssue(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.delete(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`
)
return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response;
@ -669,9 +587,7 @@ export class ProjectIssuesServices extends APIService {
}
async getDraftIssueById(workspaceSlug: string, projectId: string, issueId: string): Promise<any> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`
)
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/${issueId}/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response;

View File

@ -1,29 +0,0 @@
import { observable, action, computed, makeObservable, runInAction } from "mobx";
// types
import { RootStore } from "../root";
export interface IIssueViewStore {
loader: boolean;
error: any | null;
}
class IssueViewStore implements IIssueViewStore {
loader: boolean = false;
error: any | null = null;
// root store
rootStore;
// service
constructor(_rootStore: RootStore) {
makeObservable(this, {
// observable
loader: observable,
error: observable,
});
this.rootStore = _rootStore;
}
}
export default IssueViewStore;

View File

@ -49,11 +49,7 @@ export interface IIssueViewStore {
getIssues: IIssues | null | undefined;
// actions
getMyIssuesAsync: (workspaceId: string, fetchFilterToggle: boolean) => null | Promise<any>;
getProjectIssuesAsync: (
workspaceId: string,
projectId: string,
fetchFilterToggle: boolean
) => null | Promise<any>;
getProjectIssuesAsync: (workspaceId: string, projectId: string, fetchFilterToggle: boolean) => null | Promise<any>;
getIssuesForModulesAsync: (
workspaceId: string,
projectId: string,
@ -122,29 +118,25 @@ class IssueViewStore implements IIssueViewStore {
if (!currentView || !currentWorkspaceId) return null;
const currentLayout: TIssueLayouts = currentProjectId
? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]
?.project_issue_properties?.[currentProjectId]?.issues?.display_filters?.layout
: this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties
?.display_filters?.layout;
? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.project_issue_properties?.[currentProjectId]
?.issues?.display_filters?.layout
: this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties?.display_filters?.layout;
if (currentView === "my_issues")
return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout];
if (currentView === "my_issues") return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout];
else if (currentView === "issues" && currentProjectId)
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.issues?.[currentLayout];
else if (currentView === "modules" && currentProjectId && currentModuleId)
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.modules?.[currentModuleId]?.[
currentLayout
];
else if (currentView === "modules" && currentProjectId && currentModuleId)
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.modules?.[
currentModuleId
]?.[currentLayout];
else if (currentView === "cycles" && currentProjectId && currentCycleId)
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.cycles?.[
currentCycleId
]?.[currentLayout];
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.cycles?.[currentCycleId]?.[
currentLayout
];
else if (currentView === "views" && currentProjectId && currentViewId)
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.views?.[
currentViewId
]?.[currentLayout];
return this.issues?.[currentWorkspaceId]?.project_issues?.[currentProjectId]?.views?.[currentViewId]?.[
currentLayout
];
}
return null;
@ -156,8 +148,7 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
if (fetchFilterToggle)
await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId);
if (fetchFilterToggle) await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
null,
@ -175,8 +166,7 @@ class IssueViewStore implements IIssueViewStore {
...this?.issues[workspaceId],
my_issues: {
...this?.issues[workspaceId]?.my_issues,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]:
issuesResponse,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
},
},
};
@ -198,17 +188,12 @@ class IssueViewStore implements IIssueViewStore {
};
// fetching project issues
getProjectIssuesAsync = async (
workspaceId: string,
projectId: string,
fetchFilterToggle: boolean = true
) => {
getProjectIssuesAsync = async (workspaceId: string, projectId: string, fetchFilterToggle: boolean = true) => {
try {
this.loader = true;
this.error = null;
if (fetchFilterToggle)
await this.rootStore.issueFilters.getProjectIssueFilters(workspaceId, projectId);
if (fetchFilterToggle) await this.rootStore.issueFilters.getProjectIssueFilters(workspaceId, projectId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -217,11 +202,7 @@ class IssueViewStore implements IIssueViewStore {
null,
"issues"
);
const issuesResponse = await this.issueService.getIssuesWithParams(
workspaceId,
projectId,
filteredParams
);
const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams);
if (issuesResponse) {
const _issueResponse: any = {
@ -234,8 +215,7 @@ class IssueViewStore implements IIssueViewStore {
...this?.issues?.[workspaceId]?.project_issues?.[projectId],
issues: {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.issues,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]:
issuesResponse,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
},
},
},
@ -270,11 +250,7 @@ class IssueViewStore implements IIssueViewStore {
this.error = null;
if (fetchFilterToggle)
await this.rootStore.issueFilters.getProjectIssueModuleFilters(
workspaceId,
projectId,
moduleId
);
await this.rootStore.issueFilters.getProjectIssueModuleFilters(workspaceId, projectId, moduleId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -303,8 +279,7 @@ class IssueViewStore implements IIssueViewStore {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.modules,
[moduleId]: {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.modules?.[moduleId],
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]:
issuesResponse,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
},
},
},
@ -340,11 +315,7 @@ class IssueViewStore implements IIssueViewStore {
this.error = null;
if (fetchFilterToggle)
await this.rootStore.issueFilters.getProjectIssueCyclesFilters(
workspaceId,
projectId,
cycleId
);
await this.rootStore.issueFilters.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -373,8 +344,7 @@ class IssueViewStore implements IIssueViewStore {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.cycles,
[cycleId]: {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.cycles?.[cycleId],
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]:
issuesResponse,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
},
},
},
@ -410,11 +380,7 @@ class IssueViewStore implements IIssueViewStore {
this.error = null;
if (fetchFilterToggle)
await this.rootStore.issueFilters.getProjectIssueViewsFilters(
workspaceId,
projectId,
viewId
);
await this.rootStore.issueFilters.getProjectIssueViewsFilters(workspaceId, projectId, viewId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -423,11 +389,7 @@ class IssueViewStore implements IIssueViewStore {
viewId,
"views"
);
const issuesResponse = await this.issueService.getIssuesWithParams(
workspaceId,
projectId,
filteredParams
);
const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams);
if (issuesResponse) {
const _issueResponse: any = {
@ -442,8 +404,7 @@ class IssueViewStore implements IIssueViewStore {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.views,
[viewId]: {
...this?.issues[workspaceId]?.project_issues?.[projectId]?.views?.[viewId],
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]:
issuesResponse,
[this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
},
},
},

View File

@ -45,7 +45,7 @@ export const displayPropertyGroupBy: { key: string; title: string }[] = [
{ key: "state", title: "States" },
{ key: "state_detail.group", title: "State Groups" },
{ key: "priority", title: "Priority" },
{ key: "Project", title: "Project" }, // required this on my issues
{ key: "project", title: "Project" }, // required this on my issues
{ key: "labels", title: "Labels" },
{ key: "assignees", title: "Assignees" },
{ key: "created_by", title: "Created By" },

View File

@ -0,0 +1,175 @@
import { observable, action, makeObservable, runInAction } from "mobx";
// types
import { RootStore } from "../root";
// services
import { ProjectIssuesServices } from "services/issues.service";
export type IPeekMode = "side" | "modal" | "full";
export interface IIssueViewDetailStore {
loader: boolean;
error: any | null;
peekId: string | null;
peekMode: IPeekMode | null;
issue_detail: {
workspace: {
[key: string]: {
issues: {
[key: string]: any;
};
};
};
};
setPeekId: (issueId: string | null) => void;
setPeekMode: (issueId: IPeekMode | null) => void;
// fetch issue details
fetchIssueDetailsAsync: (workspaceId: string, projectId: string, issueId: string) => void;
// creating issue
createIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
// updating issue
updateIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
// deleting issue
deleteIssueAsync: (workspaceId: string, projectId: string, issueId: string) => void;
}
class IssueViewDetailStore implements IIssueViewDetailStore {
loader: boolean = false;
error: any | null = null;
peekId: string | null = null;
peekMode: IPeekMode | null = null;
issue_detail: {
workspace: {
[key: string]: {
issues: {
[key: string]: any;
};
};
};
} = {
workspace: {},
};
// root store
rootStore;
// service
issueService;
constructor(_rootStore: RootStore) {
makeObservable(this, {
// observable
loader: observable,
error: observable,
peekId: observable,
peekMode: observable,
issue_detail: observable,
setPeekId: action,
setPeekMode: action,
fetchIssueDetailsAsync: action,
createIssueAsync: action,
updateIssueAsync: action,
deleteIssueAsync: action,
});
this.rootStore = _rootStore;
this.issueService = new ProjectIssuesServices();
}
setPeekId = (issueId: string | null) => (this.peekId = issueId);
setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode);
fetchIssueDetailsAsync = async (workspaceId: string, projectId: string, issueId: string) => {
try {
this.loader = true;
this.error = null;
console.log("workspaceId", workspaceId);
console.log("projectId", projectId);
console.log("issueId", issueId);
runInAction(() => {
this.loader = false;
this.error = null;
});
} catch (error) {
console.log("error in fetching issue details", error);
this.loader = false;
this.error = error;
return error;
}
};
createIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
try {
this.loader = true;
this.error = null;
console.log("workspaceId", workspaceId);
console.log("projectId", projectId);
console.log("issueId", issueId);
console.log("data", data);
runInAction(() => {
this.loader = false;
this.error = null;
});
} catch (error) {
console.log("error in fetching issue details", error);
this.loader = false;
this.error = error;
return error;
}
};
updateIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
try {
this.loader = true;
this.error = null;
const issueResponse = await this.issueService.patchIssue(workspaceId, projectId, issueId, data, undefined);
if (issueResponse) {
runInAction(() => {
this.loader = false;
this.error = null;
});
}
} catch (error) {
console.log("error in fetching issue details", error);
this.loader = false;
this.error = error;
return error;
}
};
deleteIssueAsync = async (workspaceId: string, projectId: string, issueId: string) => {
try {
this.loader = true;
this.error = null;
console.log("workspaceId", workspaceId);
console.log("projectId", projectId);
console.log("issueId", issueId);
runInAction(() => {
this.loader = false;
this.error = null;
});
} catch (error) {
console.log("error in fetching issue details", error);
this.loader = false;
this.error = error;
return error;
}
};
}
export default IssueViewDetailStore;

View File

@ -178,39 +178,17 @@ export interface IIssueFilterStore {
getProjectIssueFilters: (workspaceId: string, projectId: string) => Promise<any>;
getProjectIssueModuleFilters: (
workspaceId: string,
projectId: string,
moduleId: string
) => Promise<any>;
getProjectIssueModuleFilters: (workspaceId: string, projectId: string, moduleId: string) => Promise<any>;
updateProjectIssueModuleFilters: (
workspaceId: string,
projectId: string,
moduleId: string,
data: any
) => Promise<any>;
getProjectIssueCyclesFilters: (
workspaceId: string,
projectId: string,
cycleId: string
) => Promise<any>;
updateProjectIssueCyclesFilters: (
workspaceId: string,
projectId: string,
cycleId: string,
data: any
) => Promise<any>;
getProjectIssueViewsFilters: (
workspaceId: string,
projectId: string,
viewId: string
) => Promise<any>;
updateProjectIssueViewsFilters: (
workspaceId: string,
projectId: string,
viewId: string,
data: any
) => Promise<any>;
getProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string) => Promise<any>;
updateProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string, data: any) => Promise<any>;
getProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string) => Promise<any>;
updateProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string, data: any) => Promise<any>;
}
class IssueFilterStore implements IIssueFilterStore {
@ -323,11 +301,10 @@ class IssueFilterStore implements IIssueFilterStore {
// computed
get issueLayout() {
if (!this.workspaceId) return null;
if (!this.projectId)
return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout;
if (!this.projectId) return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout;
if (this.projectId)
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.issues?.display_filters?.layout;
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters
?.layout;
}
get workspaceProjects() {
@ -341,26 +318,22 @@ class IssueFilterStore implements IIssueFilterStore {
get projectStates() {
if (!this.workspaceId || !this.projectId) return null;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[
this.projectId
]?.states;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId]
?.states;
}
get projectLabels() {
if (!this.workspaceId || !this.projectId) return null;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[
this.projectId
]?.labels;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId]
?.labels;
}
get projectMembers() {
if (!this.workspaceId || !this.projectId) return null;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[
this.projectId
]?.members;
return this.issueRenderFilters?.workspace_properties?.[this.workspaceId]?.project_properties?.[this.projectId]
?.members;
}
get projectDisplayProperties() {
if (!this.workspaceId || !this.projectId) return null;
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.display_properties as any;
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties as any;
}
get userFilters() {
@ -380,22 +353,17 @@ class IssueFilterStore implements IIssueFilterStore {
} = {
filters: null,
display_filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues
?.display_filters,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters,
display_properties_id:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.display_properties_id,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties_id,
display_properties:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.display_properties,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.display_properties,
};
if (this.issueView === "issues") {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues
?.filters,
filters: this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.filters,
};
return _issueFilters;
}
@ -404,8 +372,8 @@ class IssueFilterStore implements IIssueFilterStore {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.modules?.[this.moduleId]?.filters,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[this.moduleId]
?.filters,
};
return _issueFilters;
}
@ -414,8 +382,8 @@ class IssueFilterStore implements IIssueFilterStore {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.cycles?.[this.cycleId]?.filters,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[this.cycleId]
?.filters,
};
return _issueFilters;
}
@ -424,8 +392,8 @@ class IssueFilterStore implements IIssueFilterStore {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.views?.[this.viewId]?.filters,
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[this.viewId]
?.filters,
};
return _issueFilters;
}
@ -496,12 +464,11 @@ class IssueFilterStore implements IIssueFilterStore {
[this.projectId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId],
issues: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.issues,
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues,
[filter_type]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.issues?.[filter_type],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[
filter_type
],
[filter_key]: value,
},
},
@ -524,17 +491,13 @@ class IssueFilterStore implements IIssueFilterStore {
project_issue_properties: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties,
[this.projectId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId],
issues: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.issues,
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues,
[filter_type]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.issues?.[filter_type],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.[
filter_type
],
[filter_key]: value,
},
},
@ -556,21 +519,17 @@ class IssueFilterStore implements IIssueFilterStore {
project_issue_properties: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties,
[this.projectId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId],
modules: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.modules,
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules,
[this.moduleId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.modules?.[this.moduleId],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[
this.moduleId
],
[filter_type]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.modules?.[this.moduleId]?.[filter_type],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.modules?.[
this.moduleId
]?.[filter_type],
[filter_key]: value,
},
},
@ -595,21 +554,17 @@ class IssueFilterStore implements IIssueFilterStore {
project_issue_properties: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties,
[this.projectId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId],
cycles: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.cycles,
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles,
[this.cycleId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.cycles?.[this.cycleId],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[
this.cycleId
],
[filter_type]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.cycles?.[this.cycleId]?.[filter_type],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.cycles?.[
this.cycleId
]?.[filter_type],
[filter_key]: value,
},
},
@ -618,12 +573,7 @@ class IssueFilterStore implements IIssueFilterStore {
},
},
};
this.updateProjectIssueCyclesFilters(
this.workspaceId,
this.projectId,
this.cycleId,
this.userFilters?.filters
);
this.updateProjectIssueCyclesFilters(this.workspaceId, this.projectId, this.cycleId, this.userFilters?.filters);
}
if (this.issueView === "views" && this.viewId) {
@ -634,21 +584,17 @@ class IssueFilterStore implements IIssueFilterStore {
project_issue_properties: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties,
[this.projectId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId],
views: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.views,
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views,
[this.viewId]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.views?.[this.viewId],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[
this.viewId
],
[filter_type]: {
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[
this.projectId
]?.views?.[this.viewId]?.[filter_type],
...this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.views?.[
this.viewId
]?.[filter_type],
[filter_key]: value,
},
},
@ -657,12 +603,7 @@ class IssueFilterStore implements IIssueFilterStore {
},
},
};
this.updateProjectIssueViewsFilters(
this.workspaceId,
this.projectId,
this.viewId,
this.userFilters?.filters
);
this.updateProjectIssueViewsFilters(this.workspaceId, this.projectId, this.viewId, this.userFilters?.filters);
}
}
@ -671,26 +612,11 @@ class IssueFilterStore implements IIssueFilterStore {
if (this.issueView === "issues")
this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false);
if (this.issueView === "modules" && this.moduleId)
this.rootStore?.issueView?.getIssuesForModulesAsync(
this.workspaceId,
this.projectId,
this.moduleId,
false
);
this.rootStore?.issueView?.getIssuesForModulesAsync(this.workspaceId, this.projectId, this.moduleId, false);
if (this.issueView === "cycles" && this.cycleId)
this.rootStore?.issueView?.getIssuesForCyclesAsync(
this.workspaceId,
this.projectId,
this.cycleId,
false
);
this.rootStore?.issueView?.getIssuesForCyclesAsync(this.workspaceId, this.projectId, this.cycleId, false);
if (this.issueView === "views" && this.viewId)
this.rootStore?.issueView?.getIssuesForViewsAsync(
this.workspaceId,
this.projectId,
this.viewId,
false
);
this.rootStore?.issueView?.getIssuesForViewsAsync(this.workspaceId, this.projectId, this.viewId, false);
};
computedFilter = (filters: any, filteredParams: any) => {
@ -698,9 +624,7 @@ class IssueFilterStore implements IIssueFilterStore {
Object.keys(filters).map((key) => {
if (filters[key] != undefined && filteredParams.includes(key))
computedFilters[key] =
typeof filters[key] === "string" || typeof filters[key] === "boolean"
? filters[key]
: filters[key].join(",");
typeof filters[key] === "string" || typeof filters[key] === "boolean" ? filters[key] : filters[key].join(",");
});
return computedFilters;
@ -926,33 +850,25 @@ class IssueFilterStore implements IIssueFilterStore {
order_by: issuesFiltersResponse?.view_props?.display_filters?.order_by ?? null,
type: issuesFiltersResponse?.view_props?.display_filters?.type ?? null,
sub_issue: issuesFiltersResponse?.view_props?.display_filters?.sub_issue ?? false,
show_empty_groups:
issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false,
show_empty_groups: issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false,
layout: issuesFiltersResponse?.view_props?.display_filters?.layout ?? "list",
calendar_date_range:
issuesFiltersResponse?.view_props?.display_filters?.calendar_date_range ?? false,
start_target_date:
issuesFiltersResponse?.view_props?.display_filters?.start_target_date ?? true,
calendar_date_range: issuesFiltersResponse?.view_props?.display_filters?.calendar_date_range ?? false,
start_target_date: issuesFiltersResponse?.view_props?.display_filters?.start_target_date ?? true,
},
display_properties: {
assignee: issuesFiltersResponse?.view_props?.display_properties?.assignee ?? false,
attachment_count:
issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false,
created_on:
issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false,
attachment_count: issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false,
created_on: issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false,
due_date: issuesFiltersResponse?.view_props?.display_properties?.due_date ?? false,
estimate: issuesFiltersResponse?.view_props?.display_properties?.estimate ?? false,
key: issuesFiltersResponse?.view_props?.display_properties?.key ?? false,
labels: issuesFiltersResponse?.view_props?.display_properties?.labels ?? false,
link: issuesFiltersResponse?.view_props?.display_properties?.link ?? false,
priority: issuesFiltersResponse?.view_props?.display_properties?.priority ?? false,
start_date:
issuesFiltersResponse?.view_props?.display_properties?.start_date ?? false,
start_date: issuesFiltersResponse?.view_props?.display_properties?.start_date ?? false,
state: issuesFiltersResponse?.view_props?.display_properties?.state ?? false,
sub_issue_count:
issuesFiltersResponse?.view_props?.display_properties?.sub_issue_count ?? false,
updated_on:
issuesFiltersResponse?.view_props?.display_properties?.updated_on ?? false,
sub_issue_count: issuesFiltersResponse?.view_props?.display_properties?.sub_issue_count ?? false,
updated_on: issuesFiltersResponse?.view_props?.display_properties?.updated_on ?? false,
},
},
},
@ -979,10 +895,7 @@ class IssueFilterStore implements IIssueFilterStore {
const payload = {
view_props: data,
};
const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(
workspaceId,
payload
);
const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(workspaceId, payload);
if (issuesFiltersResponse) {
runInAction(() => {
@ -1014,8 +927,7 @@ class IssueFilterStore implements IIssueFilterStore {
project_properties: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties,
[projectId]: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]
?.project_properties?.[projectId],
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId],
states: issuesStateResponse,
},
},
@ -1053,8 +965,7 @@ class IssueFilterStore implements IIssueFilterStore {
project_properties: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties,
[projectId]: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]
?.project_properties?.[projectId],
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId],
labels: issuesLabelsResponse,
},
},
@ -1081,10 +992,7 @@ class IssueFilterStore implements IIssueFilterStore {
this.loader = true;
this.error = null;
const issuesMembersResponse = await this.projectService.projectMembers(
workspaceId,
projectId
);
const issuesMembersResponse = await this.projectService.projectMembers(workspaceId, projectId);
if (issuesMembersResponse) {
const _issuesMembersResponse = {
...this.issueRenderFilters,
@ -1095,8 +1003,7 @@ class IssueFilterStore implements IIssueFilterStore {
project_properties: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties,
[projectId]: {
...this.issueRenderFilters?.workspace_properties?.[workspaceId]
?.project_properties?.[projectId],
...this.issueRenderFilters?.workspace_properties?.[workspaceId]?.project_properties?.[projectId],
members: issuesMembersResponse,
},
},
@ -1124,10 +1031,7 @@ class IssueFilterStore implements IIssueFilterStore {
this.loader = true;
this.error = null;
const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(
workspaceId,
projectId
);
const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(workspaceId, projectId);
if (issuesDisplayPropertiesResponse) {
const _myUserId: string = issuesDisplayPropertiesResponse?.user;
@ -1206,10 +1110,7 @@ class IssueFilterStore implements IIssueFilterStore {
this.loader = true;
this.error = null;
const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(
workspaceId,
projectId
);
const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(workspaceId, projectId);
if (issuesDisplayFiltersResponse) {
const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters };
@ -1256,11 +1157,7 @@ class IssueFilterStore implements IIssueFilterStore {
const payload: any = {
view_props: data,
};
const issuesFiltersResponse = await this.projectService.setProjectView(
workspaceId,
projectId,
payload
);
const issuesFiltersResponse = await this.projectService.setProjectView(workspaceId, projectId, payload);
if (issuesFiltersResponse) {
runInAction(() => {
@ -1302,22 +1199,14 @@ class IssueFilterStore implements IIssueFilterStore {
}
};
getProjectIssueModuleFilters = async (
workspaceId: string,
projectId: string,
moduleId: string
) => {
getProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string) => {
try {
this.loader = true;
this.error = null;
await this.getProjectIssueFilters(workspaceId, projectId);
const issuesFiltersModuleResponse = await this.moduleService.getModuleDetails(
workspaceId,
projectId,
moduleId
);
const issuesFiltersModuleResponse = await this.moduleService.getModuleDetails(workspaceId, projectId, moduleId);
if (issuesFiltersModuleResponse) {
const _filters = { ...issuesFiltersModuleResponse?.view_props?.filters };
@ -1330,11 +1219,9 @@ class IssueFilterStore implements IIssueFilterStore {
[projectId]: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId],
modules: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]
?.modules,
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules,
[moduleId]: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]
?.modules?.[moduleId],
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[moduleId],
filters: {
priority: _filters?.priority ?? undefined,
state: _filters?.state ?? undefined,
@ -1365,12 +1252,7 @@ class IssueFilterStore implements IIssueFilterStore {
return error;
}
};
updateProjectIssueModuleFilters = async (
workspaceId: string,
projectId: string,
moduleId: string,
data: any
) => {
updateProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string, data: any) => {
try {
this.loader = true;
this.error = null;
@ -1401,22 +1283,14 @@ class IssueFilterStore implements IIssueFilterStore {
}
};
getProjectIssueCyclesFilters = async (
workspaceId: string,
projectId: string,
cycleId: string
) => {
getProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string) => {
try {
this.loader = true;
this.error = null;
await this.getProjectIssueFilters(workspaceId, projectId);
const issuesFiltersCycleResponse = await this.cycleService.getCycleDetails(
workspaceId,
projectId,
cycleId
);
const issuesFiltersCycleResponse = await this.cycleService.getCycleDetails(workspaceId, projectId, cycleId);
if (issuesFiltersCycleResponse) {
const _filters = { ...issuesFiltersCycleResponse?.view_props?.filters };
@ -1431,8 +1305,7 @@ class IssueFilterStore implements IIssueFilterStore {
cycles: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles,
[cycleId]: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]
?.modules?.[cycleId],
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[cycleId],
filters: {
priority: _filters?.priority ?? undefined,
state: _filters?.state ?? undefined,
@ -1463,12 +1336,7 @@ class IssueFilterStore implements IIssueFilterStore {
return error;
}
};
updateProjectIssueCyclesFilters = async (
workspaceId: string,
projectId: string,
cycleId: string,
data: any
) => {
updateProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string, data: any) => {
try {
this.loader = true;
this.error = null;
@ -1506,11 +1374,7 @@ class IssueFilterStore implements IIssueFilterStore {
await this.getProjectIssueFilters(workspaceId, projectId);
const issuesFiltersViewResponse = await this.viewService.getViewDetails(
workspaceId,
projectId,
viewId
);
const issuesFiltersViewResponse = await this.viewService.getViewDetails(workspaceId, projectId, viewId);
if (issuesFiltersViewResponse) {
const _filters = { ...issuesFiltersViewResponse?.query_data } as any;
@ -1525,8 +1389,7 @@ class IssueFilterStore implements IIssueFilterStore {
views: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.cycles,
[viewId]: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]
?.modules?.[viewId],
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.modules?.[viewId],
filters: {
priority: _filters?.priority ?? undefined,
state: _filters?.state ?? undefined,
@ -1557,12 +1420,7 @@ class IssueFilterStore implements IIssueFilterStore {
return error;
}
};
updateProjectIssueViewsFilters = async (
workspaceId: string,
projectId: string,
viewId: string,
data: any
) => {
updateProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string, data: any) => {
try {
this.loader = true;
this.error = null;

View File

@ -0,0 +1,185 @@
import { action, computed, makeObservable } from "mobx";
// types
import { RootStore } from "../root";
export interface IIssueKanBanViewStore {
handleDragDrop: (source: any, destination: any) => void;
}
class IssueKanBanViewStore implements IIssueKanBanViewStore {
// root store
rootStore;
constructor(_rootStore: RootStore) {
makeObservable(this, {
// computed
canUserDragDrop: computed,
canUserDragDropVertically: computed,
canUserDragDropHorizontally: computed,
// actions
handleDragDrop: action,
});
this.rootStore = _rootStore;
}
get canUserDragDrop() {
if (
this.rootStore?.issueFilters?.issueView &&
this.rootStore?.issueFilters?.userFilters?.display_filters?.group_by &&
this.rootStore?.issueFilters?.userFilters?.display_filters?.order_by &&
!["my_issues"].includes(this.rootStore?.issueFilters?.issueView) &&
["state", "priority"].includes(this.rootStore?.issueFilters?.userFilters?.display_filters?.group_by) &&
this.rootStore?.issueFilters?.userFilters?.display_filters?.order_by === "sort_order"
) {
return true;
}
return false;
}
get canUserDragDropVertically() {
return true;
}
get canUserDragDropHorizontally() {
return true;
}
handleDragDrop = async (source: any, destination: any) => {
const workspaceId = this.rootStore?.issueFilters?.workspaceId;
const projectId = this.rootStore?.issueFilters?.projectId;
const issueView = this.rootStore?.issueFilters?.issueView;
const issueLayout = this.rootStore?.issueFilters?.userFilters?.display_filters?.layout;
const sortOrderDefaultValue = 10000;
if (
this.rootStore?.issueView?.getIssues &&
workspaceId &&
projectId &&
issueView &&
issueLayout &&
issueView != "my_issues"
) {
const projectSortedIssues: any =
this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId]?.[issueView]?.[issueLayout];
let updateIssue: any = {
workspaceId: workspaceId,
projectId: projectId,
};
// user can drag the issues from any direction
if (this.canUserDragDrop) {
// vertical
if (source.droppableId === destination.droppableId) {
const _columnId = source.droppableId;
const _issues = projectSortedIssues[_columnId];
// update the sort order
if (destination.index === 0) {
updateIssue = { ...updateIssue, sort_order: _issues[destination.index].sort_order - sortOrderDefaultValue };
} else if (destination.index === _issues.length - 1) {
updateIssue = { ...updateIssue, sort_order: _issues[destination.index].sort_order + sortOrderDefaultValue };
} else {
updateIssue = {
...updateIssue,
sort_order: (_issues[destination.index - 1].sort_order + _issues[destination.index].sort_order) / 2,
};
}
// update the mobx state array
const [removed] = _issues.splice(source.index, 1);
_issues.splice(destination.index, 0, { ...removed, sort_order: updateIssue.sort_order });
updateIssue = { ...updateIssue, issueId: removed?.id };
projectSortedIssues[_columnId] = _issues;
}
// horizontal
if (source.droppableId != destination.droppableId) {
const _sourceColumnId = source.droppableId;
const _destinationColumnId = destination.droppableId;
const _sourceIssues = projectSortedIssues[_sourceColumnId];
const _destinationIssues = projectSortedIssues[_destinationColumnId];
if (_destinationIssues.length > 0) {
if (destination.index === 0) {
updateIssue = {
...updateIssue,
sort_order: _destinationIssues[destination.index].sort_order - sortOrderDefaultValue,
state: destination?.droppableId,
};
} else if (destination.index === _destinationIssues.length - 1) {
updateIssue = {
...updateIssue,
sort_order: _destinationIssues[destination.index].sort_order + sortOrderDefaultValue,
state: destination?.droppableId,
};
} else {
updateIssue = {
...updateIssue,
sort_order:
(_destinationIssues[destination.index - 1].sort_order +
_destinationIssues[destination.index].sort_order) /
2,
state: destination?.droppableId,
};
}
} else {
updateIssue = {
...updateIssue,
sort_order: sortOrderDefaultValue,
state: destination?.droppableId,
};
}
const [removed] = _sourceIssues.splice(source.index, 1);
_destinationIssues.splice(destination.index, 0, {
...removed,
state: destination?.droppableId,
sort_order: updateIssue.sort_order,
});
updateIssue = { ...updateIssue, issueId: removed?.id };
projectSortedIssues[_sourceColumnId] = _sourceIssues;
projectSortedIssues[_destinationColumnId] = _destinationIssues;
}
}
// user can drag the issues only vertically
if (this.canUserDragDropVertically && source.droppableId === destination.droppableId) {
}
// user can drag the issues only horizontally
if (this.canUserDragDropHorizontally && source.droppableId != destination.droppableId) {
}
this.rootStore.issueView.issues = {
...this.rootStore?.issueView.issues,
[workspaceId]: {
...this.rootStore?.issueView.issues?.[workspaceId],
project_issues: {
...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues,
[projectId]: {
...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId],
[issueView]: {
...this.rootStore?.issueView.issues?.[workspaceId]?.project_issues?.[projectId]?.[issueView],
[issueLayout]: projectSortedIssues,
},
},
},
},
};
this.rootStore.issueDetail?.updateIssueAsync(
updateIssue.workspaceId,
updateIssue.projectId,
updateIssue.issueId,
updateIssue
);
}
};
}
export default IssueKanBanViewStore;

View File

@ -9,6 +9,8 @@ import IssuesStore from "./issues";
// issues views and filters
import IssueFilterStore from "./issue-views/issue_filters";
import IssueViewStore from "./issue-views/Issues";
import IssueViewDetailStore from "./issue-views/issue_detail";
import IssueKanBanViewStore from "./issue-views/kanban-view";
enableStaticRendering(typeof window === "undefined");
@ -20,6 +22,8 @@ export class RootStore {
issues: IssuesStore;
issueFilters: IssueFilterStore;
issueView: IssueViewStore;
issueDetail: IssueViewDetailStore;
issueKanBanView: IssueKanBanViewStore;
constructor() {
this.user = new UserStore(this);
@ -29,5 +33,7 @@ export class RootStore {
this.issues = new IssuesStore(this);
this.issueFilters = new IssueFilterStore(this);
this.issueView = new IssueViewStore(this);
this.issueDetail = new IssueViewDetailStore(this);
this.issueKanBanView = new IssueKanBanViewStore(this);
}
}