Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions web/components/dropdowns/date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const DateDropdown: React.FC<Props> = (props) => {
tabIndex={tabIndex}
className={cn("h-full", className)}
onKeyDown={handleKeyDown}
disabled={disabled}
>
<Combobox.Button as={React.Fragment}>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import { TGroupedIssues, TIssue } from "@plane/types";
import { IQuickActionProps } from "../list/list-view-types";
import { EIssueActions } from "../types";
import { handleDragDrop } from "./utils";
import { useIssues } from "hooks/store";
import { useIssues, useUser } from "hooks/store";
import { ICycleIssues, ICycleIssuesFilter } from "store/issue/cycle";
import { IModuleIssues, IModuleIssuesFilter } from "store/issue/module";
import { IProjectIssues, IProjectIssuesFilter } from "store/issue/project";
import { IProjectViewIssues, IProjectViewIssuesFilter } from "store/issue/project-views";
import { EUserProjectRoles } from "constants/project";

interface IBaseCalendarRoot {
issueStore: IProjectIssues | IModuleIssues | ICycleIssues | IProjectViewIssues;
Expand All @@ -27,10 +28,11 @@ interface IBaseCalendarRoot {
[EIssueActions.REMOVE]?: (issue: TIssue) => Promise<void>;
};
viewId?: string;
isCompletedCycle?: boolean;
}

export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
const { issueStore, issuesFilterStore, QuickActions, issueActions, viewId } = props;
const { issueStore, issuesFilterStore, QuickActions, issueActions, viewId, isCompletedCycle = false } = props;

// router
const router = useRouter();
Expand All @@ -39,6 +41,11 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
// hooks
const { setToastAlert } = useToast();
const { issueMap } = useIssues();
const {
membership: { currentProjectRole },
} = useUser();

const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;

const displayFilters = issuesFilterStore.issueFilters?.displayFilters;

Expand Down Expand Up @@ -107,10 +114,12 @@ export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => {
? async () => handleIssues(issue.target_date ?? "", issue, EIssueActions.REMOVE)
: undefined
}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
)}
quickAddCallback={issueStore.quickAddIssue}
viewId={viewId}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
</DragDropContext>
</div>
Expand Down
16 changes: 14 additions & 2 deletions web/components/issues/issue-layouts/calendar/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,21 @@ type Props = {
viewId?: string
) => Promise<TIssue | undefined>;
viewId?: string;
readOnly?: boolean;
};

export const CalendarChart: React.FC<Props> = observer((props) => {
const { issuesFilterStore, issues, groupedIssueIds, layout, showWeekends, quickActions, quickAddCallback, viewId } =
props;
const {
issuesFilterStore,
issues,
groupedIssueIds,
layout,
showWeekends,
quickActions,
quickAddCallback,
viewId,
readOnly = false,
} = props;
// store hooks
const {
issues: { viewFlags },
Expand Down Expand Up @@ -80,6 +90,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
quickActions={quickActions}
quickAddCallback={quickAddCallback}
viewId={viewId}
readOnly={readOnly}
/>
))}
</div>
Expand All @@ -95,6 +106,7 @@ export const CalendarChart: React.FC<Props> = observer((props) => {
quickActions={quickActions}
quickAddCallback={quickAddCallback}
viewId={viewId}
readOnly={readOnly}
/>
)}
</div>
Expand Down
7 changes: 5 additions & 2 deletions web/components/issues/issue-layouts/calendar/day-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Props = {
viewId?: string
) => Promise<TIssue | undefined>;
viewId?: string;
readOnly?: boolean;
};

