UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: каркас вкладки внешние контуры
This commit is contained in:
parent
a59f09e2f0
commit
c76f519488
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { Outlet } from "react-router";
|
||||
import { AppHeader } from "@/components/core/app-header";
|
||||
import { ContentWrapper } from "@/components/core/content-wrapper";
|
||||
import { ProjectExternalContoursHeader } from "@/plane-web/components/projects/external-contours/header";
|
||||
|
||||
export default function ProjectExternalContoursLayout() {
|
||||
return (
|
||||
<>
|
||||
<AppHeader header={<ProjectExternalContoursHeader />} />
|
||||
<ContentWrapper>
|
||||
<Outlet />
|
||||
</ContentWrapper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TransferIcon } from "@plane/propel/icons";
|
||||
import { PageHead } from "@/components/core/page-title";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import type { Route } from "./+types/page";
|
||||
|
||||
function ProjectExternalContoursPage(_props: Route.ComponentProps) {
|
||||
const { t } = useTranslation();
|
||||
const { currentProjectDetails } = useProject();
|
||||
|
||||
const pageTitle = currentProjectDetails?.name
|
||||
? t("external_contours_page.page_label", { workspace: currentProjectDetails.name })
|
||||
: t("external_contours_page.page_label", { workspace: "NODE.DC" });
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<PageHead title={pageTitle} />
|
||||
<div className="mx-auto flex w-full max-w-5xl flex-col gap-6 px-5 py-6 md:px-8">
|
||||
<section className="rounded-xl border border-subtle bg-surface-1 p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex size-11 shrink-0 items-center justify-center rounded-lg bg-accent-primary/10 text-accent-primary">
|
||||
<TransferIcon className="h-5 w-5 fill-current" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-2xl font-semibold text-primary">{t("external_contours_page.empty_state.title")}</h1>
|
||||
<p className="max-w-3xl text-sm text-secondary">
|
||||
{t("external_contours_page.empty_state.description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="grid gap-4 lg:grid-cols-2">
|
||||
<div className="rounded-xl border border-dashed border-subtle bg-surface-1 p-6">
|
||||
<p className="mb-2 text-base font-semibold text-primary">
|
||||
{t("external_contours_page.empty_state.request_title")}
|
||||
</p>
|
||||
<p className="text-sm text-secondary">{t("external_contours_page.empty_state.request_description")}</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-dashed border-subtle bg-surface-1 p-6">
|
||||
<p className="mb-2 text-base font-semibold text-primary">
|
||||
{t("external_contours_page.empty_state.list_title")}
|
||||
</p>
|
||||
<p className="text-sm text-secondary">{t("external_contours_page.empty_state.list_description")}</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(ProjectExternalContoursPage);
|
||||
|
|
@ -216,6 +216,13 @@ export const coreRoutes: RouteConfigEntry[] = [
|
|||
"./(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/intake/page.tsx"
|
||||
),
|
||||
]),
|
||||
// External contours list
|
||||
layout("./(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/external-contours/layout.tsx", [
|
||||
route(
|
||||
":workspaceSlug/projects/:projectId/external-contours",
|
||||
"./(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/external-contours/page.tsx"
|
||||
),
|
||||
]),
|
||||
]),
|
||||
|
||||
// Project Archives - Issues, Cycles, Modules
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { useMemo, useCallback } from "react";
|
||||
// plane imports
|
||||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, TransferIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import type { EUserProjectRoles, IPartialProject } from "@plane/types";
|
||||
import type { TNavigationItem } from "@/components/navigation/tab-navigation-root";
|
||||
|
||||
|
|
@ -42,6 +42,16 @@ export const useNavigationItems = ({
|
|||
shouldRender: true,
|
||||
sortOrder: 1,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.external_contours",
|
||||
key: "external_contours",
|
||||
name: "External contours",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/external-contours`,
|
||||
icon: TransferIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: true,
|
||||
sortOrder: 2,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.cycles",
|
||||
key: "cycles",
|
||||
|
|
@ -50,7 +60,7 @@ export const useNavigationItems = ({
|
|||
icon: CycleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: !!project?.cycle_view,
|
||||
sortOrder: 2,
|
||||
sortOrder: 3,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.modules",
|
||||
|
|
@ -60,7 +70,7 @@ export const useNavigationItems = ({
|
|||
icon: ModuleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: !!project?.module_view,
|
||||
sortOrder: 3,
|
||||
sortOrder: 4,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.views",
|
||||
|
|
@ -70,7 +80,7 @@ export const useNavigationItems = ({
|
|||
icon: ViewsIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: !!project?.issue_views_view,
|
||||
sortOrder: 4,
|
||||
sortOrder: 5,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.pages",
|
||||
|
|
@ -80,7 +90,7 @@ export const useNavigationItems = ({
|
|||
icon: PageIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: !!project?.page_view,
|
||||
sortOrder: 5,
|
||||
sortOrder: 6,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.intake",
|
||||
|
|
@ -90,7 +100,7 @@ export const useNavigationItems = ({
|
|||
icon: IntakeIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: !!project?.inbox_view,
|
||||
sortOrder: 6,
|
||||
sortOrder: 7,
|
||||
},
|
||||
],
|
||||
[project]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TransferIcon } from "@plane/propel/icons";
|
||||
import { Breadcrumbs, Header } from "@plane/ui";
|
||||
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
|
||||
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs/common";
|
||||
|
||||
export const ProjectExternalContoursHeader = observer(function ProjectExternalContoursHeader() {
|
||||
const { workspaceSlug, projectId } = useParams();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Header>
|
||||
<Header.LeftItem>
|
||||
<Breadcrumbs>
|
||||
<CommonProjectBreadcrumbs workspaceSlug={workspaceSlug?.toString()} projectId={projectId?.toString()} />
|
||||
<Breadcrumbs.Item
|
||||
component={
|
||||
<BreadcrumbLink
|
||||
label={t("external_contours_page.title")}
|
||||
href={`/${workspaceSlug}/projects/${projectId}/external-contours/`}
|
||||
icon={<TransferIcon className="h-4 w-4 text-tertiary" />}
|
||||
isLast
|
||||
/>
|
||||
}
|
||||
isLast
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
</Header.LeftItem>
|
||||
</Header>
|
||||
);
|
||||
});
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// plane imports
|
||||
import { EUserPermissions, EProjectFeatureKey } from "@plane/constants";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, TransferIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
// components
|
||||
import type { TNavigationItem } from "@/components/workspace/sidebar/project-navigation";
|
||||
|
||||
|
|
@ -31,6 +31,16 @@ export const getProjectFeatureNavigation = (
|
|||
shouldRender: true,
|
||||
sortOrder: 1,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.external_contours",
|
||||
key: "external_contours",
|
||||
name: "External contours",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/external-contours`,
|
||||
icon: TransferIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: true,
|
||||
sortOrder: 2,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.cycles",
|
||||
key: EProjectFeatureKey.CYCLES,
|
||||
|
|
@ -39,7 +49,7 @@ export const getProjectFeatureNavigation = (
|
|||
icon: CycleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: project.cycle_view,
|
||||
sortOrder: 2,
|
||||
sortOrder: 3,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.modules",
|
||||
|
|
@ -49,7 +59,7 @@ export const getProjectFeatureNavigation = (
|
|||
icon: ModuleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: project.module_view,
|
||||
sortOrder: 3,
|
||||
sortOrder: 4,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.views",
|
||||
|
|
@ -59,7 +69,7 @@ export const getProjectFeatureNavigation = (
|
|||
icon: ViewsIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project.issue_views_view,
|
||||
sortOrder: 4,
|
||||
sortOrder: 5,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.pages",
|
||||
|
|
@ -69,7 +79,7 @@ export const getProjectFeatureNavigation = (
|
|||
icon: PageIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project.page_view,
|
||||
sortOrder: 5,
|
||||
sortOrder: 6,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.intake",
|
||||
|
|
@ -79,6 +89,6 @@ export const getProjectFeatureNavigation = (
|
|||
icon: IntakeIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project.inbox_view,
|
||||
sortOrder: 6,
|
||||
sortOrder: 7,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import Link from "next/link";
|
|||
import { useParams, usePathname } from "next/navigation";
|
||||
import { EUserPermissionsLevel, EUserPermissions } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import { CycleIcon, IntakeIcon, ModuleIcon, PageIcon, TransferIcon, ViewsIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import type { EUserProjectRoles } from "@plane/types";
|
||||
// plane ui
|
||||
// components
|
||||
|
|
@ -80,6 +80,16 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
shouldRender: true,
|
||||
sortOrder: 1,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.external_contours",
|
||||
key: "external_contours",
|
||||
name: "External contours",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/external-contours`,
|
||||
icon: TransferIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: true,
|
||||
sortOrder: 2,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.cycles",
|
||||
key: "cycles",
|
||||
|
|
@ -88,7 +98,7 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
icon: CycleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: project?.cycle_view ?? false,
|
||||
sortOrder: 2,
|
||||
sortOrder: 3,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.modules",
|
||||
|
|
@ -98,7 +108,7 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
icon: ModuleIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
shouldRender: project?.module_view ?? false,
|
||||
sortOrder: 3,
|
||||
sortOrder: 4,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.views",
|
||||
|
|
@ -108,7 +118,7 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
icon: ViewsIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project?.issue_views_view ?? false,
|
||||
sortOrder: 4,
|
||||
sortOrder: 5,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.pages",
|
||||
|
|
@ -118,7 +128,7 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
icon: PageIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project?.page_view ?? false,
|
||||
sortOrder: 5,
|
||||
sortOrder: 6,
|
||||
},
|
||||
{
|
||||
i18n_key: "sidebar.intake",
|
||||
|
|
@ -128,7 +138,7 @@ export const ProjectNavigation = observer(function ProjectNavigation(props: TPro
|
|||
icon: IntakeIcon,
|
||||
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
|
||||
shouldRender: project?.inbox_view ?? false,
|
||||
sortOrder: 6,
|
||||
sortOrder: 7,
|
||||
},
|
||||
],
|
||||
[project]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,27 @@
|
|||
*/
|
||||
|
||||
export default {
|
||||
sidebar: {
|
||||
projects: "Projects",
|
||||
pages: "Pages",
|
||||
new_work_item: "New work item",
|
||||
home: "Home",
|
||||
your_work: "Your work",
|
||||
inbox: "Inbox",
|
||||
workspace: "Workspace",
|
||||
views: "Views",
|
||||
analytics: "Analytics",
|
||||
work_items: "Work items",
|
||||
external_contours: "External contours",
|
||||
cycles: "Cycles",
|
||||
modules: "Modules",
|
||||
intake: "Intake",
|
||||
drafts: "Drafts",
|
||||
favorites: "Favorites",
|
||||
pro: "Pro",
|
||||
upgrade: "Upgrade",
|
||||
stickies: "Stickies",
|
||||
},
|
||||
submit: "Submit",
|
||||
cancel: "Cancel",
|
||||
loading: "Loading",
|
||||
|
|
@ -217,6 +238,7 @@ export default {
|
|||
modules: "Modules",
|
||||
pages: "Pages",
|
||||
intake: "Intake",
|
||||
external_contours: "External contours",
|
||||
time_tracking: "Time Tracking",
|
||||
work_management: "Work management",
|
||||
projects_and_issues: "Projects and work items",
|
||||
|
|
@ -258,6 +280,21 @@ export default {
|
|||
you_can_see_here_if_someone_invites_you_to_a_workspace: "You can see here if someone invites you to a workspace",
|
||||
back_to_home: "Back to home",
|
||||
workspace_name: "workspace-name",
|
||||
external_contours_page: {
|
||||
page_label: "{workspace} - External contours",
|
||||
title: "External contours",
|
||||
empty_state: {
|
||||
title: "External contours module is ready for the next stage",
|
||||
description:
|
||||
"This screen will host the cross-project request form, the sent requests list, and status pills for each routed task.",
|
||||
request_title: "Send to an external contour",
|
||||
request_description:
|
||||
"The next stage will add the form for selecting the target project, assignee, priority, due date, and description.",
|
||||
list_title: "Sent requests",
|
||||
list_description:
|
||||
"This area will show sent cross-project requests with their current status, a link to the target task, and later synchronization.",
|
||||
},
|
||||
},
|
||||
deactivate_your_account: "Deactivate your account",
|
||||
deactivate_your_account_description:
|
||||
"Once deactivated, you can't be assigned work items and be billed for your workspace. To reactivate your account, you will need an invite to a workspace at this email address.",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export default {
|
|||
views: "Представления",
|
||||
analytics: "Аналитика",
|
||||
work_items: "Внутренний контур",
|
||||
external_contours: "Внешние контуры",
|
||||
cycles: "Циклы",
|
||||
modules: "Модули",
|
||||
intake: "Предложения",
|
||||
|
|
@ -389,6 +390,7 @@ export default {
|
|||
modules: "Модули",
|
||||
pages: "Страницы",
|
||||
intake: "Предложения",
|
||||
external_contours: "Внешние контуры",
|
||||
time_tracking: "Учет времени",
|
||||
work_management: "Управление рабочими элементами",
|
||||
projects_and_issues: "Проекты и рабочие элементы",
|
||||
|
|
@ -434,6 +436,21 @@ export default {
|
|||
you_can_see_here_if_someone_invites_you_to_a_workspace: "Здесь отображаются приглашения в рабочие пространства",
|
||||
back_to_home: "Вернуться на главную",
|
||||
workspace_name: "название-рабочего-пространства",
|
||||
external_contours_page: {
|
||||
page_label: "{workspace} - Внешние контуры",
|
||||
title: "Внешние контуры",
|
||||
empty_state: {
|
||||
title: "Модуль внешних контуров подготовлен",
|
||||
description:
|
||||
"Здесь появятся форма отправки задачи в другой проект, список отправленных запросов и их статусные маркеры.",
|
||||
request_title: "Отправка во внешний контур",
|
||||
request_description:
|
||||
"На следующем этапе здесь будет форма выбора целевого проекта, исполнителя, приоритета, срока и описания.",
|
||||
list_title: "Отправленные запросы",
|
||||
list_description:
|
||||
"Здесь будет список межпроектных запросов с текущим статусом, ссылкой на целевую задачу и дальнейшей синхронизацией.",
|
||||
},
|
||||
},
|
||||
deactivate_your_account: "Деактивировать ваш аккаунт",
|
||||
deactivate_your_account_description:
|
||||
"После деактивации вы не сможете получать рабочие элементы и оплачивать рабочее пространство. Для реактивации потребуется новое приглашение.",
|
||||
|
|
|
|||
Loading…
Reference in New Issue