Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apiserver/plane/space/urls/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@
ProjectStatesEndpoint,
ProjectLabelsEndpoint,
ProjectMembersEndpoint,
ProjectMetaDataEndpoint,
)

urlpatterns = [
path(
"anchor/<str:anchor>/meta/",
ProjectMetaDataEndpoint.as_view(),
name="project-meta",
),
path(
"anchor/<str:anchor>/settings/",
ProjectDeployBoardPublicSettingsEndpoint.as_view(),
Expand Down
2 changes: 2 additions & 0 deletions apiserver/plane/space/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
from .label import ProjectLabelsEndpoint

from .asset import EntityAssetEndpoint, AssetRestoreEndpoint, EntityBulkAssetEndpoint

from .meta import ProjectMetaDataEndpoint
34 changes: 34 additions & 0 deletions apiserver/plane/space/views/meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# third party
from rest_framework.permissions import AllowAny
from rest_framework import status
from rest_framework.response import Response

from plane.db.models import DeployBoard, Project

from .base import BaseAPIView
from plane.space.serializer.project import ProjectLiteSerializer


class ProjectMetaDataEndpoint(BaseAPIView):
permission_classes = [AllowAny]

def get(self, request, anchor):
try:
deploy_board = DeployBoard.objects.filter(
anchor=anchor, entity_name="project"
).first()
except DeployBoard.DoesNotExist:
return Response(
{"error": "Project is not published"}, status=status.HTTP_404_NOT_FOUND
)

try:
project_id = deploy_board.entity_identifier
project = Project.objects.get(id=project_id)
except Project.DoesNotExist:
return Response(
{"error": "Project is not published"}, status=status.HTTP_404_NOT_FOUND
)

serializer = ProjectLiteSerializer(project)
return Response(serializer.data, status=status.HTTP_200_OK)
3 changes: 3 additions & 0 deletions packages/constants/src/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ export const SITES_URL = encodeURI(`${SPACE_BASE_URL}${SPACE_BASE_PATH}/`);
export const LIVE_BASE_URL = process.env.NEXT_PUBLIC_LIVE_BASE_URL || "";
export const LIVE_BASE_PATH = process.env.NEXT_PUBLIC_LIVE_BASE_PATH || "";
export const LIVE_URL = encodeURI(`${LIVE_BASE_URL}${LIVE_BASE_PATH}/`);
// plane website url
export const WEBSITE_URL =
process.env.NEXT_PUBLIC_WEBSITE_URL || "https://plane.so";
54 changes: 54 additions & 0 deletions space/app/issues/[anchor]/client-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import { observer } from "mobx-react";
import useSWR from "swr";
// components
import { LogoSpinner } from "@/components/common";
import { IssuesNavbarRoot } from "@/components/issues";
import { SomethingWentWrongError } from "@/components/issues/issue-layouts/error";
// hooks
import { useIssueFilter, usePublish, usePublishList } from "@/hooks/store";

type Props = {
children: React.ReactNode;
anchor: string;
};

export const IssuesClientLayout = observer((props: Props) => {
const { children, anchor } = props;
// store hooks
const { fetchPublishSettings } = usePublishList();
const publishSettings = usePublish(anchor);
const { updateLayoutOptions } = useIssueFilter();
// fetch publish settings
const { error } = useSWR(
anchor ? `PUBLISH_SETTINGS_${anchor}` : null,
anchor
? async () => {
const response = await fetchPublishSettings(anchor);
if (response.view_props) {
updateLayoutOptions({
list: !!response.view_props.list,
kanban: !!response.view_props.kanban,
calendar: !!response.view_props.calendar,
gantt: !!response.view_props.gantt,
spreadsheet: !!response.view_props.spreadsheet,
});
}
}
: null
);

if (!publishSettings && !error) return <LogoSpinner />;

if (error) return <SomethingWentWrongError />;

return (
<div className="relative flex h-screen min-h-[500px] w-screen flex-col overflow-hidden">
<div className="relative flex h-[60px] flex-shrink-0 select-none items-center border-b border-custom-border-300 bg-custom-sidebar-background-100">
<IssuesNavbarRoot publishSettings={publishSettings} />
</div>
<div className="relative h-full w-full overflow-hidden bg-custom-background-90">{children}</div>
</div>
);
});
82 changes: 18 additions & 64 deletions space/app/issues/[anchor]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
"use client";
"use server";

import { observer } from "mobx-react";
import Image from "next/image";
import useSWR from "swr";
// components
import { LogoSpinner } from "@/components/common";
import { IssuesNavbarRoot } from "@/components/issues";
import { SomethingWentWrongError } from "@/components/issues/issue-layouts/error";
// hooks
import { useIssueFilter, usePublish, usePublishList } from "@/hooks/store";
// assets
import planeLogo from "@/public/plane-logo.svg";
import { IssuesClientLayout } from "./client-layout";

type Props = {
children: React.ReactNode;
Expand All @@ -19,58 +9,22 @@ type Props = {
};
};

const IssuesLayout = observer((props: Props) => {
const { children, params } = props;
// params
export async function generateMetadata({ params }: Props) {
const { anchor } = params;
// store hooks
const { fetchPublishSettings } = usePublishList();
const publishSettings = usePublish(anchor);
const { updateLayoutOptions } = useIssueFilter();
// fetch publish settings
const { error } = useSWR(
anchor ? `PUBLISH_SETTINGS_${anchor}` : null,
anchor
? async () => {
const response = await fetchPublishSettings(anchor);
if (response.view_props) {
updateLayoutOptions({
list: !!response.view_props.list,
kanban: !!response.view_props.kanban,
calendar: !!response.view_props.calendar,
gantt: !!response.view_props.gantt,
spreadsheet: !!response.view_props.spreadsheet,
});
}
}
: null
);

if (!publishSettings && !error) return <LogoSpinner />;

if (error) return <SomethingWentWrongError />;
const DEFAULT_TITLE = "Plane";
const DEFAULT_DESCRIPTION = "Made with Plane, an AI-powered work management platform with publishing capabilities.";
try {
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/public/anchor/${anchor}/meta/`);
const data = await response.json();
return { title: data?.name || DEFAULT_TITLE, description: data?.description || DEFAULT_DESCRIPTION };
} catch {
return { title: DEFAULT_TITLE, description: DEFAULT_DESCRIPTION };
}
}

return (
<div className="relative flex h-screen min-h-[500px] w-screen flex-col overflow-hidden">
<div className="relative flex h-[60px] flex-shrink-0 select-none items-center border-b border-custom-border-300 bg-custom-sidebar-background-100">
<IssuesNavbarRoot publishSettings={publishSettings} />
</div>
<div className="relative h-full w-full overflow-hidden bg-custom-background-90">{children}</div>
<a
href="https://plane.so"
className="fixed bottom-2.5 right-5 !z-[999999] flex items-center gap-1 rounded border border-custom-border-200 bg-custom-background-100 px-2 py-1 shadow-custom-shadow-2xs"
target="_blank"
rel="noreferrer noopener"
>
<div className="relative grid h-6 w-6 place-items-center">
<Image src={planeLogo} alt="Plane logo" className="h-6 w-6" height="24" width="24" />
</div>
<div className="text-xs">
Powered by <span className="font-semibold">Plane Publish</span>
</div>
</a>
</div>
);
});
export default async function IssuesLayout(props: Props) {
const { children, params } = props;
const { anchor } = params;

export default IssuesLayout;
return <IssuesClientLayout anchor={anchor}>{children}</IssuesClientLayout>;
}
24 changes: 9 additions & 15 deletions space/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { Metadata } from "next";
// helpers
import { ASSET_PREFIX } from "@/helpers/common.helper";
// components
import { InstanceProvider } from "@/lib/instance-provider";
import { StoreProvider } from "@/lib/store-provider";
import { SPACE_BASE_PATH } from "@plane/constants";
// styles
import "@/styles/globals.css";
import { ToastProvider } from "@/lib/toast-provider";
// components
import { AppProvider } from "./provider";

export const metadata: Metadata = {
title: "Plane Publish | Make your Plane boards public with one-click",
Expand All @@ -27,18 +25,14 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en">
<head>
<link rel="apple-touch-icon" sizes="180x180" href={`${ASSET_PREFIX}/favicon/apple-touch-icon.png`} />
<link rel="icon" type="image/png" sizes="32x32" href={`${ASSET_PREFIX}/favicon/favicon-32x32.png`} />
<link rel="icon" type="image/png" sizes="16x16" href={`${ASSET_PREFIX}/favicon/favicon-16x16.png`} />
<link rel="manifest" href={`${ASSET_PREFIX}/site.webmanifest.json`} />
<link rel="shortcut icon" href={`${ASSET_PREFIX}/favicon/favicon.ico`} />
<link rel="apple-touch-icon" sizes="180x180" href={`${SPACE_BASE_PATH}/favicon/apple-touch-icon.png`} />
<link rel="icon" type="image/png" sizes="32x32" href={`${SPACE_BASE_PATH}/favicon/favicon-32x32.png`} />
<link rel="icon" type="image/png" sizes="16x16" href={`${SPACE_BASE_PATH}/favicon/favicon-16x16.png`} />
<link rel="manifest" href={`${SPACE_BASE_PATH}/site.webmanifest.json`} />
<link rel="shortcut icon" href={`${SPACE_BASE_PATH}/favicon/favicon.ico`} />
</head>
<body>
<StoreProvider>
<ToastProvider>
<InstanceProvider>{children}</InstanceProvider>
</ToastProvider>
</StoreProvider>
<AppProvider>{children}</AppProvider>
</body>
</html>
);
Expand Down
23 changes: 23 additions & 0 deletions space/app/provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";

import { FC, ReactNode } from "react";
// components
import { InstanceProvider } from "@/lib/instance-provider";
import { StoreProvider } from "@/lib/store-provider";
import { ToastProvider } from "@/lib/toast-provider";

interface IAppProvider {
children: ReactNode;
}

export const AppProvider: FC<IAppProvider> = (props) => {
const { children } = props;

return (
<StoreProvider>
<ToastProvider>
<InstanceProvider>{children}</InstanceProvider>
</ToastProvider>
</StoreProvider>
);
};
16 changes: 0 additions & 16 deletions space/app/views/[anchor]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import { observer } from "mobx-react";
import Image from "next/image";
import useSWR from "swr";
// components
import { LogoSpinner } from "@/components/common";
Expand All @@ -11,8 +10,6 @@ import { usePublish, usePublishList } from "@/hooks/store";
// Plane web
import { ViewNavbarRoot } from "@/plane-web/components/navbar";
import { useView } from "@/plane-web/hooks/store";
// assets
import planeLogo from "@/public/plane-logo.svg";

type Props = {
children: React.ReactNode;
Expand Down Expand Up @@ -53,19 +50,6 @@ const IssuesLayout = observer((props: Props) => {
<ViewNavbarRoot publishSettings={publishSettings} />
</div>
<div className="relative h-full w-full overflow-hidden bg-custom-background-90">{children}</div>
<a
href="https://plane.so"
className="fixed bottom-2.5 right-5 !z-[999999] flex items-center gap-1 rounded border border-custom-border-200 bg-custom-background-100 px-2 py-1 shadow-custom-shadow-2xs"
target="_blank"
rel="noreferrer noopener"
>
<div className="relative grid h-6 w-6 place-items-center">
<Image src={planeLogo} alt="Plane logo" className="h-6 w-6" height="24" width="24" />
</div>
<div className="text-xs">
Powered by <span className="font-semibold">Plane Publish</span>
</div>
</a>
</div>
);
});
Expand Down
2 changes: 1 addition & 1 deletion space/core/components/account/auth-forms/password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { observer } from "mobx-react";
import { Eye, EyeOff, XCircle } from "lucide-react";
import { API_BASE_URL } from "@plane/constants";
import { Button, Input, Spinner } from "@plane/ui";
// components
import { PasswordStrengthMeter } from "@/components/account";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { E_PASSWORD_STRENGTH, getPasswordStrength } from "@/helpers/password.helper";
// services
import { AuthService } from "@/services/auth.service";
Expand Down
3 changes: 1 addition & 2 deletions space/core/components/account/auth-forms/unique-code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import React, { useEffect, useState } from "react";
import { CircleCheck, XCircle } from "lucide-react";
import { API_BASE_URL } from "@plane/constants";
import { Button, Input, Spinner } from "@plane/ui";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
// hooks
import useTimer from "@/hooks/use-timer";
// services
Expand Down
3 changes: 1 addition & 2 deletions space/core/components/account/oauth/github-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { FC } from "react";
import { useSearchParams } from "next/navigation";
import Image from "next/image";
import { useTheme } from "next-themes";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { API_BASE_URL } from "@plane/constants";
// images
import githubLightModeImage from "/public/logos/github-black.png";
import githubDarkModeImage from "/public/logos/github-dark.svg";
Expand Down
3 changes: 1 addition & 2 deletions space/core/components/account/oauth/gitlab-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { FC } from "react";
import { useSearchParams } from "next/navigation";
import Image from "next/image";
import { useTheme } from "next-themes";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { API_BASE_URL } from "@plane/constants";
// images
import GitlabLogo from "/public/logos/gitlab-logo.svg";

Expand Down
3 changes: 1 addition & 2 deletions space/core/components/account/oauth/google-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { FC } from "react";
import { useSearchParams } from "next/navigation";
import Image from "next/image";
import { useTheme } from "next-themes";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
import { API_BASE_URL } from "@plane/constants";
// images
import GoogleLogo from "/public/logos/google-logo.svg";

Expand Down
1 change: 1 addition & 0 deletions space/core/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./project-logo";
export * from "./logo-spinner";
export * from "./powered-by";
Loading