mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
Compare commits
4 Commits
refactor/e
...
fix/remove
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5319bc5072 | ||
|
|
11f487f2a4 | ||
|
|
50c7757075 | ||
|
|
be0bd8c541 |
@@ -60,6 +60,7 @@ from plane.db.models import (
|
||||
IssueVote,
|
||||
ProjectPublicMember,
|
||||
IssueAttachment,
|
||||
Project,
|
||||
)
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.utils.issue_filters import issue_filters
|
||||
@@ -77,6 +78,15 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
|
||||
deploy_board = DeployBoard.objects.filter(
|
||||
anchor=anchor, entity_name="project"
|
||||
).first()
|
||||
|
||||
project = Project.objects.get(pk=deploy_board.project_id)
|
||||
|
||||
if project.archived_at:
|
||||
return Response(
|
||||
{"error": "Project is archived"},
|
||||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
|
||||
if not deploy_board:
|
||||
return Response(
|
||||
{"error": "Project is not published"},
|
||||
|
||||
50
space/core/components/common/empty-state.tsx
Normal file
50
space/core/components/common/empty-state.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
|
||||
import Image from "next/image";
|
||||
|
||||
// ui
|
||||
import { Button } from "@plane/ui";
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
description?: React.ReactNode;
|
||||
image: any;
|
||||
primaryButton?: {
|
||||
icon?: any;
|
||||
text: string;
|
||||
onClick: () => void;
|
||||
};
|
||||
secondaryButton?: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const EmptyState: React.FC<Props> = ({
|
||||
title,
|
||||
description,
|
||||
image,
|
||||
primaryButton,
|
||||
secondaryButton,
|
||||
disabled = false,
|
||||
}) => (
|
||||
<div className={`flex h-full w-full items-center justify-center`}>
|
||||
<div className="flex w-full flex-col items-center text-center">
|
||||
<Image src={image} className="w-52 sm:w-60" alt={primaryButton?.text || "button image"} />
|
||||
<h6 className="mb-3 mt-6 text-xl font-semibold sm:mt-8">{title}</h6>
|
||||
{description && <p className="mb-7 px-5 text-custom-text-300 sm:mb-8">{description}</p>}
|
||||
<div className="flex items-center gap-4">
|
||||
{primaryButton && (
|
||||
<Button
|
||||
variant="primary"
|
||||
prependIcon={primaryButton.icon}
|
||||
onClick={primaryButton.onClick}
|
||||
disabled={disabled}
|
||||
>
|
||||
{primaryButton.text}
|
||||
</Button>
|
||||
)}
|
||||
{secondaryButton}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -1,6 +1,11 @@
|
||||
import { observer } from "mobx-react";
|
||||
// import { useTheme } from "next-themes";
|
||||
import { useTheme } from "next-themes";
|
||||
import { TLoader } from "@plane/types";
|
||||
import { LogoSpinner } from "@/components/common";
|
||||
import { EmptyState } from "@/components/common/empty-state";
|
||||
import emptyIssueDark from "@/public/empty-state/search/issues-dark.webp"
|
||||
import emptyIssueLight from "@/public/empty-state/search/issues-light.webp"
|
||||
|
||||
interface Props {
|
||||
children: string | JSX.Element | JSX.Element[];
|
||||
@@ -13,6 +18,9 @@ interface Props {
|
||||
}
|
||||
|
||||
export const IssueLayoutHOC = observer((props: Props) => {
|
||||
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
const { getIssueLoader, getGroupIssueCount } = props;
|
||||
|
||||
const issueCount = getGroupIssueCount(undefined, undefined, false);
|
||||
@@ -25,8 +33,15 @@ export const IssueLayoutHOC = observer((props: Props) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (getGroupIssueCount(undefined, undefined, false) === 0) {
|
||||
return <div className="flex w-full h-full items-center justify-center">No Issues Found</div>;
|
||||
if (issueCount === 0) {
|
||||
return <div className="flex w-full h-full items-center justify-center">
|
||||
{/* No Issues Found */}
|
||||
<EmptyState
|
||||
image={resolvedTheme === "dark" ? emptyIssueDark : emptyIssueLight}
|
||||
title="Project does not exist"
|
||||
description="The project you are looking for has no issues or has been archived."
|
||||
/>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <>{props.children}</>;
|
||||
|
||||
BIN
space/public/empty-state/search/issues-dark.webp
Normal file
BIN
space/public/empty-state/search/issues-dark.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
space/public/empty-state/search/issues-light.webp
Normal file
BIN
space/public/empty-state/search/issues-light.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -9,6 +9,7 @@ import { TActivityFilters, ACTIVITY_FILTER_TYPE_OPTIONS, TActivityFilterOption }
|
||||
export type TActivityFilterRoot = {
|
||||
selectedFilters: TActivityFilters[];
|
||||
toggleFilter: (filter: TActivityFilters) => void;
|
||||
isIntakeIssue?: boolean;
|
||||
};
|
||||
|
||||
export const ActivityFilterRoot: FC<TActivityFilterRoot> = (props) => {
|
||||
|
||||
@@ -123,7 +123,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
||||
disabled={disabled}
|
||||
/>
|
||||
)}
|
||||
<ActivityFilterRoot selectedFilters={selectedFilters} toggleFilter={toggleFilter} />
|
||||
<ActivityFilterRoot selectedFilters={selectedFilters} toggleFilter={toggleFilter} isIntakeIssue={isIntakeIssue}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user