fix: order by last updated, cycles empty state alignment (#1151)

* fix: order by last updated

* fix: cycles empty space alignment, chore: new meta tags

* chore: update meta tags
This commit is contained in:
Aaryan Khandelwal 2023-05-29 15:38:35 +05:30 committed by GitHub
parent 022960d7e3
commit 26ba4d71c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 119 additions and 297 deletions

View File

@ -21,12 +21,7 @@ export const NotAuthorizedView: React.FC<Props> = ({ actionButton, type }) => {
const { asPath: currentPath } = useRouter();
return (
<DefaultLayout
meta={{
title: "Plane - Not Authorized",
description: "You are not authorized to view this page",
}}
>
<DefaultLayout>
<div className="flex h-full w-full flex-col items-center justify-center gap-y-5 bg-brand-surface-1 text-center">
<div className="h-44 w-72">
<Image

View File

@ -1,28 +1,19 @@
import Link from "next/link";
import { useRouter } from "next/router";
// layouts
import DefaultLayout from "layouts/default-layout";
// ui
import { PrimaryButton, SecondaryButton } from "components/ui";
export const NotAWorkspaceMember = () => {
const router = useRouter();
return (
<DefaultLayout
meta={{
title: "Plane - Unauthorized User",
description: "Unauthorized user",
}}
>
export const NotAWorkspaceMember = () => (
<DefaultLayout>
<div className="grid h-full place-items-center p-4">
<div className="space-y-8 text-center">
<div className="space-y-2">
<h3 className="text-lg font-semibold">Not Authorized!</h3>
<p className="mx-auto w-1/2 text-sm text-brand-secondary">
You{"'"}re not a member of this workspace. Please contact the workspace admin to get
an invitation or check your pending invitations.
You{"'"}re not a member of this workspace. Please contact the workspace admin to get an
invitation or check your pending invitations.
</p>
</div>
<div className="flex items-center justify-center gap-2">
@ -40,5 +31,4 @@ export const NotAWorkspaceMember = () => {
</div>
</div>
</DefaultLayout>
);
};
);

View File

@ -165,14 +165,9 @@ export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
});
};
const completedSubIssues =
subIssuesResponse && subIssuesResponse.state_distribution
? (subIssuesResponse?.state_distribution.completed
? subIssuesResponse?.state_distribution.completed
: 0) +
(subIssuesResponse?.state_distribution.cancelled
? subIssuesResponse?.state_distribution.cancelled
: 0)
const completedSubIssues = subIssuesResponse
? subIssuesResponse?.state_distribution.completed +
subIssuesResponse?.state_distribution.cancelled
: 0;
const totalSubIssues =
@ -278,7 +273,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
key={issue.id}
href={`/${workspaceSlug}/projects/${projectId}/issues/${issue.id}`}
>
<a className="group flex items-center justify-between gap-2 rounded p-2 hover:bg-brand-surface-1">
<a className="group flex items-center justify-between gap-2 rounded p-2 hover:bg-brand-base">
<div className="flex items-center gap-2 rounded text-xs">
<span
className="block h-1.5 w-1.5 flex-shrink-0 rounded-full"

View File

@ -15,7 +15,7 @@ export const ORDER_BY_OPTIONS: Array<{
}> = [
{ name: "Manual", key: "sort_order" },
{ name: "Last created", key: "-created_at" },
{ name: "Last updated", key: "updated_at" },
{ name: "Last updated", key: "-updated_at" },
{ name: "Priority", key: "priority" },
];

View File

@ -1,8 +1,8 @@
export const SITE_NAME = "Plane";
export const SITE_TITLE = "Plane | Accelerate software development with peace.";
export const SITE_NAME = "Plane | Simple, extensible, open-source project management tool.";
export const SITE_TITLE = "Plane | Simple, extensible, open-source project management tool.";
export const SITE_DESCRIPTION =
"Plane accelerated the software development by order of magnitude for agencies and product companies.";
"Open-source project management tool to manage issues, sprints, and product roadmaps with peace of mind.";
export const SITE_KEYWORDS =
"software development, plan, ship, software, accelerate, code management, release management";
export const SITE_URL = "http://localhost:3000/";
export const TWITTER_USER_NAME = "caravel";
"software development, plan, ship, software, accelerate, code management, release management, project management, issue tracking, agile, scrum, kanban, collaboration";
export const SITE_URL = "https://app.plane.so/";
export const TWITTER_USER_NAME = "Plane | Simple, extensible, open-source project management tool.";

View File

@ -5,10 +5,7 @@ import { useRouter } from "next/router";
// contexts
import { useProjectMyMembership, ProjectMemberProvider } from "contexts/project-member.context";
// hooks
import useIssuesView from "hooks/use-issues-view";
// layouts
import Container from "layouts/container";
import AppHeader from "layouts/app-layout/app-header";
import AppSidebar from "layouts/app-layout/app-sidebar";
// components
@ -19,15 +16,7 @@ import { PrimaryButton, Spinner } from "components/ui";
// icons
import { LayerDiagonalIcon } from "components/icons";
type Meta = {
title?: string | null;
description?: string | null;
image?: string | null;
url?: string | null;
};
type Props = {
meta?: Meta;
children: React.ReactNode;
noHeader?: boolean;
bg?: "primary" | "secondary";
@ -43,7 +32,6 @@ export const ProjectAuthorizationWrapper: React.FC<Props> = (props) => (
);
const ProjectAuthorizationWrapped: React.FC<Props> = ({
meta,
children,
noHeader = false,
bg = "primary",
@ -61,7 +49,7 @@ const ProjectAuthorizationWrapped: React.FC<Props> = ({
const settingsLayout = router.pathname.includes("/settings");
return (
<Container meta={meta}>
<>
<CommandPalette />
<div className="relative flex h-screen w-full overflow-hidden">
<AppSidebar toggleSidebar={toggleSidebar} setToggleSidebar={setToggleSidebar} />
@ -126,6 +114,6 @@ const ProjectAuthorizationWrapped: React.FC<Props> = ({
</main>
)}
</div>
</Container>
</>
);
};

View File

@ -8,7 +8,6 @@ import useSWR from "swr";
// services
import workspaceServices from "services/workspace.service";
// layouts
import Container from "layouts/container";
import AppSidebar from "layouts/app-layout/app-sidebar";
import AppHeader from "layouts/app-layout/app-header";
import { UserAuthorizationLayout } from "./user-authorization-wrapper";
@ -21,15 +20,7 @@ import { LayerDiagonalIcon } from "components/icons";
// fetch-keys
import { WORKSPACE_MEMBERS_ME } from "constants/fetch-keys";
type Meta = {
title?: string | null;
description?: string | null;
image?: string | null;
url?: string | null;
};
type Props = {
meta?: Meta;
children: React.ReactNode;
noHeader?: boolean;
bg?: "primary" | "secondary";
@ -39,7 +30,6 @@ type Props = {
};
export const WorkspaceAuthorizationLayout: React.FC<Props> = ({
meta,
children,
noHeader = false,
bg = "primary",
@ -88,7 +78,6 @@ export const WorkspaceAuthorizationLayout: React.FC<Props> = ({
return (
<UserAuthorizationLayout>
<Container meta={meta}>
<CommandPalette />
<div className="relative flex h-screen w-full overflow-hidden">
<AppSidebar toggleSidebar={toggleSidebar} setToggleSidebar={setToggleSidebar} />
@ -131,7 +120,6 @@ export const WorkspaceAuthorizationLayout: React.FC<Props> = ({
</main>
)}
</div>
</Container>
</UserAuthorizationLayout>
);
};

View File

@ -1,69 +0,0 @@
import React from "react";
// next
import Head from "next/head";
import { useRouter } from "next/router";
// constants
import {
SITE_NAME,
SITE_DESCRIPTION,
SITE_URL,
TWITTER_USER_NAME,
SITE_KEYWORDS,
SITE_TITLE,
} from "constants/seo-variables";
type Meta = {
title?: string | null;
description?: string | null;
image?: string | null;
url?: string | null;
};
type Props = {
meta?: Meta;
children: React.ReactNode;
noPadding?: boolean;
bg?: "primary" | "secondary";
noHeader?: boolean;
breadcrumbs?: JSX.Element;
left?: JSX.Element;
right?: JSX.Element;
};
const Container = ({ meta, children }: Props) => {
const router = useRouter();
const image = meta?.image || "/site-image.png";
const title = meta?.title || SITE_TITLE;
const url = meta?.url || `${SITE_URL}${router.asPath}`;
const description = meta?.description || SITE_DESCRIPTION;
return (
<>
<Head>
<title>{title}</title>
<meta property="og:site_name" content={SITE_NAME} />
<meta property="og:title" content={title} />
<meta property="og:url" content={url} />
<meta name="description" content={description} />
<meta property="og:description" content={description} />
<meta name="keywords" content={SITE_KEYWORDS} />
<meta name="twitter:site" content={`@${TWITTER_USER_NAME}`} />
<meta name="twitter:card" content={image ? "summary_large_image" : "summary"} />
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest.json" />
<link rel="shortcut icon" href="/favicon/favicon.ico" />
{image && (
<meta
property="og:image"
content={image.startsWith("https://") ? image : `${SITE_URL}${image}`}
/>
)}
</Head>
{children}
</>
);
};
export default Container;

View File

@ -1,15 +1,4 @@
// layouts
import Container from "layouts/container";
type Meta = {
title?: string | null;
description?: string | null;
image?: string | null;
url?: string | null;
};
type Props = {
meta?: Meta;
children: React.ReactNode;
noPadding?: boolean;
bg?: "primary" | "secondary";
@ -19,12 +8,10 @@ type Props = {
right?: JSX.Element;
};
const DefaultLayout: React.FC<Props> = ({ meta, children }) => (
<Container meta={meta}>
const DefaultLayout: React.FC<Props> = ({ children }) => (
<div className="h-screen w-full overflow-auto bg-brand-surface-1">
<>{children}</>
</div>
</Container>
);
export default DefaultLayout;

View File

@ -13,12 +13,7 @@ import Image404 from "public/404.svg";
import type { NextPage } from "next";
const PageNotFound: NextPage = () => (
<DefaultLayout
meta={{
title: "Plane - Page Not Found",
description: "Page Not Found",
}}
>
<DefaultLayout>
<div className="grid h-full place-items-center p-4">
<div className="space-y-8 text-center">
<div className="relative mx-auto h-60 w-60 lg:h-80 lg:w-80">

View File

@ -18,9 +18,6 @@ const ProfileActivity = () => {
return (
<WorkspaceAuthorizationLayout
meta={{
title: "Plane - My Profile",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="My Profile Activity" />

View File

@ -123,9 +123,6 @@ const Profile: NextPage = () => {
return (
<WorkspaceAuthorizationLayout
meta={{
title: "Plane - My Profile",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="My Profile" />

View File

@ -29,9 +29,6 @@ const ProfilePreferences = () => {
return (
<WorkspaceAuthorizationLayout
meta={{
title: "Plane - My Profile",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="My Profile Preferences" />

View File

@ -89,9 +89,6 @@ const ProjectCycles: NextPage = () => {
return (
<ProjectAuthorizationWrapper
meta={{
title: "Plane - Cycles",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -66,9 +66,6 @@ const ProjectModules: NextPage = () => {
return (
<ProjectAuthorizationWrapper
meta={{
title: "Plane - Modules",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -290,9 +290,6 @@ const SinglePage: NextPage = () => {
return (
<ProjectAuthorizationWrapper
meta={{
title: "Plane - Pages",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -100,9 +100,6 @@ const ProjectPages: NextPage = () => {
handleClose={() => setCreateUpdatePageModal(false)}
/>
<ProjectAuthorizationWrapper
meta={{
title: "Plane - Pages",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -60,9 +60,6 @@ const ProjectViews: NextPage = () => {
return (
<ProjectAuthorizationWrapper
meta={{
title: "Plane - Views",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />

View File

@ -146,9 +146,6 @@ const WorkspaceSettings: NextPage = () => {
return (
<WorkspaceAuthorizationLayout
meta={{
title: "Plane - Workspace Settings",
}}
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title={`${activeWorkspace?.name ?? "Workspace"} Settings`} />

View File

@ -10,8 +10,8 @@ import "styles/command-pallette.css";
import "styles/nprogress.css";
import "styles/react-datepicker.css";
// router
import Router from "next/router";
import Head from "next/head";
// nprogress
import NProgress from "nprogress";
@ -24,6 +24,15 @@ import { ThemeContextProvider } from "contexts/theme.context";
import type { AppProps } from "next/app";
// constants
import { THEMES } from "constants/themes";
// constants
import {
SITE_NAME,
SITE_DESCRIPTION,
SITE_URL,
TWITTER_USER_NAME,
SITE_KEYWORDS,
SITE_TITLE,
} from "constants/seo-variables";
const CrispWithNoSSR = dynamic(() => import("constants/crisp"), { ssr: false });
@ -39,7 +48,22 @@ function MyApp({ Component, pageProps }: AppProps) {
<UserProvider>
<ToastContextProvider>
<ThemeContextProvider>
<CrispWithNoSSR />
<CrispWithNoSSR />{" "}
<Head>
<title>{SITE_TITLE}</title>
<meta property="og:site_name" content={SITE_NAME} />
<meta property="og:title" content={SITE_TITLE} />
<meta property="og:url" content={SITE_URL} />
<meta name="description" content={SITE_DESCRIPTION} />
<meta property="og:description" content={SITE_DESCRIPTION} />
<meta name="keywords" content={SITE_KEYWORDS} />
<meta name="twitter:site" content={`@${TWITTER_USER_NAME}`} />
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest.json" />
<link rel="shortcut icon" href="/favicon/favicon.ico" />
</Head>
<Component {...pageProps} />
</ThemeContextProvider>
</ToastContextProvider>

View File

@ -1,21 +1,3 @@
/**
* NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher.
*
* NOTE: If using this with `next` version 12.2.0 or lower, uncomment the
* penultimate line in `CustomErrorComponent`.
*
* This page is loaded by Nextjs:
* - on the server, when data-fetching methods throw or reject
* - on the client, when `getInitialProps` throws or rejects
* - on the client, when a React lifecycle method throws or rejects, and it's
* caught by the built-in Nextjs error boundary
*
* See:
* - https://nextjs.org/docs/basic-features/data-fetching/overview
* - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
* - https://reactjs.org/docs/error-boundaries.html
*/
import * as Sentry from "@sentry/nextjs";
import { useRouter } from "next/router";
@ -48,12 +30,7 @@ const CustomErrorComponent = () => {
};
return (
<DefaultLayout
meta={{
title: "Plane - Exception Detected",
description: "Exception Detected",
}}
>
<DefaultLayout>
<div className="grid h-full place-items-center p-4">
<div className="space-y-8 text-center">
<div className="space-y-2">
@ -91,9 +68,7 @@ const CustomErrorComponent = () => {
);
};
CustomErrorComponent.getInitialProps = async (contextData) => {
// In case this is running in a serverless function, await this in order to give Sentry
// time to send the error before the lambda exits
CustomErrorComponent.getInitialProps = async (contextData: any) => {
await Sentry.captureUnderscoreErrorException(contextData);
const { res, err } = contextData;

View File

@ -6,12 +6,7 @@ import DefaultLayout from "layouts/default-layout";
import type { NextPage } from "next";
const ErrorPage: NextPage = () => (
<DefaultLayout
meta={{
title: "Plane - An error occurred",
description: "We were unable to get this page for you.",
}}
>
<DefaultLayout>
<div className="h-full w-full">
<h2 className="text-3xl">Error!</h2>
</div>

View File

@ -80,13 +80,7 @@ const OnBoard: NextPage = () => {
return (
<UserAuthorizationLayout>
<DefaultLayout
meta={{
title: "Plane - Welcome to Plane",
description:
"Please fasten your seatbelts because we are about to take your productivity to the next level.",
}}
>
<DefaultLayout>
<div className="flex min-h-full flex-col items-center justify-center p-4 sm:p-0">
{user && (
<div className="mb-10 w-96 rounded-lg bg-brand-accent/20 p-2 text-brand-accent">

View File

@ -48,11 +48,7 @@ const MagicSignIn: NextPage = () => {
}, [password, key, mutateUser, router]);
return (
<DefaultLayout
meta={{
title: "Magic Sign In",
}}
>
<DefaultLayout>
<div className="flex h-screen w-full items-center justify-center overflow-auto bg-gray-50">
{isSigningIn ? (
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">

View File

@ -90,11 +90,7 @@ const SignInPage: NextPage = () => {
);
return (
<DefaultLayout
meta={{
title: "Plane - Sign In",
}}
>
<DefaultLayout>
{isLoading ? (
<div className="absolute top-0 left-0 z-50 flex h-full w-full flex-col items-center justify-center gap-y-3">
<h2 className="text-xl text-brand-base">Signing in. Please wait...</h2>

View File

@ -267,7 +267,7 @@ export type TIssueViewOptions = "list" | "kanban" | "calendar" | "gantt_chart";
export type TIssueGroupByOptions = "state" | "priority" | "labels" | "created_by" | null;
export type TIssueOrderByOptions = "-created_at" | "updated_at" | "priority" | "sort_order";
export type TIssueOrderByOptions = "-created_at" | "-updated_at" | "priority" | "sort_order";
export interface IIssueViewOptions {
group_by: TIssueGroupByOptions;