export const CalendarDayTile: React.FC<Props> = observer((props) => {
Expand All @@ -41,6 +42,7 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {
disableIssueCreation,
quickAddCallback,
viewId,
readOnly = false,
} = props;
const [showAllIssues, setShowAllIssues] = useState(false);
const calendarLayout = issuesFilterStore?.issueFilters?.displayFilters?.calendar?.layout ?? "month";
Expand Down Expand Up @@ -73,7 +75,7 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {

{/* content */}
<div className="h-full w-full">
<Droppable droppableId={formattedDatePayload} isDropDisabled={false}>
<Droppable droppableId={formattedDatePayload} isDropDisabled={readOnly}>
{(provided, snapshot) => (
<div
className={`h-full w-full select-none overflow-y-auto ${
Expand All @@ -89,9 +91,10 @@ export const CalendarDayTile: React.FC<Props> = observer((props) => {
issueIdList={issueIdList}
quickActions={quickActions}
showAllIssues={showAllIssues}
isDragDisabled={readOnly}
/>

{enableQuickIssueCreate && !disableIssueCreation && (
{enableQuickIssueCreate && !disableIssueCreation && !readOnly && (
<div className="px-2 py-1">
<CalendarQuickAddIssueForm
formKey="target_date"
Expand Down
5 changes: 3 additions & 2 deletions web/components/issues/issue-layouts/calendar/issue-blocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ type Props = {
issueIdList: string[] | null;
quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode;
showAllIssues?: boolean;
isDragDisabled?: boolean;
};

export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
const { issues, issueIdList, quickActions, showAllIssues = false } = props;
const { issues, issueIdList, quickActions, showAllIssues = false, isDragDisabled = false } = props;
// hooks
const {
router: { workspaceSlug, projectId },
Expand Down Expand Up @@ -65,7 +66,7 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
getProjectStates(issue?.project_id)?.find((state) => state?.id == issue?.state_id)?.color || "";

return (
<Draggable key={issue.id} draggableId={issue.id} index={index}>
<Draggable key={issue.id} draggableId={issue.id} index={index} isDragDisabled={isDragDisabled}>
{(provided, snapshot) => (
<div
className="relative cursor-pointer p-1 px-2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
//hooks
import { useIssues } from "hooks/store";
import { useCycle, useIssues } from "hooks/store";
// components
import { CycleIssueQuickActions } from "components/issues";
// types
Expand All @@ -13,6 +13,7 @@ import { useMemo } from "react";

export const CycleCalendarLayout: React.FC = observer(() => {
const { issues, issuesFilter } = useIssues(EIssuesStoreType.CYCLE);
const { currentProjectCompletedCycleIds } = useCycle();

const router = useRouter();
const { workspaceSlug, projectId, cycleId } = router.query;
Expand All @@ -38,13 +39,17 @@ export const CycleCalendarLayout: React.FC = observer(() => {

if (!cycleId) return null;

const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;

return (
<BaseCalendarRoot
issueStore={issues}
issuesFilterStore={issuesFilter}
QuickActions={CycleIssueQuickActions}
issueActions={issueActions}
viewId={cycleId.toString()}
isCompletedCycle={isCompletedCycle}
/>
);
});
3 changes: 3 additions & 0 deletions web/components/issues/issue-layouts/calendar/week-days.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Props = {
viewId?: string
) => Promise<TIssue | undefined>;
viewId?: string;
readOnly?: boolean;
};

export const CalendarWeekDays: React.FC<Props> = observer((props) => {
Expand All @@ -39,6 +40,7 @@ export const CalendarWeekDays: React.FC<Props> = observer((props) => {
disableIssueCreation,
quickAddCallback,
viewId,
readOnly = false,
} = props;

const calendarLayout = issuesFilterStore?.issueFilters?.displayFilters?.calendar?.layout ?? "month";
Expand Down Expand Up @@ -67,6 +69,7 @@ export const CalendarWeekDays: React.FC<Props> = observer((props) => {
disableIssueCreation={disableIssueCreation}
quickAddCallback={quickAddCallback}
viewId={viewId}
readOnly={readOnly}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface IBaseKanBanLayout {
storeType?: TCreateModalStoreTypes;
addIssuesToView?: (issueIds: string[]) => Promise<any>;
canEditPropertiesBasedOnProject?: (projectId: string) => boolean;
isCompletedCycle?: boolean;
}

type KanbanDragState = {
Expand All @@ -65,6 +66,7 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
storeType,
addIssuesToView,
canEditPropertiesBasedOnProject,
isCompletedCycle = false,
} = props;
// router
const router = useRouter();
Expand Down Expand Up @@ -183,6 +185,7 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
handleRemoveFromView={
issueActions[EIssueActions.REMOVE] ? async () => handleIssues(issue, EIssueActions.REMOVE) : undefined
}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
),
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -282,7 +285,7 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
showEmptyGroup={userDisplayFilters?.show_empty_groups || true}
quickAddCallback={issues?.quickAddIssue}
viewId={viewId}
disableIssueCreation={!enableIssueCreation || !isEditingAllowed}
disableIssueCreation={!enableIssueCreation || !isEditingAllowed || isCompletedCycle}
canEditProperties={canEditProperties}
storeType={storeType}
addIssuesToView={addIssuesToView}
Expand Down
10 changes: 9 additions & 1 deletion web/components/issues/issue-layouts/kanban/roots/cycle-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useMemo } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// hooks
import { useIssues } from "hooks/store";
import { useCycle, useIssues } from "hooks/store";
// ui
import { CycleIssueQuickActions } from "components/issues";
// types
Expand All @@ -20,6 +20,7 @@ export const CycleKanBanLayout: React.FC = observer(() => {

// store
const { issues, issuesFilter } = useIssues(EIssuesStoreType.CYCLE);
const { currentProjectCompletedCycleIds } = useCycle();

const issueActions = useMemo(
() => ({
Expand All @@ -42,6 +43,11 @@ export const CycleKanBanLayout: React.FC = observer(() => {
[issues, workspaceSlug, cycleId]
);

const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;

const canEditIssueProperties = () => !isCompletedCycle;

return (
<BaseKanBanRoot
issueActions={issueActions}
Expand All @@ -55,6 +61,8 @@ export const CycleKanBanLayout: React.FC = observer(() => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
}}
canEditPropertiesBasedOnProject={canEditIssueProperties}
isCompletedCycle={isCompletedCycle}
/>
);
});
4 changes: 4 additions & 0 deletions web/components/issues/issue-layouts/list/base-list-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ interface IBaseListRoot {
storeType: TCreateModalStoreTypes;
addIssuesToView?: (issueIds: string[]) => Promise<any>;
canEditPropertiesBasedOnProject?: (projectId: string) => boolean;
isCompletedCycle?: boolean;
}

export const BaseListRoot = observer((props: IBaseListRoot) => {
Expand All @@ -63,6 +64,7 @@ export const BaseListRoot = observer((props: IBaseListRoot) => {
storeType,
addIssuesToView,
canEditPropertiesBasedOnProject,
isCompletedCycle = false,
} = props;
// mobx store
const {
Expand Down Expand Up @@ -112,6 +114,7 @@ export const BaseListRoot = observer((props: IBaseListRoot) => {
handleRemoveFromView={
issueActions[EIssueActions.REMOVE] ? async () => handleIssues(issue, EIssueActions.REMOVE) : undefined
}
readOnly={!isEditingAllowed || isCompletedCycle}
/>
),
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand All @@ -136,6 +139,7 @@ export const BaseListRoot = observer((props: IBaseListRoot) => {
disableIssueCreation={!enableIssueCreation || !isEditingAllowed}
storeType={storeType}
addIssuesToView={addIssuesToView}
isCompletedCycle={isCompletedCycle}
/>
</div>
</>
Expand Down
9 changes: 7 additions & 2 deletions web/components/issues/issue-layouts/list/default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface IGroupByList {
storeType: TCreateModalStoreTypes;
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
viewId?: string;
isCompletedCycle?: boolean;
}

const GroupByList: React.FC<IGroupByList> = (props) => {
Expand All @@ -55,6 +56,7 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
disableIssueCreation,
storeType,
addIssuesToView,
isCompletedCycle = false,
} = props;
// store hooks
const member = useMember();
Expand Down Expand Up @@ -115,7 +117,7 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
title={_list.name || ""}
count={is_list ? issueIds?.length || 0 : issueIds?.[_list.id]?.length || 0}
issuePayload={_list.payload}
disableIssueCreation={disableIssueCreation || isGroupByCreatedBy}
disableIssueCreation={disableIssueCreation || isGroupByCreatedBy || isCompletedCycle}
storeType={storeType}
addIssuesToView={addIssuesToView}
/>
Expand All @@ -132,7 +134,7 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
/>
)}

{enableIssueQuickAdd && !disableIssueCreation && !isGroupByCreatedBy && (
{enableIssueQuickAdd && !disableIssueCreation && !isGroupByCreatedBy && !isCompletedCycle && (
<div className="sticky bottom-0 z-[1] w-full flex-shrink-0">
<ListQuickAddIssueForm
prePopulatedData={prePopulateQuickAddData(group_by, _list.id)}
Expand Down Expand Up @@ -168,6 +170,7 @@ export interface IList {
disableIssueCreation?: boolean;
storeType: TCreateModalStoreTypes;
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
isCompletedCycle?: boolean;
}

export const List: React.FC<IList> = (props) => {
Expand All @@ -186,6 +189,7 @@ export const List: React.FC<IList> = (props) => {
disableIssueCreation,
storeType,
addIssuesToView,
isCompletedCycle = false,
} = props;

return (
Expand All @@ -205,6 +209,7 @@ export const List: React.FC<IList> = (props) => {
disableIssueCreation={disableIssueCreation}
storeType={storeType}
addIssuesToView={addIssuesToView}
isCompletedCycle={isCompletedCycle}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface IQuickActionProps {
handleRemoveFromView?: () => Promise<void>;
customActionButton?: React.ReactElement;
portalElement?: HTMLDivElement | null;
readOnly?: boolean;
}
Loading