mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'preview' of github.com:makeplane/plane into auth-fixes
This commit is contained in:
commit
2501a8bbab
@ -7,9 +7,10 @@ import { Transition } from "@headlessui/react";
|
||||
import { ExternalLink, FileText, HelpCircle, MoveLeft } from "lucide-react";
|
||||
import { DiscordIcon, GithubIcon, Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import { useInstance, useTheme } from "@/hooks/store";
|
||||
import { useTheme } from "@/hooks/store";
|
||||
// assets
|
||||
import packageJson from "package.json";
|
||||
import { WEB_BASE_URL } from "@/helpers/common.helper";
|
||||
|
||||
const helpOptions = [
|
||||
{
|
||||
@ -30,8 +31,6 @@ const helpOptions = [
|
||||
];
|
||||
|
||||
export const HelpSection: FC = observer(() => {
|
||||
// hooks
|
||||
const { instance } = useInstance();
|
||||
// states
|
||||
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
||||
// store
|
||||
@ -39,7 +38,7 @@ export const HelpSection: FC = observer(() => {
|
||||
// refs
|
||||
const helpOptionsRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const redirectionLink = `${instance?.config?.app_base_url ? `${instance?.config?.app_base_url}/create-workspace` : `/god-mode/`}`;
|
||||
const redirectionLink = encodeURI(WEB_BASE_URL + "/create-workspace");
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -25,7 +25,7 @@
|
||||
"mobx-react-lite": "^4.0.5",
|
||||
"next": "^14.2.3",
|
||||
"next-themes": "^0.2.1",
|
||||
"postcss": "8.4.23",
|
||||
"postcss": "^8.4.38",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-hook-form": "^7.51.0",
|
||||
|
@ -38,6 +38,8 @@ class InstanceEndpoint(BaseAPIView):
|
||||
@cache_response(60 * 60 * 2, user=False)
|
||||
def get(self, request):
|
||||
instance = Instance.objects.first()
|
||||
|
||||
print("Instance: ", instance)
|
||||
# get the instance
|
||||
if instance is None:
|
||||
return Response(
|
||||
|
@ -30,19 +30,6 @@ INTERNAL_IPS = ("127.0.0.1",)
|
||||
MEDIA_URL = "/uploads/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "uploads") # noqa
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://localhost",
|
||||
"http://127.0.0.1",
|
||||
"http://localhost:3000",
|
||||
"http://127.0.0.1:3000",
|
||||
"http://localhost:3001",
|
||||
"http://127.0.0.1:3001",
|
||||
"http://localhost:3002",
|
||||
"http://127.0.0.1:3002",
|
||||
]
|
||||
CSRF_TRUSTED_ORIGINS = CORS_ALLOWED_ORIGINS
|
||||
CORS_ALLOW_ALL_ORIGINS = True
|
||||
|
||||
LOG_DIR = os.path.join(BASE_DIR, "logs") # noqa
|
||||
|
||||
if not os.path.exists(LOG_DIR):
|
||||
|
@ -21,6 +21,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||
# Module imports
|
||||
from plane.utils.exception_logger import log_exception
|
||||
from plane.utils.paginator import BasePaginator
|
||||
from plane.authentication.session import BaseSessionAuthentication
|
||||
|
||||
|
||||
class TimezoneMixin:
|
||||
@ -49,6 +50,10 @@ class BaseViewSet(TimezoneMixin, ModelViewSet, BasePaginator):
|
||||
SearchFilter,
|
||||
)
|
||||
|
||||
authentication_classes = [
|
||||
BaseSessionAuthentication,
|
||||
]
|
||||
|
||||
filterset_fields = []
|
||||
|
||||
search_fields = []
|
||||
@ -146,6 +151,10 @@ class BaseAPIView(TimezoneMixin, APIView, BasePaginator):
|
||||
|
||||
search_fields = []
|
||||
|
||||
authentication_classes = [
|
||||
BaseSessionAuthentication,
|
||||
]
|
||||
|
||||
def filter_queryset(self, queryset):
|
||||
for backend in list(self.filter_backends):
|
||||
queryset = backend().filter_queryset(self.request, queryset, self)
|
||||
|
@ -25,7 +25,7 @@
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.15",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "latest",
|
||||
"prettier-plugin-tailwindcss": "^0.5.4",
|
||||
"tailwindcss": "^3.3.3",
|
||||
|
@ -61,7 +61,7 @@
|
||||
"@types/react": "^18.2.42",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwind-config-custom": "*",
|
||||
"tsconfig": "*",
|
||||
"tsup": "^7.2.0",
|
||||
|
@ -46,7 +46,7 @@
|
||||
"@types/react": "^18.2.42",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwind-config-custom": "*",
|
||||
"tsconfig": "*",
|
||||
"tsup": "^7.2.0",
|
||||
|
@ -42,7 +42,7 @@
|
||||
"@types/react": "^18.2.42",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwind-config-custom": "*",
|
||||
"tsconfig": "*",
|
||||
"tsup": "^7.2.0",
|
||||
|
@ -37,7 +37,7 @@
|
||||
"@types/react": "^18.2.42",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"tailwind-config-custom": "*",
|
||||
"tsconfig": "*",
|
||||
"tsup": "^7.2.0",
|
||||
|
@ -39,7 +39,7 @@
|
||||
"@types/react": "^18.2.42",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"eslint-config-custom": "*",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.38",
|
||||
"react": "^18.2.0",
|
||||
"tailwind-config-custom": "*",
|
||||
"tsconfig": "*",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"tailwindcss": "^3.2.7",
|
||||
|
@ -1 +1,2 @@
|
||||
export * from "./not-ready-view";
|
||||
export * from "./not-ready-view";
|
||||
export * from "./instance-failure-view";
|
||||
|
38
space/components/instance/instance-failure-view.tsx
Normal file
38
space/components/instance/instance-failure-view.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { FC } from "react";
|
||||
import Image from "next/image";
|
||||
import { useTheme } from "next-themes";
|
||||
import { Button } from "@plane/ui";
|
||||
// assets
|
||||
import InstanceFailureDarkImage from "public/instance/instance-failure-dark.svg";
|
||||
import InstanceFailureImage from "public/instance/instance-failure.svg";
|
||||
|
||||
type InstanceFailureViewProps = {
|
||||
mutate: () => void;
|
||||
};
|
||||
|
||||
export const InstanceFailureView: FC<InstanceFailureViewProps> = (props) => {
|
||||
const { mutate } = props;
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
const instanceImage = resolvedTheme === "dark" ? InstanceFailureDarkImage : InstanceFailureImage;
|
||||
|
||||
return (
|
||||
<div className="h-full w-full relative container px-5 mx-auto flex justify-center items-center mt-10">
|
||||
<div className="w-auto max-w-2xl relative space-y-8 py-10">
|
||||
<div className="relative flex flex-col justify-center items-center space-y-4">
|
||||
<Image src={instanceImage} alt="Plane Logo" />
|
||||
<h3 className="font-medium text-2xl text-white ">Unable to fetch instance details.</h3>
|
||||
<p className="font-medium text-base text-center">
|
||||
We were unable to fetch the details of the instance. <br />
|
||||
Fret not, it might just be a connectivity issue.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<Button size="md" onClick={mutate}>
|
||||
Retry
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,40 +1,33 @@
|
||||
import { FC } from "react";
|
||||
import Image from "next/image";
|
||||
import { useTheme } from "next-themes";
|
||||
// icons
|
||||
import { UserCog2 } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
// ui
|
||||
import { getButtonStyling } from "@plane/ui";
|
||||
import { Button } from "@plane/ui";
|
||||
// helpers
|
||||
import { ADMIN_BASE_URL, ADMIN_BASE_PATH } from "@/helpers/common.helper";
|
||||
// images
|
||||
import instanceNotReady from "public/instance/plane-instance-not-ready.webp";
|
||||
import PlaneBlackLogo from "public/plane-logos/black-horizontal-with-blue-logo.svg";
|
||||
import PlaneWhiteLogo from "public/plane-logos/white-horizontal-with-blue-logo.svg";
|
||||
import PlaneTakeOffImage from "@/public/instance/plane-takeoff.png";
|
||||
|
||||
export const InstanceNotReady: FC = () => {
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
const planeLogo = resolvedTheme === "dark" ? PlaneWhiteLogo : PlaneBlackLogo;
|
||||
const GOD_MODE_URL = encodeURI(ADMIN_BASE_URL + ADMIN_BASE_PATH + "/setup/?auth_enabled=0");
|
||||
|
||||
return (
|
||||
<div className="h-screen w-full overflow-y-auto bg-onboarding-gradient-100">
|
||||
<div className="h-full w-full pt-24">
|
||||
<div className="mx-auto h-full rounded-t-md border-x border-t border-custom-border-100 bg-onboarding-gradient-100 px-4 pt-4 shadow-sm sm:w-4/5 md:w-2/3">
|
||||
<div className="relative h-full rounded-t-md bg-onboarding-gradient-200 px-7 sm:px-0">
|
||||
<div className="flex items-center justify-center py-10">
|
||||
<Image src={planeLogo} className="h-[44px] w-full" alt="Plane logo" />
|
||||
</div>
|
||||
<div className="mt-20">
|
||||
<Image src={instanceNotReady} className="w-full" alt="Instance not ready" />
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-center gap-5 py-12 pb-20">
|
||||
<h3 className="text-2xl font-medium">Your Plane instance isn{"'"}t ready yet</h3>
|
||||
<p className="text-sm">Ask your Instance Admin to complete set-up first.</p>
|
||||
<a href="/god-mode" className={`${getButtonStyling("primary", "md")} mt-4`}>
|
||||
<UserCog2 className="h-3.5 w-3.5" />
|
||||
Get started
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full w-full relative container px-5 mx-auto flex justify-center items-center mt-10">
|
||||
<div className="w-auto max-w-2xl relative space-y-8 py-10">
|
||||
<div className="relative flex flex-col justify-center items-center space-y-4">
|
||||
<h1 className="text-3xl font-bold pb-3">Welcome aboard Plane!</h1>
|
||||
<Image src={PlaneTakeOffImage} alt="Plane Logo" />
|
||||
<p className="font-medium text-base text-onboarding-text-400">
|
||||
Get started by setting up your instance and workspace
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Link href={GOD_MODE_URL}>
|
||||
<Button size="lg" className="w-full">
|
||||
Get started
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,9 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "";
|
||||
|
||||
export const ADMIN_BASE_URL = process.env.NEXT_PUBLIC_ADMIN_BASE_URL || "";
|
||||
export const ADMIN_BASE_PATH = process.env.NEXT_PUBLIC_ADMIN_BASE_PATH || "";
|
||||
|
||||
export const SPACE_BASE_PATH = process.env.NEXT_PUBLIC_SPACE_BASE_PATH || "";
|
||||
|
||||
export const WEB_BASE_URL = process.env.NEXT_PUBLIC_WEB_BASE_URL || "";
|
||||
|
@ -1,10 +1,9 @@
|
||||
import Image from "next/image";
|
||||
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
import planeLogo from "public/plane-logo.svg";
|
||||
import Image from "next/image";
|
||||
// components
|
||||
import IssueNavbar from "@/components/issues/navbar";
|
||||
// logo
|
||||
import planeLogo from "public/plane-logo.svg";
|
||||
|
||||
const ProjectLayout = ({ children }: { children: React.ReactNode }) => (
|
||||
<div className="relative flex h-screen min-h-[500px] w-screen flex-col overflow-hidden">
|
||||
@ -12,7 +11,6 @@ const ProjectLayout = ({ children }: { children: React.ReactNode }) => (
|
||||
<IssueNavbar />
|
||||
</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"
|
||||
|
@ -32,6 +32,7 @@ export const AuthWrapper: FC<TAuthWrapper> = observer((props) => {
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
||||
if (pageType === EPageTypes.PUBLIC) return <>{children}</>;
|
||||
|
||||
if (pageType === EPageTypes.INIT) {
|
||||
|
@ -4,7 +4,7 @@ import useSWR from "swr";
|
||||
// ui
|
||||
import { Spinner } from "@plane/ui";
|
||||
// components
|
||||
import { InstanceNotReady } from "@/components/instance";
|
||||
import { InstanceNotReady, InstanceFailureView } from "@/components/instance";
|
||||
// hooks
|
||||
import { useInstance } from "@/hooks/store";
|
||||
|
||||
@ -17,8 +17,11 @@ export const InstanceWrapper: FC<TInstanceWrapper> = observer((props) => {
|
||||
// hooks
|
||||
const { isLoading, instance, fetchInstanceInfo } = useInstance();
|
||||
|
||||
const { isLoading: isSWRLoading } = useSWR("INSTANCE_INFORMATION", () => fetchInstanceInfo(), {
|
||||
const { isLoading: isSWRLoading, mutate } = useSWR("INSTANCE_INFORMATION", () => fetchInstanceInfo(), {
|
||||
revalidateOnFocus: false,
|
||||
revalidateIfStale: false,
|
||||
revalidateOnReconnect: false,
|
||||
errorRetryCount: 0,
|
||||
});
|
||||
|
||||
if (isSWRLoading || isLoading)
|
||||
@ -28,6 +31,8 @@ export const InstanceWrapper: FC<TInstanceWrapper> = observer((props) => {
|
||||
</div>
|
||||
);
|
||||
|
||||
if (!instance) return <InstanceFailureView mutate={mutate} />;
|
||||
|
||||
if (instance?.instance?.is_setup_done === false) return <InstanceNotReady />;
|
||||
|
||||
return <>{children}</>;
|
||||
|
40
space/public/instance/instance-failure-dark.svg
Normal file
40
space/public/instance/instance-failure-dark.svg
Normal file
@ -0,0 +1,40 @@
|
||||
<svg width="210" height="206" viewBox="0 0 210 206" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="107.5" cy="103" r="102.5" fill="#24252C"/>
|
||||
<path d="M140.625 162.125V148.875C138.868 148.875 137.183 148.177 135.94 146.935C134.698 145.692 134 144.007 134 142.25V135.625C134 132.111 135.396 128.741 137.881 126.256C140.366 123.771 143.736 122.375 147.25 122.375H160.5C164.014 122.375 167.384 123.771 169.869 126.256C172.354 128.741 173.75 132.111 173.75 135.625V142.25C173.75 144.007 173.052 145.692 171.81 146.935C170.567 148.177 168.882 148.875 167.125 148.875" stroke="#454961" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M153.875 122.375V66.0625C153.875 59.9128 151.432 54.015 147.084 49.6665C142.735 45.318 136.837 42.875 130.687 42.875C124.538 42.875 118.64 45.318 114.291 49.6665C109.943 54.015 107.5 59.9128 107.5 66.0625M107.5 138.937C107.5 145.087 105.057 150.985 100.709 155.334C96.36 159.682 90.4622 162.125 84.3125 162.125C78.1628 162.125 72.265 159.682 67.9165 155.334C63.568 150.985 61.125 145.087 61.125 138.937V82.625" stroke="#454961" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M167.125 162.125V148.875H140.625" stroke="#454961" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M47.875 56.125H74.375V42.875" stroke="#454961" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M74.375 56.125C76.1321 56.125 77.8172 56.823 79.0596 58.0654C80.302 59.3078 81 60.9929 81 62.75V69.375C81 72.8891 79.604 76.2593 77.1192 78.7442C74.6343 81.229 71.2641 82.625 67.75 82.625H54.5C50.9859 82.625 47.6157 81.229 45.1308 78.7442C42.646 76.2593 41.25 72.8891 41.25 69.375V62.75C41.25 60.9929 41.948 59.3078 43.1904 58.0654C44.4328 56.823 46.1179 56.125 47.875 56.125V42.875" stroke="#454961" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g filter="url(#filter0_ddd_11437_265561)">
|
||||
<circle cx="107.911" cy="102.911" r="23.7938" fill="#3A5BC7"/>
|
||||
<path d="M114.051 96.7712L101.771 109.052" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M101.771 96.7712L114.051 109.052" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_ddd_11437_265561" x="76.1172" y="74.1177" width="63.5879" height="64.5876" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="2" operator="erode" in="SourceAlpha" result="effect1_dropShadow_11437_265561"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="1.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.24 0 0 0 0.051 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_11437_265561"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect2_dropShadow_11437_265561"/>
|
||||
<feOffset dy="3"/>
|
||||
<feGaussianBlur stdDeviation="6"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.055 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_11437_265561" result="effect2_dropShadow_11437_265561"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="8" operator="erode" in="SourceAlpha" result="effect3_dropShadow_11437_265561"/>
|
||||
<feOffset dy="4"/>
|
||||
<feGaussianBlur stdDeviation="8"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.078 0"/>
|
||||
<feBlend mode="normal" in2="effect2_dropShadow_11437_265561" result="effect3_dropShadow_11437_265561"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect3_dropShadow_11437_265561" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
40
space/public/instance/instance-failure.svg
Normal file
40
space/public/instance/instance-failure.svg
Normal file
@ -0,0 +1,40 @@
|
||||
<svg width="210" height="206" viewBox="0 0 210 206" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="107.5" cy="103" r="102.5" fill="#F3F6FF"/>
|
||||
<path d="M140.625 162.125V148.875C138.868 148.875 137.183 148.177 135.94 146.935C134.698 145.692 134 144.007 134 142.25V135.625C134 132.111 135.396 128.741 137.881 126.256C140.366 123.771 143.736 122.375 147.25 122.375H160.5C164.014 122.375 167.384 123.771 169.869 126.256C172.354 128.741 173.75 132.111 173.75 135.625V142.25C173.75 144.007 173.052 145.692 171.81 146.935C170.567 148.177 168.882 148.875 167.125 148.875" stroke="#3E63DD" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M153.875 122.375V66.0625C153.875 59.9128 151.432 54.015 147.084 49.6665C142.735 45.318 136.837 42.875 130.687 42.875C124.538 42.875 118.64 45.318 114.291 49.6665C109.943 54.015 107.5 59.9128 107.5 66.0625M107.5 138.937C107.5 145.087 105.057 150.985 100.709 155.334C96.36 159.682 90.4622 162.125 84.3125 162.125C78.1628 162.125 72.265 159.682 67.9165 155.334C63.568 150.985 61.125 145.087 61.125 138.937V82.625" stroke="#3E63DD" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M167.125 162.125V148.875H140.625" stroke="#3E63DD" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M47.875 56.125H74.375V42.875" stroke="#3E63DD" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M74.375 56.125C76.1321 56.125 77.8172 56.823 79.0596 58.0654C80.302 59.3078 81 60.9929 81 62.75V69.375C81 72.8891 79.604 76.2593 77.1192 78.7442C74.6343 81.229 71.2641 82.625 67.75 82.625H54.5C50.9859 82.625 47.6157 81.229 45.1308 78.7442C42.646 76.2593 41.25 72.8891 41.25 69.375V62.75C41.25 60.9929 41.948 59.3078 43.1904 58.0654C44.4328 56.823 46.1179 56.125 47.875 56.125V42.875" stroke="#3E63DD" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g filter="url(#filter0_ddd_11424_265422)">
|
||||
<circle cx="107.911" cy="102.911" r="23.7938" fill="#3A5BC7"/>
|
||||
<path d="M114.051 96.7712L101.771 109.052" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M101.771 96.7712L114.051 109.052" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_ddd_11424_265422" x="76.1172" y="74.1177" width="63.5879" height="64.5876" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="2" operator="erode" in="SourceAlpha" result="effect1_dropShadow_11424_265422"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="1.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.24 0 0 0 0.051 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_11424_265422"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect2_dropShadow_11424_265422"/>
|
||||
<feOffset dy="3"/>
|
||||
<feGaussianBlur stdDeviation="6"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.055 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_11424_265422" result="effect2_dropShadow_11424_265422"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="8" operator="erode" in="SourceAlpha" result="effect3_dropShadow_11424_265422"/>
|
||||
<feOffset dy="4"/>
|
||||
<feGaussianBlur stdDeviation="8"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.078 0"/>
|
||||
<feBlend mode="normal" in2="effect2_dropShadow_11424_265422" result="effect3_dropShadow_11424_265422"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect3_dropShadow_11424_265422" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
BIN
space/public/instance/plane-takeoff.png
Normal file
BIN
space/public/instance/plane-takeoff.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
@ -2,7 +2,7 @@ import { FC, MouseEvent, useRef } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { Info } from "lucide-react";
|
||||
import { CalendarCheck2, CalendarClock, Info, MoveRight } from "lucide-react";
|
||||
// types
|
||||
import type { TCycleGroups } from "@plane/types";
|
||||
// ui
|
||||
@ -226,12 +226,14 @@ export const CyclesBoardCard: FC<ICyclesBoardCard> = observer((props) => {
|
||||
</Tooltip>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
{isDateValid ? (
|
||||
<span className="text-xs text-custom-text-300">
|
||||
{renderFormattedDate(startDate) ?? "_ _"} - {renderFormattedDate(endDate) ?? "_ _"}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs text-custom-text-400">No due date</span>
|
||||
{isDateValid && (
|
||||
<div className="h-6 flex items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs px-2 cursor-default">
|
||||
<CalendarClock className="h-3 w-3 flex-shrink-0" />
|
||||
<span className="flex-grow truncate">{renderFormattedDate(startDate)}</span>
|
||||
<MoveRight className="h-3 w-3 flex-shrink-0" />
|
||||
<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />
|
||||
<span className="flex-grow truncate">{renderFormattedDate(endDate)}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { FC, MouseEvent } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { User2 } from "lucide-react";
|
||||
import { CalendarCheck2, CalendarClock, MoveRight, User2 } from "lucide-react";
|
||||
// types
|
||||
import { ICycle, TCycleGroups } from "@plane/types";
|
||||
// ui
|
||||
@ -106,9 +106,15 @@ export const CycleListItemAction: FC<Props> = observer((props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="text-xs text-custom-text-300 flex-shrink-0">
|
||||
{renderDate && `${renderFormattedDate(startDate) ?? `_ _`} - ${renderFormattedDate(endDate) ?? `_ _`}`}
|
||||
</div>
|
||||
{renderDate && (
|
||||
<div className="h-6 flex items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs px-2 cursor-default">
|
||||
<CalendarClock className="h-3 w-3 flex-shrink-0" />
|
||||
<span className="flex-grow truncate">{renderFormattedDate(startDate)}</span>
|
||||
<MoveRight className="h-3 w-3 flex-shrink-0" />
|
||||
<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />
|
||||
<span className="flex-grow truncate">{renderFormattedDate(endDate)}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{currentCycle && (
|
||||
<div
|
||||
|
@ -94,7 +94,7 @@ export const CyclesListItem: FC<TCyclesListItem> = observer((props) => {
|
||||
) : progress === 100 ? (
|
||||
<Check className="h-3 w-3 stroke-[2] text-custom-primary-100" />
|
||||
) : (
|
||||
<span className="text-xs text-custom-text-300">{`${progress}%`}</span>
|
||||
<span className="text-[9px] text-custom-text-300">{`${progress}%`}</span>
|
||||
)}
|
||||
</CircularProgressIndicator>
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { ArrowRight, Plus, PanelRight } from "lucide-react";
|
||||
import { ArrowRight, PanelRight } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
// ui
|
||||
@ -281,7 +281,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
toggleCreateIssueModal(true, EIssuesStoreType.CYCLE);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
Add Issue
|
||||
</Button>
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { Plus } from "lucide-react";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, ContrastIcon } from "@plane/ui";
|
||||
// components
|
||||
@ -61,7 +59,6 @@ export const CyclesHeader: FC = observer(() => {
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
setTrackElement("Cycles page");
|
||||
toggleCreateCycleModal(true);
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { useCallback, useState } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { PlusIcon } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types";
|
||||
// ui
|
||||
@ -134,8 +132,8 @@ export const GlobalIssuesHeader: React.FC = observer(() => {
|
||||
</FiltersDropdown>
|
||||
</>
|
||||
{isAuthorizedUser && (
|
||||
<Button variant="primary" size="sm" prependIcon={<PlusIcon />} onClick={() => setCreateViewModal(true)}>
|
||||
New View
|
||||
<Button variant="primary" size="sm" onClick={() => setCreateViewModal(true)}>
|
||||
Add View
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { ArrowRight, PanelRight, Plus } from "lucide-react";
|
||||
import { ArrowRight, PanelRight } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
// ui
|
||||
@ -288,7 +288,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
toggleCreateIssueModal(true, EIssuesStoreType.MODULE);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
Add Issue
|
||||
</Button>
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { Plus } from "lucide-react";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, DiceIcon } from "@plane/ui";
|
||||
// components
|
||||
@ -63,7 +61,6 @@ export const ModulesListHeader: React.FC = observer(() => {
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
setTrackElement("Modules page");
|
||||
toggleCreateModuleModal(true);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { FileText, Plus } from "lucide-react";
|
||||
import { FileText } from "lucide-react";
|
||||
// hooks
|
||||
// ui
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
@ -79,8 +79,8 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
</div>
|
||||
{showButton && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="primary" prependIcon={<Plus />} size="sm" onClick={() => toggleCreatePageModal(true)}>
|
||||
Create Page
|
||||
<Button variant="primary" size="sm" onClick={() => toggleCreatePageModal(true)}>
|
||||
Add Page
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { observer } from "mobx-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { FileText, Plus } from "lucide-react";
|
||||
import { FileText } from "lucide-react";
|
||||
// hooks
|
||||
// ui
|
||||
import { Breadcrumbs, Button } from "@plane/ui";
|
||||
@ -59,14 +59,13 @@ export const PagesHeader = observer(() => {
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="primary"
|
||||
prependIcon={<Plus />}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setTrackElement("Project pages page");
|
||||
toggleCreatePageModal(true);
|
||||
}}
|
||||
>
|
||||
Create Page
|
||||
Add Page
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FC, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { Plus, RefreshCcw } from "lucide-react";
|
||||
import { RefreshCcw } from "lucide-react";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, LayersIcon } from "@plane/ui";
|
||||
// components
|
||||
@ -70,7 +70,7 @@ export const ProjectInboxHeader: FC = observer(() => {
|
||||
issue={undefined}
|
||||
/>
|
||||
|
||||
<Button variant="primary" prependIcon={<Plus />} size="sm" onClick={() => setCreateIssueModal(true)}>
|
||||
<Button variant="primary" size="sm" onClick={() => setCreateIssueModal(true)}>
|
||||
Add Issue
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@ import { useCallback, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { Briefcase, Circle, ExternalLink, Plus } from "lucide-react";
|
||||
import { Briefcase, Circle, ExternalLink } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
// ui
|
||||
@ -229,7 +229,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
<div className="hidden sm:block">Add</div> Issue
|
||||
</Button>
|
||||
|
@ -2,8 +2,6 @@ import { useCallback } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
// icons
|
||||
import { Plus } from "lucide-react";
|
||||
// types
|
||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types";
|
||||
// ui
|
||||
@ -241,7 +239,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
||||
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
Add Issue
|
||||
</Button>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { observer } from "mobx-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { Plus } from "lucide-react";
|
||||
// hooks
|
||||
// components
|
||||
import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui";
|
||||
@ -61,13 +60,8 @@ export const ProjectViewsHeader: React.FC = observer(() => {
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
<ViewListHeader />
|
||||
<div>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
prependIcon={<Plus className="h-3.5 w-3.5 stroke-2" />}
|
||||
onClick={() => toggleCreateViewModal(true)}
|
||||
>
|
||||
Create View
|
||||
<Button variant="primary" size="sm" onClick={() => toggleCreateViewModal(true)}>
|
||||
Add View
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Search, Plus, Briefcase, X, ListFilter } from "lucide-react";
|
||||
import { Search, Briefcase, X, ListFilter } from "lucide-react";
|
||||
// types
|
||||
import { TProjectFilters } from "@plane/types";
|
||||
// ui
|
||||
@ -167,7 +167,6 @@ export const ProjectsHeader = observer(() => {
|
||||
</div>
|
||||
{isAuthorizedUser && (
|
||||
<Button
|
||||
prependIcon={<Plus />}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setTrackElement("Projects page");
|
||||
|
@ -80,7 +80,7 @@ export const IssueBlockRoot: FC<Props> = observer((props) => {
|
||||
canEditProperties={canEditProperties}
|
||||
displayProperties={displayProperties}
|
||||
nestingLevel={nestingLevel + 1}
|
||||
spacingLeft={spacingLeft + (displayProperties?.key ? 19 : 0)}
|
||||
spacingLeft={spacingLeft + (displayProperties?.key ? 12 : 0)}
|
||||
containerRef={containerRef}
|
||||
/>
|
||||
))}
|
||||
|
@ -57,14 +57,14 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
||||
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
|
||||
|
||||
const issue = issuesMap[issueId];
|
||||
const subIssues = subIssuesStore.subIssuesByIssueId(issueId);
|
||||
// const subIssues = subIssuesStore.subIssuesByIssueId(issueId);
|
||||
const { isMobile } = usePlatformOS();
|
||||
if (!issue) return null;
|
||||
|
||||
const canEditIssueProperties = canEditProperties(issue.project_id);
|
||||
const projectIdentifier = getProjectIdentifierById(issue.project_id);
|
||||
// if sub issues have been fetched for the issue, use that for count or use issue's sub_issues_count
|
||||
const subIssuesCount = subIssues ? subIssues.length : issue.sub_issues_count;
|
||||
// const subIssuesCount = subIssues ? subIssues.length : issue.sub_issues_count;
|
||||
|
||||
const paddingLeft = `${spacingLeft}px`;
|
||||
|
||||
@ -86,25 +86,28 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
||||
<div
|
||||
ref={parentRef}
|
||||
className={cn(
|
||||
"min-h-[52px] relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 pl-8 text-sm",
|
||||
"min-h-11 relative flex flex-col md:flex-row md:items-center gap-3 bg-custom-background-100 p-3 pl-1.5 text-sm",
|
||||
{
|
||||
"border border-custom-primary-70 hover:border-custom-primary-70": getIsIssuePeeked(issue.id),
|
||||
"last:border-b-transparent": !getIsIssuePeeked(issue.id),
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full truncate" style={nestingLevel !== 0 ? { paddingLeft } : {}}>
|
||||
<div className="flex w-full truncate" style={issue?.parent_id && nestingLevel !== 0 ? { paddingLeft } : {}}>
|
||||
<div className="flex flex-grow items-center gap-3 truncate">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<div className="flex h-5 w-5 items-center justify-center">
|
||||
{subIssuesCount > 0 && (
|
||||
<button
|
||||
className="flex items-center justify-center h-5 w-5 cursor-pointer rounded-sm text-custom-text-400 hover:text-custom-text-300"
|
||||
onClick={handleToggleExpand}
|
||||
>
|
||||
<ChevronRight className={`h-4 w-4 ${isExpanded ? "rotate-90" : ""}`} />
|
||||
</button>
|
||||
)}
|
||||
<div className="flex items-center gap-0.5">
|
||||
<div className="flex items-center group">
|
||||
<span className="size-3.5" />
|
||||
<div className="flex h-4 w-4 items-center justify-center">
|
||||
{issue.sub_issues_count > 0 && (
|
||||
<button
|
||||
className="flex items-center justify-center h-4 w-4 cursor-pointer rounded-sm text-custom-text-400 hover:text-custom-text-300"
|
||||
onClick={handleToggleExpand}
|
||||
>
|
||||
<ChevronRight className={`h-4 w-4 ${isExpanded ? "rotate-90" : ""}`} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{displayProperties && displayProperties?.key && (
|
||||
<div className="flex-shrink-0 text-xs font-medium text-custom-text-300">
|
||||
@ -118,7 +121,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
||||
</div>
|
||||
|
||||
{issue?.is_draft ? (
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile} position="top-left">
|
||||
<p className="truncate">{issue.name}</p>
|
||||
</Tooltip>
|
||||
) : (
|
||||
@ -132,7 +135,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
||||
className="w-full truncate cursor-pointer text-sm text-custom-text-100"
|
||||
disabled={!!issue?.tempId}
|
||||
>
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile} position="top-left">
|
||||
<p className="truncate">{issue.name}</p>
|
||||
</Tooltip>
|
||||
</ControlLink>
|
||||
@ -151,7 +154,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
|
||||
{!issue?.tempId ? (
|
||||
<>
|
||||
<IssueProperties
|
||||
className="relative flex flex-wrap items-center gap-2 whitespace-nowrap md:flex-shrink-0 md:flex-grow"
|
||||
className="relative flex flex-wrap md:flex-grow md:flex-shrink-0 items-center gap-2 whitespace-nowrap"
|
||||
issue={issue}
|
||||
isReadOnly={!canEditIssueProperties}
|
||||
updateIssue={updateIssue}
|
||||
|
@ -133,7 +133,7 @@ const GroupByList: React.FC<IGroupByList> = (props) => {
|
||||
(_list: IGroupByColumn) =>
|
||||
validateEmptyIssueGroups(is_list ? issueIds : issueIds?.[_list.id]) && (
|
||||
<div key={_list.id} className={`flex flex-shrink-0 flex-col`}>
|
||||
<div className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 py-1">
|
||||
<div className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-custom-border-200 bg-custom-background-90 px-3 pl-5 py-1">
|
||||
<HeaderGroupByCard
|
||||
icon={_list.icon}
|
||||
title={_list.name || ""}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { FC, useState } from "react";
|
||||
import { Plus } from "lucide-react";
|
||||
import { Button } from "@plane/ui";
|
||||
// components
|
||||
import { CreateUpdateProjectViewModal } from "@/components/views";
|
||||
@ -25,7 +24,7 @@ export const SaveFilterView: FC<ISaveFilterView> = (props) => {
|
||||
onClose={() => setViewModal(false)}
|
||||
/>
|
||||
|
||||
<Button size="sm" prependIcon={<Plus />} onClick={() => setViewModal(true)}>
|
||||
<Button size="sm" onClick={() => setViewModal(true)}>
|
||||
Save View
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { FC } from "react";
|
||||
import { FC, Fragment } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { TIssue } from "@plane/types";
|
||||
// hooks
|
||||
@ -45,7 +45,7 @@ export const IssueList: FC<IIssueList> = observer((props) => {
|
||||
{subIssueIds &&
|
||||
subIssueIds.length > 0 &&
|
||||
subIssueIds.map((issueId) => (
|
||||
<>
|
||||
<Fragment key={issueId}>
|
||||
<IssueListItem
|
||||
workspaceSlug={workspaceSlug}
|
||||
projectId={projectId}
|
||||
@ -56,7 +56,7 @@ export const IssueList: FC<IIssueList> = observer((props) => {
|
||||
handleIssueCrudState={handleIssueCrudState}
|
||||
subIssueOperations={subIssueOperations}
|
||||
/>
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
<div
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Circle, Earth, Info, Lock, Minus } from "lucide-react";
|
||||
import { Earth, Info, Lock, Minus } from "lucide-react";
|
||||
// ui
|
||||
import { Avatar, TOAST_TYPE, Tooltip, setToast } from "@plane/ui";
|
||||
// components
|
||||
@ -50,24 +50,16 @@ export const BlockItemAction: FC<Props> = observer((props) => {
|
||||
return (
|
||||
<>
|
||||
{/* page details */}
|
||||
<div className="flex items-center gap-2 text-custom-text-400">
|
||||
{/* <span className="text-xs">Labels</span>
|
||||
<Circle className="h-1 w-1 fill-custom-text-300" /> */}
|
||||
<div className="cursor-default">
|
||||
<Tooltip tooltipHeading="Owned by" tooltipContent={ownerDetails?.display_name}>
|
||||
<Avatar src={ownerDetails?.avatar} name={ownerDetails?.display_name} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Circle className="h-1 w-1 fill-custom-text-300" />
|
||||
{/* <span className="text-xs cursor-default">10m read</span>
|
||||
<Circle className="h-1 w-1 fill-custom-text-300" /> */}
|
||||
<div className="cursor-default">
|
||||
<Tooltip tooltipContent={access === 0 ? "Public" : "Private"}>
|
||||
{access === 0 ? <Earth className="h-3 w-3" /> : <Lock className="h-3 w-3" />}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="cursor-default">
|
||||
<Tooltip tooltipHeading="Owned by" tooltipContent={ownerDetails?.display_name}>
|
||||
<Avatar src={ownerDetails?.avatar} name={ownerDetails?.display_name} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="cursor-default text-custom-text-300">
|
||||
<Tooltip tooltipContent={access === 0 ? "Public" : "Private"}>
|
||||
{access === 0 ? <Earth className="h-4 w-4" /> : <Lock className="h-4 w-4" />}
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
{/* vertical divider */}
|
||||
<Minus className="h-5 w-5 text-custom-text-400 rotate-90 -mx-3" strokeWidth={1} />
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Fragment } from "react";
|
||||
import { getRandomInt, getRandomLength } from "../utils";
|
||||
|
||||
const ListItemRow = () => (
|
||||
@ -8,13 +9,13 @@ const ListItemRow = () => (
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{[...Array(6)].map((_, index) => (
|
||||
<>
|
||||
<Fragment key={index}>
|
||||
{getRandomInt(1, 2) % 2 === 0 ? (
|
||||
<span key={index} className="h-5 w-5 bg-custom-background-80 rounded" />
|
||||
) : (
|
||||
<span className="h-5 w-16 bg-custom-background-80 rounded" />
|
||||
)}
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
// types
|
||||
import { RootStore } from "@/store/root.store";
|
||||
import { IUserLite } from "@plane/types";
|
||||
import { RootStore } from "@/store/root.store";
|
||||
import { IProjectMemberStore, ProjectMemberStore } from "./project-member.store";
|
||||
import { IWorkspaceMemberStore, WorkspaceMemberStore } from "./workspace-member.store";
|
||||
|
||||
|
32
yarn.lock
32
yarn.lock
@ -6908,15 +6908,6 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss@8.4.23:
|
||||
version "8.4.23"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
|
||||
integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==
|
||||
dependencies:
|
||||
nanoid "^3.3.6"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
postcss@8.4.31:
|
||||
version "8.4.31"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
|
||||
@ -6926,7 +6917,7 @@ postcss@8.4.31:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.29:
|
||||
postcss@^8.4.23, postcss@^8.4.38:
|
||||
version "8.4.38"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e"
|
||||
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
|
||||
@ -7954,16 +7945,8 @@ streamx@^2.15.0, streamx@^2.16.1:
|
||||
optionalDependencies:
|
||||
bare-events "^2.2.0"
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0:
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
|
||||
name string-width-cjs
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -8043,14 +8026,7 @@ stringify-object@^3.3.0:
|
||||
is-obj "^1.0.1"
|
||||
is-regexp "^1.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
Loading…
Reference in New Issue
Block a user