From c96d83bc08c2c43f8354ffcc9a5fa4ea0492637f Mon Sep 17 00:00:00 2001 From: Yousif Yassi Date: Mon, 2 Dec 2024 13:13:18 -0500 Subject: [PATCH 01/13] feat: OPTIC-1359: Account Settings page moved to React --- .../users/templates/users/user_account.html | 372 ------------------ web/apps/labelstudio/src/app/App.jsx | 2 + .../labelstudio/src/assets/icons/index.js | 1 + .../labelstudio/src/assets/icons/launch.svg | 3 + .../src/components/Menubar/Menubar.jsx | 5 +- .../AccountSettings/AccountSettings.scss | 11 + .../pages/AccountSettings/AccountSettings.tsx | 49 +++ .../sections/EmailPreferences.jsx | 14 + .../sections/MembershipInfo.jsx | 57 +++ .../sections/PersonalAccessToken.jsx | 29 ++ .../AccountSettings/sections/PersonalInfo.jsx | 28 ++ .../pages/AccountSettings/sections/index.jsx | 32 ++ web/apps/labelstudio/src/pages/index.js | 3 +- .../src/providers/CurrentUser.d.ts | 1 + 14 files changed, 232 insertions(+), 375 deletions(-) create mode 100644 web/apps/labelstudio/src/assets/icons/launch.svg create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.scss create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.tsx create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/sections/EmailPreferences.jsx create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/sections/MembershipInfo.jsx create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/sections/PersonalAccessToken.jsx create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/sections/PersonalInfo.jsx create mode 100644 web/apps/labelstudio/src/pages/AccountSettings/sections/index.jsx diff --git a/label_studio/users/templates/users/user_account.html b/label_studio/users/templates/users/user_account.html index c20eca96f139..e533221d6ddb 100644 --- a/label_studio/users/templates/users/user_account.html +++ b/label_studio/users/templates/users/user_account.html @@ -1,374 +1,2 @@ {% extends 'base.html' %} {% load static %} - -{% block head %} - - -{% endblock %} - -{% block divider %} -{% endblock %} - -{% block frontend_settings %} - { - breadcrumbs: [ - { - title: "Account & Settings" - } - ], - } -{% endblock %} - -{% block content %} - - -
- - - -
- -{% endblock %} diff --git a/web/apps/labelstudio/src/app/App.jsx b/web/apps/labelstudio/src/app/App.jsx index c5581b515447..89823367aca6 100644 --- a/web/apps/labelstudio/src/app/App.jsx +++ b/web/apps/labelstudio/src/app/App.jsx @@ -18,6 +18,7 @@ import ErrorBoundary from "./ErrorBoundary"; import { RootPage } from "./RootPage"; import { FF_OPTIC_2, FF_UNSAVED_CHANGES, isFF } from "../utils/feature-flags"; import { ToastProvider, ToastViewport } from "@humansignal/ui"; +import { CurrentUserProvider } from "../providers/CurrentUser"; const baseURL = new URL(APP_SETTINGS.hostname || location.origin); export const UNBLOCK_HISTORY_MESSAGE = "UNBLOCK_HISTORY"; @@ -61,6 +62,7 @@ const App = ({ content }) => { , , , + , ]} > diff --git a/web/apps/labelstudio/src/assets/icons/index.js b/web/apps/labelstudio/src/assets/icons/index.js index b8755e330d33..762572f0f0e2 100644 --- a/web/apps/labelstudio/src/assets/icons/index.js +++ b/web/apps/labelstudio/src/assets/icons/index.js @@ -29,5 +29,6 @@ export { ReactComponent as IconSparkGrey } from "./spark-grey.svg"; export { ReactComponent as IconPredictions } from "./predictions.svg"; export { ReactComponent as IconEmptyPredictions } from "./empty-predictions.svg"; export { ReactComponent as IconSpark } from "./spark.svg"; +export { ReactComponent as IconLaunch } from "./launch.svg"; export { ReactComponent as IconModel } from "./model.svg"; export { ReactComponent as IconModels } from "./models.svg"; diff --git a/web/apps/labelstudio/src/assets/icons/launch.svg b/web/apps/labelstudio/src/assets/icons/launch.svg new file mode 100644 index 000000000000..c48173687ac9 --- /dev/null +++ b/web/apps/labelstudio/src/assets/icons/launch.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/apps/labelstudio/src/components/Menubar/Menubar.jsx b/web/apps/labelstudio/src/components/Menubar/Menubar.jsx index 7f13680a47fe..955dc58849a8 100644 --- a/web/apps/labelstudio/src/components/Menubar/Menubar.jsx +++ b/web/apps/labelstudio/src/components/Menubar/Menubar.jsx @@ -27,6 +27,7 @@ import "./MenuContent.scss"; import "./MenuSidebar.scss"; import { ModelsPage } from "../../pages/Organization/Models/ModelsPage"; import { FF_DIA_835, isFF } from "../../utils/feature-flags"; +import { AccountSettingsPage } from "../../pages/AccountSettings/AccountSettings"; export const MenubarContext = createContext(); @@ -148,13 +149,13 @@ export const Menubar = ({ enabled, defaultOpened, defaultPinned, children, onSid align="right" content={ - } label="Account & Settings" href="/user/account" data-external /> + } label="Account & Settings" href={AccountSettingsPage.path} /> {/* */} } label="Log Out" href={absoluteURL("/logout")} data-external /> {showNewsletterDot && ( <> - + Please check new notification settings in the Account & Settings page diff --git a/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.scss b/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.scss new file mode 100644 index 000000000000..1697c3ec4174 --- /dev/null +++ b/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.scss @@ -0,0 +1,11 @@ +.datamanager { + height: calc(100vh - var(--header-height)); + + #label-studio-dm [class*="Annotations_annotation_selected"] { + background: var(--grape_0); + } +} + +.datamanager * { + font-family: var(--font-sans) !important; +} diff --git a/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.tsx b/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.tsx new file mode 100644 index 000000000000..bc59800e0d86 --- /dev/null +++ b/web/apps/labelstudio/src/pages/AccountSettings/AccountSettings.tsx @@ -0,0 +1,49 @@ +import React, { useMemo, useState } from "react"; +import { Redirect } from "react-router-dom"; +import { useAPI } from "../../providers/ApiProvider"; +import { SidebarMenu } from "../../components/SidebarMenu/SidebarMenu"; +import "./AccountSettings.scss"; +import { useCurrentUser } from "../../providers/CurrentUser"; +import { accountSettingsSections } from "./sections"; + +export const AccountSettingsPage = () => { + const api = useAPI(); + const { user } = useCurrentUser(); + // const abortController = useAbortController(); + + console.log("user", api, user, accountSettingsSections); + + return ( +
+ + {accountSettingsSections?.map(({component: Section, id}: any) => ( +
+ ))} +
+ ); +}; + + +const MenuLayout = ({ children, ...routeProps }: { children: any, routeProps: any}) => { + const menuItems = useMemo(() => accountSettingsSections.map(({title, id}) => ({title, path: `#${id}`})), [accountSettingsSections]); + + return ; +}; + +AccountSettingsPage.title = "My Account"; +AccountSettingsPage.path = "/user/account"; +AccountSettingsPage.exact = true; +AccountSettingsPage.routes = () => [ + { + title: () => 'My Account', + exact: true, + component: () => { + return ; + }, + layout: MenuLayout, + // pages: { + // DataManagerPage, + // SettingsPage, + // }, + }, +]; diff --git a/web/apps/labelstudio/src/pages/AccountSettings/sections/EmailPreferences.jsx b/web/apps/labelstudio/src/pages/AccountSettings/sections/EmailPreferences.jsx new file mode 100644 index 000000000000..8c6d5c6c59a3 --- /dev/null +++ b/web/apps/labelstudio/src/pages/AccountSettings/sections/EmailPreferences.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import { Checkbox } from "@humansignal/ui"; + +export const EmailPreferences = () => { + return ( + <> + +
+

Email Preferences

+ +
+ + ); +}; \ No newline at end of file diff --git a/web/apps/labelstudio/src/pages/AccountSettings/sections/MembershipInfo.jsx b/web/apps/labelstudio/src/pages/AccountSettings/sections/MembershipInfo.jsx new file mode 100644 index 000000000000..d73e071e4edf --- /dev/null +++ b/web/apps/labelstudio/src/pages/AccountSettings/sections/MembershipInfo.jsx @@ -0,0 +1,57 @@ +import React from "react"; +import { Divider } from "../../../components/Divider/Divider"; +export const MembershipInfo = () => { + return ( + <> +
+
+

Membership Info

+
+
User ID
+
+
+ +
+
Registration date
+
+
+ +
+
Annotations submitted
+
+
+ +
+
Projects contributed to
+
+
+ + +
+
Organization
+
+
+ +
+
My role
+
+
+ +
+
Organization ID
+
+
+ +
+
Owner
+
+
+ +
+
Created
+
+
+
+ + ) +}; \ No newline at end of file diff --git a/web/apps/labelstudio/src/pages/AccountSettings/sections/PersonalAccessToken.jsx b/web/apps/labelstudio/src/pages/AccountSettings/sections/PersonalAccessToken.jsx new file mode 100644 index 000000000000..d329d11f187e --- /dev/null +++ b/web/apps/labelstudio/src/pages/AccountSettings/sections/PersonalAccessToken.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Input, TextArea } from '../../../components/Form'; +import { Button } from '../../../components/Button/Button'; +import { IconLaunch } from 'apps/labelstudio/src/assets/icons'; + +export const PersonalAccessToken = () => { + return ( + <> + +
+
+

Personal Access Token

+

Authenticate with our API using your personal access token. + {!APP_SETTINGS?.whitelabel_is_active && ( + <>See Docs + )} +

+
+ + +
+
+