mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
refactor: admin and added new spinner
This commit is contained in:
parent
5ccb4f7d19
commit
b78a064305
@ -1,2 +0,0 @@
|
|||||||
export * from "./email-config-form";
|
|
||||||
export * from "./test-email-modal";
|
|
@ -1,14 +1,15 @@
|
|||||||
import React, { FC, useMemo, useState } from "react";
|
import React, { FC, useMemo, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
// hooks
|
|
||||||
import { IFormattedInstanceConfiguration, TInstanceEmailConfigurationKeys } from "@plane/types";
|
|
||||||
import { Button, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
|
|
||||||
import { useInstance } from "@/hooks/store";
|
|
||||||
// ui
|
|
||||||
// components
|
|
||||||
import { ControllerInput, TControllerInputFormField } from "components/common";
|
|
||||||
import { SendTestEmailModal } from "./test-email-modal";
|
|
||||||
// types
|
// types
|
||||||
|
import { IFormattedInstanceConfiguration, TInstanceEmailConfigurationKeys } from "@plane/types";
|
||||||
|
// ui
|
||||||
|
import { Button, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
|
// components
|
||||||
|
import { ControllerInput, TControllerInputFormField } from "@/components/common";
|
||||||
|
// hooks
|
||||||
|
import { useInstance } from "@/hooks/store";
|
||||||
|
// local components
|
||||||
|
import { SendTestEmailModal } from "./test-email-modal";
|
||||||
|
|
||||||
type IInstanceEmailForm = {
|
type IInstanceEmailForm = {
|
||||||
config: IFormattedInstanceConfiguration;
|
config: IFormattedInstanceConfiguration;
|
@ -3,19 +3,11 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
// layouts
|
// layouts
|
||||||
import { AdminLayout } from "@/layouts/admin-layout";
|
import { AdminLayout } from "@/layouts/admin-layout";
|
||||||
// lib
|
|
||||||
import { AuthWrapper, InstanceWrapper } from "@/lib/wrappers";
|
|
||||||
|
|
||||||
interface EmailLayoutProps {
|
interface EmailLayoutProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmailLayout = ({ children }: EmailLayoutProps) => (
|
const EmailLayout = ({ children }: EmailLayoutProps) => <AdminLayout>{children}</AdminLayout>;
|
||||||
<InstanceWrapper>
|
|
||||||
<AuthWrapper>
|
|
||||||
<AdminLayout>{children}</AdminLayout>
|
|
||||||
</AuthWrapper>
|
|
||||||
</InstanceWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default EmailLayout;
|
export default EmailLayout;
|
||||||
|
@ -5,9 +5,10 @@ import useSWR from "swr";
|
|||||||
import { Loader } from "@plane/ui";
|
import { Loader } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { PageHeader } from "@/components/core";
|
import { PageHeader } from "@/components/core";
|
||||||
import { useInstance } from "@/hooks/store";
|
|
||||||
import { InstanceEmailForm } from "./components";
|
|
||||||
// hooks
|
// hooks
|
||||||
|
import { useInstance } from "@/hooks/store";
|
||||||
|
// components
|
||||||
|
import { InstanceEmailForm } from "./email-config-form";
|
||||||
|
|
||||||
const InstanceEmailPage = observer(() => {
|
const InstanceEmailPage = observer(() => {
|
||||||
// store
|
// store
|
||||||
|
@ -3,7 +3,7 @@ import { Dialog, Transition } from "@headlessui/react";
|
|||||||
// ui
|
// ui
|
||||||
import { Button, Input } from "@plane/ui";
|
import { Button, Input } from "@plane/ui";
|
||||||
// services
|
// services
|
||||||
import { InstanceService } from "services/instance.service";
|
import { InstanceService } from "@/services/instance.service";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
@ -1,14 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { ReactNode } from "react";
|
|
||||||
// layouts
|
|
||||||
import { DefaultLayout } from "@/layouts/default-layout";
|
|
||||||
interface SetupLayoutProps {
|
|
||||||
children: ReactNode;
|
|
||||||
params: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function SetupLayout(props: SetupLayoutProps) {
|
|
||||||
const { children } = props;
|
|
||||||
return <DefaultLayout>{children}</DefaultLayout>;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import { Metadata } from "next";
|
|
||||||
// components
|
|
||||||
import { InstanceSetupForm } from "@/components/instance";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: "Setup - God Mode",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function SetupPage() {
|
|
||||||
return <InstanceSetupForm />;
|
|
||||||
}
|
|
@ -5,3 +5,4 @@ export * from "./copy-field";
|
|||||||
export * from "./password-strength-meter";
|
export * from "./password-strength-meter";
|
||||||
export * from "./banner";
|
export * from "./banner";
|
||||||
export * from "./empty-state";
|
export * from "./empty-state";
|
||||||
|
export * from "./logo-spinner";
|
||||||
|
17
admin/components/common/logo-spinner.tsx
Normal file
17
admin/components/common/logo-spinner.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
// assets
|
||||||
|
import LogoSpinnerDark from "@/public/images/logo-spinner-dark.gif";
|
||||||
|
import LogoSpinnerLight from "@/public/images/logo-spinner-light.gif";
|
||||||
|
|
||||||
|
export const LogoSpinner = () => {
|
||||||
|
const { resolvedTheme } = useTheme();
|
||||||
|
|
||||||
|
const logoSrc = resolvedTheme === "dark" ? LogoSpinnerDark : LogoSpinnerLight;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center">
|
||||||
|
<Image src={logoSrc} alt="logo" className="w-[82px] h-[82px] mr-2" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -3,11 +3,10 @@ import { FC, ReactNode, useEffect } from "react";
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
// ui
|
|
||||||
import { Spinner } from "@plane/ui";
|
|
||||||
// components
|
// components
|
||||||
import { InstanceSidebar } from "@/components/admin-sidebar";
|
import { InstanceSidebar } from "@/components/admin-sidebar";
|
||||||
import { InstanceHeader } from "@/components/auth-header";
|
import { InstanceHeader } from "@/components/auth-header";
|
||||||
|
import { LogoSpinner } from "@/components/common";
|
||||||
import { NewUserPopup } from "@/components/new-user-popup";
|
import { NewUserPopup } from "@/components/new-user-popup";
|
||||||
// hooks
|
// hooks
|
||||||
import { useInstance, useUser } from "@/hooks/store";
|
import { useInstance, useUser } from "@/hooks/store";
|
||||||
@ -39,7 +38,7 @@ export const AdminLayout: FC<TAdminLayout> = observer((props) => {
|
|||||||
if (isUserLoggedIn === undefined) {
|
if (isUserLoggedIn === undefined) {
|
||||||
return (
|
return (
|
||||||
<div className="relative flex h-screen w-full items-center justify-center">
|
<div className="relative flex h-screen w-full items-center justify-center">
|
||||||
<Spinner />
|
<LogoSpinner />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
import { ReactNode, createContext } from "react";
|
import { ReactNode, createContext } from "react";
|
||||||
import { ThemeProvider } from "next-themes";
|
import { ThemeProvider } from "next-themes";
|
||||||
// ui
|
|
||||||
import { AppWrapper } from "@/lib/wrappers";
|
|
||||||
// store
|
// store
|
||||||
import { RootStore } from "@/store/root.store";
|
import { RootStore } from "@/store/root.store";
|
||||||
|
// store initialization
|
||||||
|
import { AppWrapper } from "./app-wrapper";
|
||||||
|
|
||||||
let rootStore = new RootStore();
|
let rootStore = new RootStore();
|
||||||
|
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { FC, ReactNode } from "react";
|
|
||||||
import { observer } from "mobx-react-lite";
|
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import useSWR from "swr";
|
|
||||||
import { Spinner } from "@plane/ui";
|
|
||||||
// hooks
|
|
||||||
import { EAuthenticationPageType } from "@/helpers";
|
|
||||||
import { useInstance, useUser } from "@/hooks/store";
|
|
||||||
// helpers
|
|
||||||
|
|
||||||
export interface IAuthWrapper {
|
|
||||||
children: ReactNode;
|
|
||||||
authType?: EAuthenticationPageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AuthWrapper: FC<IAuthWrapper> = observer((props) => {
|
|
||||||
const router = useRouter();
|
|
||||||
// props
|
|
||||||
const { children, authType = EAuthenticationPageType.AUTHENTICATED } = props;
|
|
||||||
// hooks
|
|
||||||
const { instance } = useInstance();
|
|
||||||
const { isLoading, currentUser, fetchCurrentUser } = useUser();
|
|
||||||
|
|
||||||
const { isLoading: isSWRLoading } = useSWR("CURRENT_USER_DETAILS", () => fetchCurrentUser(), {
|
|
||||||
shouldRetryOnError: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isSWRLoading || isLoading)
|
|
||||||
return (
|
|
||||||
<div className="relative flex h-screen w-full items-center justify-center">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (authType === EAuthenticationPageType.NOT_AUTHENTICATED) {
|
|
||||||
if (currentUser === undefined) return <>{children}</>;
|
|
||||||
else {
|
|
||||||
router.push("/general/");
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authType === EAuthenticationPageType.AUTHENTICATED) {
|
|
||||||
if (currentUser) return <>{children}</>;
|
|
||||||
else {
|
|
||||||
if (instance && instance?.instance?.is_setup_done) {
|
|
||||||
router.push("/");
|
|
||||||
return <></>;
|
|
||||||
} else {
|
|
||||||
router.push("/setup/");
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
});
|
|
@ -1,3 +0,0 @@
|
|||||||
export * from "./app-wrapper";
|
|
||||||
export * from "./instance-wrapper";
|
|
||||||
export * from "./auth-wrapper";
|
|
@ -1,65 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { FC, ReactNode } from "react";
|
|
||||||
import { observer } from "mobx-react-lite";
|
|
||||||
import { redirect, useSearchParams } from "next/navigation";
|
|
||||||
import useSWR from "swr";
|
|
||||||
import { Spinner } from "@plane/ui";
|
|
||||||
// components
|
|
||||||
import { EmptyState } from "@/components/common";
|
|
||||||
import { InstanceNotReady } from "@/components/instance";
|
|
||||||
// helpers
|
|
||||||
import { EInstancePageType } from "@/helpers";
|
|
||||||
// hooks
|
|
||||||
import { useInstance } from "@/hooks/store";
|
|
||||||
// layouts
|
|
||||||
import { DefaultLayout } from "@/layouts/default-layout";
|
|
||||||
|
|
||||||
type TInstanceWrapper = {
|
|
||||||
children: ReactNode;
|
|
||||||
pageType?: EInstancePageType;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const InstanceWrapper: FC<TInstanceWrapper> = observer((props) => {
|
|
||||||
const { children, pageType } = props;
|
|
||||||
const searchparams = useSearchParams();
|
|
||||||
const authEnabled = searchparams.get("auth_enabled") || "1";
|
|
||||||
// hooks
|
|
||||||
const { isLoading, instance, fetchInstanceInfo } = useInstance();
|
|
||||||
|
|
||||||
const { isLoading: isSWRLoading } = useSWR("INSTANCE_INFORMATION", () => fetchInstanceInfo(), {
|
|
||||||
revalidateOnFocus: false,
|
|
||||||
revalidateIfStale: false,
|
|
||||||
revalidateOnReconnect: false,
|
|
||||||
errorRetryCount: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isSWRLoading || isLoading)
|
|
||||||
return (
|
|
||||||
<div className="relative flex h-screen w-full items-center justify-center">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
return (
|
|
||||||
<EmptyState
|
|
||||||
title="Your instance wasn't configured successfully."
|
|
||||||
description="Please try re-installing Plane to fix the problem. If the issue still persists please reach out to support@plane.so."
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance?.instance?.is_setup_done === false && authEnabled === "1")
|
|
||||||
return (
|
|
||||||
<DefaultLayout withoutBackground>
|
|
||||||
<InstanceNotReady />
|
|
||||||
</DefaultLayout>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (instance?.instance?.is_setup_done && pageType === EInstancePageType.PRE_SETUP) redirect("/");
|
|
||||||
|
|
||||||
if (!instance?.instance?.is_setup_done && pageType === EInstancePageType.POST_SETUP) redirect("/setup");
|
|
||||||
|
|
||||||
return <>{children}</>;
|
|
||||||
});
|
|
BIN
admin/public/images/logo-spinner-dark.gif
Normal file
BIN
admin/public/images/logo-spinner-dark.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
admin/public/images/logo-spinner-light.gif
Normal file
BIN
admin/public/images/logo-spinner-light.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Loading…
Reference in New Issue
Block a user