[WEB-1255] chore: public and unlocked views (#4932)

* chore private and public views required changes

* fix slight alignment of view icons

* add feedback for update View button

* fix object reference sharing by using cloneDeep to replicate objects

* addressing review comments
This commit is contained in:
rahulramesha 2024-06-25 18:21:30 +05:30 committed by GitHub
parent 711494b72e
commit 635efeab7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 524 additions and 240 deletions

View file

@ -11,11 +11,12 @@ import { Button, EmojiIconPicker, EmojiIconPickerTypes, Input, PhotoFilterIcon,
import { Logo } from "@/components/common";
import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "@/components/issues";
// constants
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue";
import { EIssueLayoutTypes, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue";
// helpers
import { convertHexEmojiToDecimal } from "@/helpers/emoji.helper";
// hooks
import { useLabel, useMember, useProject, useProjectState } from "@/hooks/store";
import { LayoutDropDown } from "../dropdowns/layout";
type Props = {
data?: IProjectView | null;
@ -190,7 +191,7 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
/>
)}
/>
<span className="text-xs text-red-500">{errors?.name?.message}</span>
<span className="text-xs text-red-500">{errors?.name?.message?.toString()}</span>
</div>
</div>
<div>
@ -211,7 +212,17 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
)}
/>
</div>
<div>
<div className="flex gap-2">
<Controller
control={control}
name="display_filters.layout"
render={({ field: { onChange, value } }) => (
<LayoutDropDown
onChange={(selectedValue: EIssueLayoutTypes) => onChange(selectedValue)}
value={value}
/>
)}
/>
<Controller
control={control}
name="filters"

View file

@ -0,0 +1,70 @@
import { SetStateAction, useEffect, useState } from "react";
import { Button } from "@plane/ui";
import { LockedComponent } from "../icons/locked-component";
type Props = {
isLocked: boolean;
areFiltersEqual: boolean;
isOwner: boolean;
isAuthorizedUser: boolean;
setIsModalOpen: (value: SetStateAction<boolean>) => void;
handleUpdateView: () => void;
lockedTooltipContent?: string;
};
export const UpdateViewComponent = (props: Props) => {
const {
isLocked,
areFiltersEqual,
isOwner,
isAuthorizedUser,
setIsModalOpen,
handleUpdateView,
lockedTooltipContent,
} = props;
const [isUpdating, setIsUpdating] = useState(false);
useEffect(() => {
if (areFiltersEqual) {
setIsUpdating(false);
}
}, [areFiltersEqual]);
// Change state while updating view to have a feedback
const updateButton = isUpdating ? (
<Button variant="primary" size="sm" className="flex-shrink-0">
Updating...
</Button>
) : (
<Button
variant="primary"
size="sm"
className="flex-shrink-0"
onClick={() => {
setIsUpdating(true);
handleUpdateView();
}}
>
Update view
</Button>
);
return (
<div className="flex gap-2">
{isLocked ? (
<LockedComponent toolTipContent={lockedTooltipContent} />
) : (
!areFiltersEqual &&
isAuthorizedUser && (
<>
<Button variant="outline-primary" size="sm" className="flex-shrink-0" onClick={() => setIsModalOpen(true)}>
Save as
</Button>
{isOwner && <>{updateButton}</>}
</>
)
)}
</div>
);
};

View file

@ -1,14 +1,16 @@
import React, { FC, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { Earth, Lock } from "lucide-react";
// types
import { IProjectView } from "@plane/types";
// ui
import { FavoriteStar } from "@plane/ui";
import { Tooltip, FavoriteStar } from "@plane/ui";
// components
import { DeleteProjectViewModal, CreateUpdateProjectViewModal, ViewQuickActions } from "@/components/views";
// constants
import { EUserProjectRoles } from "@/constants/project";
import { EViewAccess } from "@/constants/views";
// helpers
import { calculateTotalFilters } from "@/helpers/filter.helper";
// hooks
@ -39,6 +41,8 @@ export const ViewListItemAction: FC<Props> = observer((props) => {
const totalFilters = calculateTotalFilters(view.filters ?? {});
const access = view.access;
// handlers
const handleAddToFavorites = () => {
if (!workspaceSlug || !projectId) return;
@ -70,8 +74,14 @@ export const ViewListItemAction: FC<Props> = observer((props) => {
{totalFilters} {totalFilters === 1 ? "filter" : "filters"}
</p>
<div className="cursor-default text-custom-text-300">
<Tooltip tooltipContent={access === EViewAccess.PUBLIC ? "Public" : "Private"}>
{access === EViewAccess.PUBLIC ? <Earth className="h-4 w-4" /> : <Lock className="h-4 w-4" />}
</Tooltip>
</div>
{/* created by */}
{createdByDetails && <ButtonAvatars showTooltip={false} userIds={createdByDetails?.id} />}
{<ButtonAvatars showTooltip={false} userIds={createdByDetails?.id ?? []} />}
{isEditingAllowed && (
<FavoriteStar