Skip to content

Commit

Permalink
issues rendering in all issue layouts fir profile and project issues …
Browse files Browse the repository at this point in the history
…and global issues store implementation (#2886)

* dev: draft and archived issue store

* connect draft and archived issues

* kanban for draft issues

* fix filter store for calendar and kanban

* dev: profile issues store and draft issues filters in header

* disble issue creation for draft issues

* dev: profile issues store filters

* disable kanban properties in draft issues

* dev: profile issues store filters

* dev: seperated adding issues to the cycle and module as seperate methds in cycle and module store

* dev: workspace profile issues store

* dev: sub group issues in the swimlanes

* profile issues and create issue connection

* fix profile issues

* fix spreadsheet issues

* fix dissapearing project from create issue modal

* page level modifications

* fix additional bugs

* dev: issues profile and global iisues and filters update

* fix issue related bugs

* fix project views for list and kanban

* fix build errors

---------

Co-authored-by: rahulramesha <[email protected]>
  • Loading branch information
gurusainath and rahulramesha authored Nov 27, 2023
1 parent eb78fd6 commit 2bf7e63
Show file tree
Hide file tree
Showing 116 changed files with 3,190 additions and 915 deletions.
3 changes: 3 additions & 0 deletions web/components/command-palette/command-pallette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const CommandPalette: FC = observer(() => {
toggleBulkDeleteIssueModal,
isDeleteIssueModalOpen,
toggleDeleteIssueModal,

createIssueStoreType,
} = commandPalette;

const isAnyModalOpen = Boolean(
Expand Down Expand Up @@ -224,6 +226,7 @@ export const CommandPalette: FC = observer(() => {
prePopulateData={
cycleId ? { cycle: cycleId.toString() } : moduleId ? { module: moduleId.toString() } : undefined
}
currentStore={createIssueStoreType}
/>

{issueId && issueDetails && (
Expand Down
15 changes: 9 additions & 6 deletions web/components/headers/cycle-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOption
// constants
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
import { EFilterType } from "store/issues/types";
import { EProjectStore } from "store/command-palette.store";

export const CycleIssuesHeader: React.FC = observer(() => {
const [analyticsModal, setAnalyticsModal] = useState(false);
Expand All @@ -33,7 +34,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {

const {
cycle: cycleStore,
cycleIssueFilters: cycleIssueFiltersStore,
projectIssuesFilter: projectIssueFiltersStore,
project: { currentProjectDetails },
projectMember: { projectMembers },
Expand Down Expand Up @@ -190,11 +190,14 @@ export const CycleIssuesHeader: React.FC = observer(() => {
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
Analytics
</Button>
<Button onClick={() => {
setTrackElement("CYCLE_PAGE_HEADER")
commandPaletteStore.toggleCreateIssueModal(true)
}
} size="sm" prependIcon={<Plus />}>
<Button
onClick={() => {
setTrackElement("CYCLE_PAGE_HEADER");
commandPaletteStore.toggleCreateIssueModal(true, EProjectStore.CYCLE);
}}
size="sm"
prependIcon={<Plus />}
>
Add Issue
</Button>
<button
Expand Down
15 changes: 9 additions & 6 deletions web/components/headers/module-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOption
// constants
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
import { EFilterType } from "store/issues/types";
import { EProjectStore } from "store/command-palette.store";

export const ModuleIssuesHeader: React.FC = observer(() => {
const [analyticsModal, setAnalyticsModal] = useState(false);
Expand All @@ -33,7 +34,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {

const {
module: moduleStore,
projectIssuesFilter: projectIssueFiltersStore,
project: projectStore,
projectMember: { projectMembers },
projectState: projectStateStore,
Expand Down Expand Up @@ -191,11 +191,14 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
Analytics
</Button>
<Button onClick={() => {
setTrackElement("MODULE_PAGE_HEADER")
commandPaletteStore.toggleCreateIssueModal(true)
}
} size="sm" prependIcon={<Plus />}>
<Button
onClick={() => {
setTrackElement("MODULE_PAGE_HEADER");
commandPaletteStore.toggleCreateIssueModal(true, EProjectStore.MODULE);
}}
size="sm"
prependIcon={<Plus />}
>
Add Issue
</Button>
<button
Expand Down
93 changes: 89 additions & 4 deletions web/components/headers/project-draft-issues.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,74 @@
import { FC } from "react";
import { FC, useCallback } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// hooks
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
// ui
import { Breadcrumbs, LayersIcon } from "@plane/ui";
// helper
import { renderEmoji } from "helpers/emoji.helper";
import { EFilterType } from "store/issues/types";
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "types";
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";

export const ProjectDraftIssueHeader: FC = observer(() => {
const router = useRouter();
const { workspaceSlug } = router.query;
const { workspaceSlug, projectId } = router.query as { workspaceSlug: string; projectId: string };

const { project: projectStore } = useMobxStore();
const { currentProjectDetails } = projectStore;
const {
project: { currentProjectDetails },
projectLabel: { projectLabels },
projectMember: { projectMembers },
projectState: projectStateStore,
projectDraftIssuesFilter: { issueFilters, updateFilters },
} = useMobxStore();

const activeLayout = issueFilters?.displayFilters?.layout;

const handleFiltersUpdate = useCallback(
(key: keyof IIssueFilterOptions, value: string | string[]) => {
if (!workspaceSlug || !projectId) return;
const newValues = issueFilters?.filters?.[key] ?? [];

if (Array.isArray(value)) {
value.forEach((val) => {
if (!newValues.includes(val)) newValues.push(val);
});
} else {
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
else newValues.push(value);
}

updateFilters(workspaceSlug, projectId, EFilterType.FILTERS, { [key]: newValues });
},
[workspaceSlug, projectId, issueFilters, updateFilters]
);

const handleLayoutChange = useCallback(
(layout: TIssueLayouts) => {
if (!workspaceSlug || !projectId) return;
updateFilters(workspaceSlug, projectId, EFilterType.DISPLAY_FILTERS, { layout: layout });
},
[workspaceSlug, projectId, updateFilters]
);

const handleDisplayFilters = useCallback(
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
if (!workspaceSlug || !projectId) return;
updateFilters(workspaceSlug, projectId, EFilterType.DISPLAY_FILTERS, updatedDisplayFilter);
},
[workspaceSlug, projectId, updateFilters]
);

const handleDisplayProperties = useCallback(
(property: Partial<IIssueDisplayProperties>) => {
if (!workspaceSlug || !projectId) return;
updateFilters(workspaceSlug, projectId, EFilterType.DISPLAY_PROPERTIES, property);
},
[workspaceSlug, projectId, updateFilters]
);
return (
<div className="relative flex w-full flex-shrink-0 flex-row z-10 h-[3.75rem] items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex items-center gap-2 flex-grow w-full whitespace-nowrap overflow-ellipsis">
Expand Down Expand Up @@ -44,6 +98,37 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
/>
</Breadcrumbs>
</div>

<div className="ml-auto flex items-center gap-2">
<LayoutSelection
layouts={["list", "kanban"]}
onChange={(layout) => handleLayoutChange(layout)}
selectedLayout={activeLayout}
/>
<FiltersDropdown title="Filters" placement="bottom-end">
<FilterSelection
filters={issueFilters?.filters ?? {}}
handleFiltersUpdate={handleFiltersUpdate}
layoutDisplayFiltersOptions={
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
}
labels={projectLabels ?? undefined}
members={projectMembers?.map((m) => m.member)}
states={projectStateStore.states?.[projectId ?? ""] ?? undefined}
/>
</FiltersDropdown>
<FiltersDropdown title="Display" placement="bottom-end">
<DisplayFiltersSelection
layoutDisplayFiltersOptions={
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
}
displayFilters={issueFilters?.displayFilters ?? {}}
handleDisplayFiltersUpdate={handleDisplayFilters}
displayProperties={issueFilters?.displayProperties ?? {}}
handleDisplayPropertiesUpdate={handleDisplayProperties}
/>
</FiltersDropdown>
</div>
</div>
</div>
);
Expand Down
14 changes: 9 additions & 5 deletions web/components/headers/project-issues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
// helper
import { renderEmoji } from "helpers/emoji.helper";
import { EFilterType } from "store/issues/types";
import { EProjectStore } from "store/command-palette.store";

export const ProjectIssuesHeader: React.FC = observer(() => {
const [analyticsModal, setAnalyticsModal] = useState(false);
Expand Down Expand Up @@ -199,11 +200,14 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
Analytics
</Button>
<Button onClick={() => {
setTrackElement("PROJECT_PAGE_HEADER");
commandPaletteStore.toggleCreateIssueModal(true)
}
} size="sm" prependIcon={<Plus />}>
<Button
onClick={() => {
setTrackElement("PROJECT_PAGE_HEADER");
commandPaletteStore.toggleCreateIssueModal(true, EProjectStore.PROJECT);
}}
size="sm"
prependIcon={<Plus />}
>
Add Issue
</Button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion web/components/issues/delete-issue-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const DeleteIssueModal: React.FC<Props> = (props) => {
<p className="text-sm text-custom-text-200">
Are you sure you want to delete issue{" "}
<span className="break-words font-medium text-custom-text-100">
{data?.project_detail.identifier}-{data?.sequence_id}
{data?.project_detail?.identifier}-{data?.sequence_id}
</span>
{""}? All of the data related to the issue will be permanently removed. This action cannot be
undone.
Expand Down
2 changes: 1 addition & 1 deletion web/components/issues/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export const IssueForm: FC<IssueFormProps> = observer((props) => {
...defaultValues,
...initialData,
});
}, [setFocus, initialData, reset]);
}, [setFocus, reset]);

// update projectId in form when projectId changes
useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,28 @@ import { useMobxStore } from "lib/mobx/store-provider";
import { CalendarChart } from "components/issues";
// types
import { IIssue } from "types";
import { ICycleIssuesStore, IModuleIssuesStore, IProjectIssuesStore, IViewIssuesStore } from "store/issues";
import { IIssueCalendarViewStore, IssueStore } from "store/issue";
import {
ICycleIssuesFilterStore,
ICycleIssuesStore,
IModuleIssuesFilterStore,
IModuleIssuesStore,
IProjectIssuesFilterStore,
IProjectIssuesStore,
IViewIssuesFilterStore,
IViewIssuesStore,
} from "store/issues";
import { IIssueCalendarViewStore } from "store/issue";
import { IQuickActionProps } from "../list/list-view-types";
import { EIssueActions } from "../types";
import { IGroupedIssues } from "store/issues/types";

interface IBaseCalendarRoot {
issueStore: IProjectIssuesStore | IModuleIssuesStore | ICycleIssuesStore | IViewIssuesStore;
issuesFilterStore:
| IProjectIssuesFilterStore
| IModuleIssuesFilterStore
| ICycleIssuesFilterStore
| IViewIssuesFilterStore;
calendarViewStore: IIssueCalendarViewStore;
QuickActions: FC<IQuickActionProps>;
issueActions: {
Expand All @@ -26,10 +40,9 @@ interface IBaseCalendarRoot {
}

export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
const { issueStore, calendarViewStore, QuickActions, issueActions, viewId } = props;
const { projectIssuesFilter: issueFilterStore } = useMobxStore();
const { issueStore, issuesFilterStore, calendarViewStore, QuickActions, issueActions, viewId } = props;

const displayFilters = issueFilterStore.issueFilters?.displayFilters;
const displayFilters = issuesFilterStore.issueFilters?.displayFilters;

const issues = issueStore.getIssues;
const groupedIssueIds = (issueStore.getIssuesIds ?? {}) as IGroupedIssues;
Expand Down Expand Up @@ -75,7 +88,7 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
}
handleRemoveFromView={
issueActions[EIssueActions.REMOVE]
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.UPDATE)
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.REMOVE)
: undefined
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import { EIssueActions } from "../../types";
import { BaseCalendarRoot } from "../base-calendar-root";

export const CycleCalendarLayout: React.FC = observer(() => {
const { cycleIssues: cycleIssueStore, cycleIssueCalendarView: cycleIssueCalendarViewStore } = useMobxStore();
const {
cycleIssues: cycleIssueStore,
cycleIssuesFilter: cycleIssueFilterStore,
cycleIssueCalendarView: cycleIssueCalendarViewStore,
} = useMobxStore();

const router = useRouter();
const { workspaceSlug, cycleId } = router.query as { workspaceSlug: string; cycleId: string };
Expand All @@ -34,6 +38,7 @@ export const CycleCalendarLayout: React.FC = observer(() => {
return (
<BaseCalendarRoot
issueStore={cycleIssueStore}
issuesFilterStore={cycleIssueFilterStore}
calendarViewStore={cycleIssueCalendarViewStore}
QuickActions={CycleIssueQuickActions}
issueActions={issueActions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import { EIssueActions } from "../../types";
import { BaseCalendarRoot } from "../base-calendar-root";

export const ModuleCalendarLayout: React.FC = observer(() => {
const { moduleIssues: moduleIssueStore, moduleIssueCalendarView: moduleIssueCalendarViewStore } = useMobxStore();
const {
moduleIssues: moduleIssueStore,
moduleIssuesFilter: moduleIssueFilterStore,
moduleIssueCalendarView: moduleIssueCalendarViewStore,
} = useMobxStore();

const router = useRouter();
const { workspaceSlug, moduleId } = router.query as { workspaceSlug: string; moduleId: string };
Expand All @@ -33,6 +37,7 @@ export const ModuleCalendarLayout: React.FC = observer(() => {
return (
<BaseCalendarRoot
issueStore={moduleIssueStore}
issuesFilterStore={moduleIssueFilterStore}
calendarViewStore={moduleIssueCalendarViewStore}
QuickActions={ModuleIssueQuickActions}
issueActions={issueActions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,26 @@ export const CalendarLayout: React.FC = observer(() => {
const {
projectIssues: issueStore,
issueCalendarView: issueCalendarViewStore,
issueDetail: issueDetailStore,
projectIssuesFilter: projectIssueFiltersStore,
} = useMobxStore();

const issueActions = {
[EIssueActions.UPDATE]: async (issue: IIssue) => {
if (!workspaceSlug) return;

issueDetailStore.updateIssue(workspaceSlug.toString(), issue.project, issue.id, issue);
issueStore.updateIssue(workspaceSlug.toString(), issue.project, issue.id, issue);
},
[EIssueActions.DELETE]: async (issue: IIssue) => {
if (!workspaceSlug) return;

issueDetailStore.deleteIssue(workspaceSlug.toString(), issue.project, issue.id);
issueStore.removeIssue(workspaceSlug.toString(), issue.project, issue.id);
},
};

return (
<BaseCalendarRoot
issueStore={issueStore}
issuesFilterStore={projectIssueFiltersStore}
calendarViewStore={issueCalendarViewStore}
QuickActions={ProjectIssueQuickActions}
issueActions={issueActions}
Expand Down
Loading

1 comment on commit 2bf7e63

@vercel
Copy link

@vercel vercel bot commented on 2bf7e63 Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

plane-dev – ./web/

plane-dev-git-develop-plane.vercel.app
plane-dev-plane.vercel.app
plane-dev.vercel.app
crew42.plane.so

Please sign in to comment.