From 06d3cd7e73a3ac76937a492ef7f4f1ffb38e503d Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Mon, 27 Nov 2023 19:41:47 +0530 Subject: [PATCH] refactor: Instance admin setting and UI updates. (#2889) * refactor: shift instance admin restriction content to seperate component. fix: instance components export logic. * style: fix sidebar dropdown `God Mode` icon padding. * style: update profile settings user dropdown menu width. * fix: update input type to `password` for Client Secret and API/ Access Key fields. * style: update loader design for all forms. * fix: typo * style: ui updates. * chore: add show/ hide button for all password fields. --- web/components/instance/ai-form.tsx | 61 +++++++++----- web/components/instance/email-form.tsx | 5 +- web/components/instance/general-form.tsx | 12 +-- .../instance/github-config-form.tsx | 60 +++++++++----- .../instance/google-config-form.tsx | 4 +- web/components/instance/image-config-form.tsx | 57 ++++++++----- web/components/instance/index.ts | 6 ++ .../instance/instance-admin-restriction.tsx | 79 +++++++++++++++++++ web/components/instance/sidebar-dropdown.tsx | 8 +- web/components/instance/sidebar-menu.tsx | 6 +- web/layouts/auth-layout/admin-wrapper.tsx | 76 +----------------- .../settings-layout/profile/sidebar.tsx | 2 +- web/pages/god-mode/ai.tsx | 10 ++- web/pages/god-mode/authorization.tsx | 13 ++- web/pages/god-mode/{mail.tsx => email.tsx} | 16 ++-- web/pages/god-mode/image.tsx | 7 +- web/pages/god-mode/index.tsx | 6 +- 17 files changed, 255 insertions(+), 173 deletions(-) create mode 100644 web/components/instance/instance-admin-restriction.tsx rename web/pages/god-mode/{mail.tsx => email.tsx} (77%) diff --git a/web/components/instance/ai-form.tsx b/web/components/instance/ai-form.tsx index 71c5d8365..d7ff4a81e 100644 --- a/web/components/instance/ai-form.tsx +++ b/web/components/instance/ai-form.tsx @@ -1,4 +1,4 @@ -import { FC } from "react"; +import { FC, useState } from "react"; import { Controller, useForm } from "react-hook-form"; // ui import { Button, Input } from "@plane/ui"; @@ -8,6 +8,8 @@ import { IFormattedInstanceConfiguration } from "types/instance"; import useToast from "hooks/use-toast"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; +// icons +import { Eye, EyeOff } from "lucide-react"; export interface IInstanceAIForm { config: IFormattedInstanceConfiguration; @@ -20,6 +22,8 @@ export interface AIFormValues { export const InstanceAIForm: FC = (props) => { const { config } = props; + // states + const [showPassword, setShowPassword] = useState(false); // store const { instance: instanceStore } = useMobxStore(); // toast @@ -55,7 +59,7 @@ export const InstanceAIForm: FC = (props) => { <>
-

GPT Engine

+

GPT_ENGINE

= (props) => {
-

API Key

- ( - +

API key

+
+ ( + + )} + /> + {showPassword ? ( + + ) : ( + )} - /> +

You will find your API key{" "} = (props) => {

diff --git a/web/components/instance/email-form.tsx b/web/components/instance/email-form.tsx index 794592ba1..da26a015c 100644 --- a/web/components/instance/email-form.tsx +++ b/web/components/instance/email-form.tsx @@ -25,6 +25,7 @@ export interface EmailFormValues { export const InstanceEmailForm: FC = (props) => { const { config } = props; + // states const [showPassword, setShowPassword] = useState(false); // store const { instance: instanceStore } = useMobxStore(); @@ -145,7 +146,7 @@ export const InstanceEmailForm: FC = (props) => { ref={ref} hasError={Boolean(errors.EMAIL_HOST_PASSWORD)} placeholder="Password" - className="rounded-md font-medium w-full" + className="rounded-md font-medium w-full !pr-10" /> )} /> @@ -222,7 +223,7 @@ export const InstanceEmailForm: FC = (props) => {
diff --git a/web/components/instance/general-form.tsx b/web/components/instance/general-form.tsx index 9ee7c2f64..4ba03f6cb 100644 --- a/web/components/instance/general-form.tsx +++ b/web/components/instance/general-form.tsx @@ -15,7 +15,7 @@ export interface IInstanceGeneralForm { export interface GeneralFormValues { instance_name: string; - is_telemetry_enabled: boolean; + // is_telemetry_enabled: boolean; } export const InstanceGeneralForm: FC = (props) => { @@ -32,7 +32,7 @@ export const InstanceGeneralForm: FC = (props) => { } = useForm({ defaultValues: { instance_name: instance.instance_name, - is_telemetry_enabled: instance.is_telemetry_enabled, + // is_telemetry_enabled: instance.is_telemetry_enabled, }, }); @@ -101,7 +101,7 @@ export const InstanceGeneralForm: FC = (props) => {
-
+ {/*
Share anonymous usage instance
@@ -115,11 +115,11 @@ export const InstanceGeneralForm: FC = (props) => { render={({ field: { value, onChange } }) => } />
-
+
*/}
-
diff --git a/web/components/instance/github-config-form.tsx b/web/components/instance/github-config-form.tsx index a58cf19d7..16d0c668e 100644 --- a/web/components/instance/github-config-form.tsx +++ b/web/components/instance/github-config-form.tsx @@ -1,4 +1,4 @@ -import { FC } from "react"; +import { FC, useState } from "react"; import { Controller, useForm } from "react-hook-form"; // ui import { Button, Input } from "@plane/ui"; @@ -9,7 +9,7 @@ import useToast from "hooks/use-toast"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // icons -import { Copy } from "lucide-react"; +import { Copy, Eye, EyeOff } from "lucide-react"; export interface IInstanceGithubConfigForm { config: IFormattedInstanceConfiguration; @@ -22,6 +22,8 @@ export interface GithubConfigFormValues { export const InstanceGithubConfigForm: FC = (props) => { const { config } = props; + // states + const [showPassword, setShowPassword] = useState(false); // store const { instance: instanceStore } = useMobxStore(); // toast @@ -90,24 +92,42 @@ export const InstanceGithubConfigForm: FC = (props) =

-

Client Secret

- ( - +

Client secret

+
+ ( + + )} + /> + {showPassword ? ( + + ) : ( + )} - /> +
+

Your client secret is also found in your{" "} = (props) =

diff --git a/web/components/instance/google-config-form.tsx b/web/components/instance/google-config-form.tsx index 0e0f80316..16b81118e 100644 --- a/web/components/instance/google-config-form.tsx +++ b/web/components/instance/google-config-form.tsx @@ -90,7 +90,7 @@ export const InstanceGoogleConfigForm: FC = (props) =

-

Origin URL

+

JavaScript origin URL

diff --git a/web/components/instance/image-config-form.tsx b/web/components/instance/image-config-form.tsx index c7a875d68..8da483b9e 100644 --- a/web/components/instance/image-config-form.tsx +++ b/web/components/instance/image-config-form.tsx @@ -1,4 +1,4 @@ -import { FC } from "react"; +import { FC, useState } from "react"; import { Controller, useForm } from "react-hook-form"; // ui import { Button, Input } from "@plane/ui"; @@ -8,6 +8,8 @@ import { IFormattedInstanceConfiguration } from "types/instance"; import useToast from "hooks/use-toast"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; +// icons +import { Eye, EyeOff } from "lucide-react"; export interface IInstanceImageConfigForm { config: IFormattedInstanceConfiguration; @@ -19,6 +21,8 @@ export interface ImageConfigFormValues { export const InstanceImageConfigForm: FC = (props) => { const { config } = props; + // states + const [showPassword, setShowPassword] = useState(false); // store const { instance: instanceStore } = useMobxStore(); // toast @@ -54,23 +58,40 @@ export const InstanceImageConfigForm: FC = (props) =>

Access key from your Unsplash account

- ( - +
+ ( + + )} + /> + {showPassword ? ( + + ) : ( + )} - /> +

You will find your access key in your Unsplash developer console.{" "} = (props) =>

diff --git a/web/components/instance/index.ts b/web/components/instance/index.ts index c4840736a..0a8f87052 100644 --- a/web/components/instance/index.ts +++ b/web/components/instance/index.ts @@ -2,3 +2,9 @@ export * from "./help-section"; export * from "./sidebar-menu"; export * from "./sidebar-dropdown"; export * from "./general-form"; +export * from "./ai-form"; +export * from "./email-form"; +export * from "./github-config-form"; +export * from "./google-config-form"; +export * from "./image-config-form"; +export * from "./instance-admin-restriction"; diff --git a/web/components/instance/instance-admin-restriction.tsx b/web/components/instance/instance-admin-restriction.tsx new file mode 100644 index 000000000..76d6e97cd --- /dev/null +++ b/web/components/instance/instance-admin-restriction.tsx @@ -0,0 +1,79 @@ +import { FC } from "react"; +import Link from "next/link"; +import Image from "next/image"; +// images +import AccessDeniedImg from "public/auth/access-denied.svg"; +// ui +import { Button } from "@plane/ui"; +// icons +import { LayoutGrid } from "lucide-react"; + +interface InstanceAdminRestrictionProps { + redirectWorkspaceSlug: string; +} + +export const InstanceAdminRestriction: FC = ({ redirectWorkspaceSlug }) => ( + +); diff --git a/web/components/instance/sidebar-dropdown.tsx b/web/components/instance/sidebar-dropdown.tsx index 9bbdd2a12..383950ef3 100644 --- a/web/components/instance/sidebar-dropdown.tsx +++ b/web/components/instance/sidebar-dropdown.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // components import { Menu, Transition } from "@headlessui/react"; // icons -import { Cog, LogIn, LogOut, Settings } from "lucide-react"; +import { LogIn, LogOut, Settings, UserCog2 } from "lucide-react"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // hooks @@ -64,12 +64,12 @@ export const InstanceSidebarDropdown = observer(() => {
-
- +
+
{!sidebarCollapsed && ( diff --git a/web/components/instance/sidebar-menu.tsx b/web/components/instance/sidebar-menu.tsx index 141555193..ad26480db 100644 --- a/web/components/instance/sidebar-menu.tsx +++ b/web/components/instance/sidebar-menu.tsx @@ -16,9 +16,9 @@ const INSTANCE_ADMIN_LINKS = [ }, { Icon: Mail, - name: "Mail", + name: "Email", description: "Set up emails to your users", - href: `/god-mode/mail`, + href: `/god-mode/email`, }, { Icon: Lock, @@ -28,7 +28,7 @@ const INSTANCE_ADMIN_LINKS = [ }, { Icon: BrainCog, - name: "OpenAI", + name: "Artificial intelligence", description: "Configure your OpenAI creds", href: `/god-mode/ai`, }, diff --git a/web/layouts/auth-layout/admin-wrapper.tsx b/web/layouts/auth-layout/admin-wrapper.tsx index 0311afb93..39934ca66 100644 --- a/web/layouts/auth-layout/admin-wrapper.tsx +++ b/web/layouts/auth-layout/admin-wrapper.tsx @@ -1,15 +1,9 @@ import { FC, ReactNode } from "react"; -import Link from "next/link"; -import Image from "next/image"; import { observer } from "mobx-react-lite"; -// icons -import { LayoutGrid } from "lucide-react"; -// ui -import { Button } from "@plane/ui"; // hooks import { useMobxStore } from "lib/mobx/store-provider"; -// images -import AccessDeniedImg from "public/auth/access-denied.svg"; +// components +import { InstanceAdminRestriction } from "components/instance"; export interface IAdminAuthWrapper { children: ReactNode; @@ -32,71 +26,7 @@ export const AdminAuthWrapper: FC = observer(({ children }) = // if user does not have admin access to the instance if (isUserInstanceAdmin !== undefined && isUserInstanceAdmin === false) { - return ( -
-
-
-
- AccessDeniedImg -

God mode needs a god role

-

Doesn’t look like you have that role.

-
-
-
-

Do we have a god role?

-

Yes.

-
-
-

Do we call it god role?

-

No. Obviously not.

-
-
-

Can you get it?

-

Maybe. Ask your god.

-
-
-

- Are we being intentionally cryptic? -

-

Yes.

-
-
-

- Is this for the security of your workspaces? -

-

Absolutely!

-
-
-

- Are you the god here and still seeing this? -

-

- Sorry, God.{" "} - - Talk to us. - -

-
-
-
-
- -
- ); + return ; } return <>{children}; diff --git a/web/layouts/settings-layout/profile/sidebar.tsx b/web/layouts/settings-layout/profile/sidebar.tsx index 9a133a994..712ee06b8 100644 --- a/web/layouts/settings-layout/profile/sidebar.tsx +++ b/web/layouts/settings-layout/profile/sidebar.tsx @@ -119,7 +119,7 @@ export const ProfileLayoutSidebar = observer(() => { leaveFrom="transform opacity-100 scale-100" leaveTo="transform opacity-0 scale-95" > - + {currentUser?.email} { // store @@ -46,9 +46,11 @@ const InstanceAdminAIPage: NextPageWithLayout = observer(() => { ) : ( - - - +
+ + +
+
)}
diff --git a/web/pages/god-mode/authorization.tsx b/web/pages/god-mode/authorization.tsx index c36c96140..08a58d505 100644 --- a/web/pages/god-mode/authorization.tsx +++ b/web/pages/god-mode/authorization.tsx @@ -13,8 +13,7 @@ import useToast from "hooks/use-toast"; // ui import { Loader, ToggleSwitch } from "@plane/ui"; // components -import { InstanceGoogleConfigForm } from "components/instance/google-config-form"; -import { InstanceGithubConfigForm } from "components/instance/github-config-form"; +import { InstanceGithubConfigForm, InstanceGoogleConfigForm } from "components/instance"; const InstanceAdminAuthorizationPage: NextPageWithLayout = observer(() => { // store @@ -168,13 +167,11 @@ const InstanceAdminAuthorizationPage: NextPageWithLayout = observer(() => { ) : ( - - - +
+ + +
- - -
)}
diff --git a/web/pages/god-mode/mail.tsx b/web/pages/god-mode/email.tsx similarity index 77% rename from web/pages/god-mode/mail.tsx rename to web/pages/god-mode/email.tsx index 0c28f2294..cc295f1d7 100644 --- a/web/pages/god-mode/mail.tsx +++ b/web/pages/god-mode/email.tsx @@ -10,9 +10,9 @@ import { useMobxStore } from "lib/mobx/store-provider"; // ui import { Loader } from "@plane/ui"; // components -import { InstanceEmailForm } from "components/instance/email-form"; +import { InstanceEmailForm } from "components/instance"; -const InstanceAdminMailPage: NextPageWithLayout = observer(() => { +const InstanceAdminEmailPage: NextPageWithLayout = observer(() => { // store const { instance: { fetchInstanceConfigurations, formattedConfig }, @@ -36,19 +36,19 @@ const InstanceAdminMailPage: NextPageWithLayout = observer(() => { ) : ( +
+ + +
- - - -
)}
); }); -InstanceAdminMailPage.getLayout = function getLayout(page: ReactElement) { +InstanceAdminEmailPage.getLayout = function getLayout(page: ReactElement) { return {page}; }; -export default InstanceAdminMailPage; +export default InstanceAdminEmailPage; diff --git a/web/pages/god-mode/image.tsx b/web/pages/god-mode/image.tsx index dbcfe20e8..e9a1572e8 100644 --- a/web/pages/god-mode/image.tsx +++ b/web/pages/god-mode/image.tsx @@ -10,7 +10,7 @@ import { useMobxStore } from "lib/mobx/store-provider"; // ui import { Loader } from "@plane/ui"; // components -import { InstanceImageConfigForm } from "components/instance/image-config-form"; +import { InstanceImageConfigForm } from "components/instance"; const InstanceAdminImagePage: NextPageWithLayout = observer(() => { // store @@ -32,8 +32,11 @@ const InstanceAdminImagePage: NextPageWithLayout = observer(() => { ) : ( +
+ + +
-
)}
diff --git a/web/pages/god-mode/index.tsx b/web/pages/god-mode/index.tsx index a42b56c54..9ae2bcc54 100644 --- a/web/pages/god-mode/index.tsx +++ b/web/pages/god-mode/index.tsx @@ -34,9 +34,11 @@ const InstanceAdminPage: NextPageWithLayout = observer(() => { ) : ( +
+ + +
- -
)}