[WEB-1981] chore: project view icon and empty state (#5153)
* chore: view icon updated * chore: view asset updated * chore: project view empty state updated
@@ -4,11 +4,11 @@ import { useCallback } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Earth, Lock } from "lucide-react";
|
||||
import { Earth, Layers, Lock } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon, Tooltip } from "@plane/ui";
|
||||
import { Breadcrumbs, Button, CustomMenu, Tooltip } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink, Logo } from "@/components/common";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues";
|
||||
@@ -159,7 +159,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
<BreadcrumbLink
|
||||
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/views`}
|
||||
label="Views"
|
||||
icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />}
|
||||
icon={<Layers className="h-4 w-4 text-custom-text-300" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -172,7 +172,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
{viewDetails?.logo_props?.in_use ? (
|
||||
<Logo logo={viewDetails.logo_props} size={12} type="lucide" />
|
||||
) : (
|
||||
<PhotoFilterIcon height={12} width={12} />
|
||||
<Layers height={12} width={12} />
|
||||
)}
|
||||
{viewDetails?.name && truncateText(viewDetails.name, 40)}
|
||||
</>
|
||||
@@ -194,7 +194,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
{view?.logo_props?.in_use ? (
|
||||
<Logo logo={view.logo_props} size={12} type="lucide" />
|
||||
) : (
|
||||
<PhotoFilterIcon height={12} width={12} />
|
||||
<Layers height={12} width={12} />
|
||||
)}
|
||||
{truncateText(view.name, 40)}
|
||||
</Link>
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
import { useCallback } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Layers } from "lucide-react";
|
||||
// ui
|
||||
import { TViewFilterProps } from "@plane/types";
|
||||
import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui";
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink, Logo } from "@/components/common";
|
||||
import { ViewListHeader } from "@/components/views";
|
||||
@@ -75,9 +76,7 @@ export const ProjectViewsHeader = observer(() => {
|
||||
/>
|
||||
<Breadcrumbs.BreadcrumbItem
|
||||
type="text"
|
||||
link={
|
||||
<BreadcrumbLink label="Views" icon={<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />} />
|
||||
}
|
||||
link={<BreadcrumbLink label="Views" icon={<Layers className="h-4 w-4 text-custom-text-300" />} />}
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ReactNode } from "react";
|
||||
import { FileText, Timer } from "lucide-react";
|
||||
import { ContrastIcon, DiceIcon, PhotoFilterIcon, Intake } from "@plane/ui";
|
||||
import { FileText, Layers, Timer } from "lucide-react";
|
||||
import { ContrastIcon, DiceIcon, Intake } from "@plane/ui";
|
||||
|
||||
export type TFeatureList = {
|
||||
[key: string]: {
|
||||
@@ -44,7 +44,7 @@ export const PROJECT_FEATURES_LIST: TProjectFeatures = {
|
||||
property: "issue_views_view",
|
||||
title: "Views",
|
||||
description: "Apply filters to issues and save them to analyse and investigate work.",
|
||||
icon: <PhotoFilterIcon className="h-5 w-5 flex-shrink-0 text-custom-text-300" />,
|
||||
icon: <Layers className="h-5 w-5 flex-shrink-0 text-custom-text-300" />,
|
||||
isPro: false,
|
||||
isEnabled: true,
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Command } from "cmdk";
|
||||
import { ContrastIcon, FileText } from "lucide-react";
|
||||
import { ContrastIcon, FileText, Layers } from "lucide-react";
|
||||
// hooks
|
||||
import { DiceIcon, PhotoFilterIcon } from "@plane/ui";
|
||||
import { DiceIcon } from "@plane/ui";
|
||||
import { useCommandPalette, useEventTracker } from "@/hooks/store";
|
||||
// ui
|
||||
|
||||
@@ -62,7 +62,7 @@ export const CommandPaletteProjectActions: React.FC<Props> = (props) => {
|
||||
className="focus:outline-none"
|
||||
>
|
||||
<div className="flex items-center gap-2 text-custom-text-200">
|
||||
<PhotoFilterIcon className="h-3.5 w-3.5" />
|
||||
<Layers className="h-3.5 w-3.5" />
|
||||
Create new view
|
||||
</div>
|
||||
<kbd>V</kbd>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
// types
|
||||
import { Briefcase, FileText, LayoutGrid } from "lucide-react";
|
||||
import { Briefcase, FileText, Layers, LayoutGrid } from "lucide-react";
|
||||
import {
|
||||
IWorkspaceDefaultSearchResult,
|
||||
IWorkspaceIssueSearchResult,
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
IWorkspaceProjectSearchResult,
|
||||
IWorkspaceSearchResult,
|
||||
} from "@plane/types";
|
||||
import { ContrastIcon, DiceIcon, LayersIcon, PhotoFilterIcon } from "@plane/ui";
|
||||
import { ContrastIcon, DiceIcon, LayersIcon } from "@plane/ui";
|
||||
|
||||
export const commandGroups: {
|
||||
[key: string]: {
|
||||
@@ -45,7 +45,7 @@ export const commandGroups: {
|
||||
title: "Issues",
|
||||
},
|
||||
issue_view: {
|
||||
icon: <PhotoFilterIcon className="h-3 w-3" />,
|
||||
icon: <Layers className="h-3 w-3" />,
|
||||
itemName: (view: IWorkspaceDefaultSearchResult) => (
|
||||
<h6>
|
||||
<span className="text-xs text-custom-text-300">{view.project__identifier}</span> {view.name}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
// icons
|
||||
import { FileText } from "lucide-react";
|
||||
import { ContrastIcon, DiceIcon, LayersIcon, PhotoFilterIcon } from "@plane/ui";
|
||||
import { FileText, Layers } from "lucide-react";
|
||||
import { ContrastIcon, DiceIcon, LayersIcon } from "@plane/ui";
|
||||
// types
|
||||
import { TTourSteps } from "./root";
|
||||
|
||||
@@ -24,7 +24,7 @@ const sidebarOptions: {
|
||||
},
|
||||
{
|
||||
key: "views",
|
||||
Icon: PhotoFilterIcon,
|
||||
Icon: Layers,
|
||||
},
|
||||
{
|
||||
key: "pages",
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { Layers } from "lucide-react";
|
||||
// types
|
||||
import { IProjectView, IIssueFilterOptions } from "@plane/types";
|
||||
// ui
|
||||
import { Button, EmojiIconPicker, EmojiIconPickerTypes, Input, PhotoFilterIcon, TextArea } from "@plane/ui";
|
||||
import { Button, EmojiIconPicker, EmojiIconPickerTypes, Input, TextArea } from "@plane/ui";
|
||||
// components
|
||||
import { Logo } from "@/components/common";
|
||||
import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "@/components/issues";
|
||||
@@ -144,7 +145,7 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
||||
{logoValue?.in_use ? (
|
||||
<Logo logo={logoValue} size={18} type="lucide" />
|
||||
) : (
|
||||
<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />
|
||||
<Layers className="h-4 w-4 text-custom-text-300" />
|
||||
)}
|
||||
</>
|
||||
</span>
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
import { FC, useRef } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Layers } from "lucide-react";
|
||||
// types
|
||||
import { IProjectView } from "@plane/types";
|
||||
// ui
|
||||
import { PhotoFilterIcon } from "@plane/ui";
|
||||
// components
|
||||
import { Logo } from "@/components/common";
|
||||
import { ListItem } from "@/components/core/list";
|
||||
@@ -34,7 +33,7 @@ export const ProjectViewListItem: FC<Props> = observer((props) => {
|
||||
{view?.logo_props?.in_use ? (
|
||||
<Logo logo={view?.logo_props} size={16} type="lucide" />
|
||||
) : (
|
||||
<PhotoFilterIcon className="h-4 w-4 text-custom-text-300" />
|
||||
<Layers className="h-4 w-4 text-custom-text-300" />
|
||||
)}
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { observer } from "mobx-react";
|
||||
import Image from "next/image";
|
||||
import { useParams } from "next/navigation";
|
||||
// components
|
||||
import { ListLayout } from "@/components/core/list";
|
||||
@@ -11,14 +10,12 @@ import { EmptyStateType } from "@/constants/empty-state";
|
||||
// hooks
|
||||
import { useCommandPalette, useProjectView } from "@/hooks/store";
|
||||
// assets
|
||||
import AllFiltersImage from "@/public/empty-state/pages/all-filters.svg";
|
||||
import NameFilterImage from "@/public/empty-state/pages/name-filter.svg";
|
||||
|
||||
export const ProjectViewsList = observer(() => {
|
||||
const { projectId } = useParams();
|
||||
// store hooks
|
||||
const { toggleCreateViewModal } = useCommandPalette();
|
||||
const { getProjectViews, getFilteredProjectViews, filters, loader } = useProjectView();
|
||||
const { getProjectViews, getFilteredProjectViews, loader } = useProjectView();
|
||||
|
||||
const projectViews = getProjectViews(projectId?.toString());
|
||||
const filteredProjectViews = getFilteredProjectViews(projectId?.toString());
|
||||
@@ -27,20 +24,8 @@ export const ProjectViewsList = observer(() => {
|
||||
|
||||
if (filteredProjectViews.length === 0 && projectViews.length > 0) {
|
||||
return (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<div className="text-center">
|
||||
<Image
|
||||
src={filters.searchQuery.length > 0 ? NameFilterImage : AllFiltersImage}
|
||||
className="h-36 sm:h-48 w-36 sm:w-48 mx-auto"
|
||||
alt="No matching modules"
|
||||
/>
|
||||
<h5 className="text-xl font-medium mt-7 mb-1">No matching views</h5>
|
||||
<p className="text-custom-text-400 text-base">
|
||||
{filters.searchQuery.length > 0
|
||||
? "Remove the search criteria to see all views"
|
||||
: "Remove the filters to see all views"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-center h-full w-full">
|
||||
<EmptyState type={EmptyStateType.VIEWS_EMPTY_SEARCH} layout="screen-simple" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
LogOut,
|
||||
MoreHorizontal,
|
||||
ChevronRight,
|
||||
Layers,
|
||||
} from "lucide-react";
|
||||
import { Disclosure, Transition } from "@headlessui/react";
|
||||
// ui
|
||||
@@ -27,7 +28,6 @@ import {
|
||||
CustomMenu,
|
||||
Tooltip,
|
||||
ArchiveIcon,
|
||||
PhotoFilterIcon,
|
||||
DiceIcon,
|
||||
ContrastIcon,
|
||||
LayersIcon,
|
||||
@@ -84,7 +84,7 @@ const navigation = (workspaceSlug: string, projectId: string) => [
|
||||
{
|
||||
name: "Views",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/views`,
|
||||
Icon: PhotoFilterIcon,
|
||||
Icon: Layers,
|
||||
},
|
||||
{
|
||||
name: "Pages",
|
||||
|
||||
@@ -423,8 +423,8 @@ const emptyStateDetails = {
|
||||
[EmptyStateType.VIEWS_EMPTY_SEARCH]: {
|
||||
key: EmptyStateType.VIEWS_EMPTY_SEARCH,
|
||||
title: "No matching views",
|
||||
description: "No views match the search criteria. Create a new view instead.",
|
||||
path: "/empty-state/search/search",
|
||||
description: "No views match the search criteria. \n Create a new view instead.",
|
||||
path: "/empty-state/search/views",
|
||||
},
|
||||
[EmptyStateType.PROJECTS_EMPTY_SEARCH]: {
|
||||
key: EmptyStateType.PROJECTS_EMPTY_SEARCH,
|
||||
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
BIN
web/public/empty-state/search/views-dark.webp
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
web/public/empty-state/search/views-light.webp
Normal file
|
After Width: | Height: | Size: 71 KiB |