From d8a535432d9703eb3e4037b2b9bb483aff2c44e4 Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Wed, 27 Sep 2023 14:00:11 +0300 Subject: [PATCH] Web:Client:PortalSettings:OAuth: add table view --- .../developer-tools/OAuth/OAuth.types.ts | 13 +- .../OAuth/OAuthSectionHeader/index.tsx | 6 +- .../developer-tools/OAuth/StyledOAuth.ts | 22 -- .../developer-tools/OAuth/index.tsx | 54 ++++- .../OAuth/sub-components/Category.js | 59 ----- .../ClientForm/ClientForm.types.ts | 14 +- .../ClientForm/components/Block.tsx | 2 - .../ClientForm/components/BlockHeader.tsx | 2 - .../ClientForm/components/Checkbox.tsx | 2 - .../ClientForm/components/Input.tsx | 5 +- .../ClientForm/components/InputHeader.tsx | 2 - .../OAuth/sub-components/ClientForm/index.tsx | 151 +++++++------ .../sub-components/EmptyScreen/index.tsx | 2 - .../sub-components/List/TableView/Header.js | 116 ---------- .../sub-components/List/TableView/Header.tsx | 68 ++++++ .../sub-components/List/TableView/Row.js | 148 ------------- .../sub-components/List/TableView/Row.tsx | 195 ++++++++++++++++ .../List/TableView/columns/name.tsx | 88 ++++++++ .../sub-components/List/TableView/index.js | 116 ---------- .../sub-components/List/TableView/index.tsx | 140 ++++++++++++ .../OAuth/sub-components/List/index.js | 30 --- .../OAuth/sub-components/List/index.tsx | 94 ++++++++ .../RegisterNewButton/index.tsx | 1 - packages/client/src/store/OAuthStore.ts | 209 ++++++++++++++---- packages/common/api/oauth/index.ts | 52 +++-- packages/common/utils/oauth/enums.ts | 10 - packages/common/utils/oauth/index.ts | 36 +-- .../utils/oauth/{dto.ts => interfaces.ts} | 73 ++++-- packages/components/input-block/index.js | 5 +- 29 files changed, 1024 insertions(+), 691 deletions(-) delete mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/Category.js delete mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.js create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.tsx delete mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.js create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.tsx create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/columns/name.tsx delete mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.js create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.tsx delete mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.js create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.tsx rename packages/common/utils/oauth/{dto.ts => interfaces.ts} (76%) diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuth.types.ts b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuth.types.ts index cffe73e672..e1f640dcb8 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuth.types.ts +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuth.types.ts @@ -1,3 +1,12 @@ -export interface OAuthProps {} +//@ts-ignore +import { ClientProps } from "@docspace/common/utils/oauth/dto"; -export interface OAuthStore {} +//@ts-ignore +import { ViewAsType } from "SRC_DIR/store/OAuthStore"; + +export interface OAuthProps { + viewAs: ViewAsType; + clientList: ClientProps[]; + isEmptyClientList: boolean; + fetchClients: (page: number) => Promise; +} diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuthSectionHeader/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuthSectionHeader/index.tsx index ceda731b0f..d8b655f0ab 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuthSectionHeader/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/OAuthSectionHeader/index.tsx @@ -1,6 +1,4 @@ -import React from "react"; import { useNavigate } from "react-router-dom"; -import { inject, observer } from "mobx-react"; import { useTranslation } from "react-i18next"; // @ts-ignore @@ -44,6 +42,4 @@ const OAuthSectionHeader = ({ isEdit }: OAuthSectionHeaderProps) => { ); }; -export default inject(({}) => { - return {}; -})(observer(OAuthSectionHeader)); +export default OAuthSectionHeader; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/StyledOAuth.ts b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/StyledOAuth.ts index ba191dc238..d0ba4b31ba 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/StyledOAuth.ts +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/StyledOAuth.ts @@ -4,25 +4,3 @@ export const OAuthContainer = styled.div` width: 100%; margin-top: 5px; `; - -export const Property = styled.div` - display: flex; - align-items: center; - gap: 16px; - margin-bottom: 16px; - width: 500px; -`; - -export const StyledCategory = styled.div` - display: flex; - flex-direction: row; - gap: 4px; - margin-bottom: 16px; - align-items: center; -`; - -export const StyledTooltip = styled.div` - .subtitle { - margin-bottom: 10px; - } -`; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/index.tsx index 1e710f1dc6..ea8bfb3162 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/index.tsx @@ -2,20 +2,66 @@ import React from "react"; import { inject, observer } from "mobx-react"; import { useTranslation } from "react-i18next"; +//@ts-ignore +import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore"; + import OAuthEmptyScreen from "./sub-components/EmptyScreen"; +import List from "./sub-components/List"; import { OAuthContainer } from "./StyledOAuth"; +import { OAuthProps } from "./OAuth.types"; -const OAuth = ({}) => { +const MIN_LOADER_TIME = 500; + +const OAuth = ({ + clientList, + viewAs, + isEmptyClientList, + fetchClients, +}: OAuthProps) => { const { t } = useTranslation(["OAuth"]); + const [isLoading, setIsLoading] = React.useState(true); + const startLoadingRef = React.useRef(null); + + const getClientList = React.useCallback(async (page = 0) => { + await fetchClients(page); + + if (startLoadingRef.current) { + const currentDate = new Date(); + + const ms = Math.abs( + startLoadingRef.current.getTime() - currentDate.getTime() + ); + + if (ms < MIN_LOADER_TIME) + return setTimeout(() => { + setIsLoading(false); + }, MIN_LOADER_TIME - ms); + } + + setIsLoading(false); + }, []); + + React.useEffect(() => { + startLoadingRef.current = new Date(); + getClientList(); + }, [getClientList]); + return ( - + {isLoading ? ( +
Loading...
+ ) : isEmptyClientList ? ( + + ) : ( + + )}
); }; -export default inject(({}) => { - return {}; +export default inject(({ oauthStore }: { oauthStore: OAuthStoreProps }) => { + const { viewAs, clientList, isEmptyClientList, fetchClients } = oauthStore; + return { viewAs, clientList, isEmptyClientList, fetchClients }; })(observer(OAuth)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/Category.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/Category.js deleted file mode 100644 index 2a0bf69f4f..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/Category.js +++ /dev/null @@ -1,59 +0,0 @@ -import InfoReactSvgUrl from "PUBLIC_DIR/images/info.react.svg?url"; -import React from "react"; -import Text from "@docspace/components/text"; -import HelpButton from "@docspace/components/help-button"; -import Link from "@docspace/components/link"; -import { Base } from "@docspace/components/themes"; -import { StyledCategory, StyledTooltip } from "../StyledOAuth"; - -const Category = (props) => { - const { - t, - title, - tooltipTitle, - tooltipUrl, - theme, - currentColorScheme, - } = props; - - const tooltip = () => ( - - - {tooltipTitle} - - {tooltipUrl && ( - - {t("Common:LearnMore")} - - )} - - ); - - return ( - - - {title} - - - - ); -}; - -Category.defaultProps = { - theme: Base, -}; - -export default Category; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/ClientForm.types.ts b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/ClientForm.types.ts index 258a745cf1..dc8bed767e 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/ClientForm.types.ts +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/ClientForm.types.ts @@ -1,4 +1,4 @@ -import { ClientProps, ScopeDTO } from "@docspace/common/utils/oauth/dto"; +import { ClientProps, Scope } from "@docspace/common/utils/oauth/interfaces"; export interface InputProps { value: string; @@ -38,13 +38,19 @@ export interface ClientFormProps { id?: string; client?: ClientProps; - scopeList?: ScopeDTO[]; + tenant?: number; + fetchTenant?: () => Promise; + + scopeList?: Scope[]; fetchClient?: (clientId: string) => Promise; fetchScopes?: () => Promise; - saveClient: (client: ClientProps) => Promise; - updateClient: (clientId: string, client: ClientProps) => Promise; + saveClient?: (client: ClientProps) => Promise; + updateClient?: ( + clientId: string, + client: ClientProps + ) => Promise; regenerateSecret?: (clientId: string) => Promise; } diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Block.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Block.tsx index 99357a3501..e6a8548f0d 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Block.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Block.tsx @@ -1,5 +1,3 @@ -import React from "react"; - import { BlockContainer } from "../ClientForm.styled"; import { BlockProps } from "../ClientForm.types"; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/BlockHeader.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/BlockHeader.tsx index ba445548f3..5b57324245 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/BlockHeader.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/BlockHeader.tsx @@ -1,5 +1,3 @@ -import React from "react"; - import Text from "@docspace/components/text"; //@ts-ignore import HelpButton from "@docspace/components/help-button"; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Checkbox.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Checkbox.tsx index 1a94820367..78c107de42 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Checkbox.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Checkbox.tsx @@ -1,5 +1,3 @@ -import React from "react"; - import Checkbox from "@docspace/components/checkbox"; import Text from "@docspace/components/text"; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Input.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Input.tsx index 22b91f9fba..51c597f0d0 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Input.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/Input.tsx @@ -1,4 +1,3 @@ -import React from "react"; import copy from "copy-to-clipboard"; import InputBlock from "@docspace/components/input-block"; @@ -45,8 +44,8 @@ const Input = ({ size={"base"} isReadOnly={isReadOnly} isDisabled={isReadOnly} - iconName={withCopy ? CopyReactSvgUrl : ""} - onIconClick={onCopy} + iconName={withCopy ? CopyReactSvgUrl : null} + onIconClick={withCopy && onCopy} scale={true} type={isSecret ? "password" : "text"} /> diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/InputHeader.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/InputHeader.tsx index 0ecfeb64e7..0f6d9a66a1 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/InputHeader.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/components/InputHeader.tsx @@ -1,5 +1,3 @@ -import React from "react"; - import Text from "@docspace/components/text"; const InputHeader = ({ header }: { header: string }) => { diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/index.tsx index 23ff33dcdd..3b8227616e 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/ClientForm/index.tsx @@ -3,7 +3,7 @@ import { inject, observer } from "mobx-react"; import { useNavigate } from "react-router-dom"; import { isMobileOnly } from "react-device-detect"; -import { ClientProps, ScopeDTO } from "@docspace/common/utils/oauth/dto"; +import { ClientProps, Scope } from "@docspace/common/utils/oauth/interfaces"; import Button from "@docspace/components/button"; @@ -27,6 +27,9 @@ const ClientForm = ({ scopeList, + tenant, + fetchTenant, + fetchClient, fetchScopes, @@ -45,20 +48,19 @@ const ClientForm = ({ appName: "", appIcon: "", description: "", + redirectUrl: "", + termsURL: "", + privacyURL: "", logoutRedirectUrl: "", - privacyURL: "", + authenticationMethod: "", }); - const [clientId, setClientId] = React.useState( - "23b2ec16-6a10-462b-8084-16be8e105b73" - ); - const [secret, setSecret] = React.useState( - "d2c083aa-9a2d-4147-9328-df32b7be0294" - ); + const [clientId, setClientId] = React.useState(""); + const [secret, setSecret] = React.useState(""); - const [scopes, setScopes] = React.useState([]); + const [scopes, setScopes] = React.useState([]); const [checkedScopes, setCheckedScopes] = React.useState([]); const onInputChange = React.useCallback( @@ -101,8 +103,17 @@ const ClientForm = ({ newClient.scopes = [...checkedScopes]; if (!id) { + if (!saveClient) return; + + if (tenant === -1 && fetchTenant) { + const t = await fetchTenant(); + + newClient.tenant = t; + } + await saveClient(newClient); } else { + if (!updateClient) return; await updateClient(clientId, newClient); } @@ -137,11 +148,15 @@ const ClientForm = ({ const setClient = React.useCallback(async (client: ClientProps) => { setForm({ appName: client.name, - appIcon: client.logoUrl, + appIcon: client.logoUrl || "", description: client.description, + redirectUrl: client.redirectUri, - logoutRedirectUrl: client.logoutRedirectUri, privacyURL: client.policyUrl, + termsUrl: client.termsUrl, + logoutRedirectUrl: client.logoutRedirectUri, + + authenticationMethod: client.authenticationMethod, }); setSecret(client.secret); @@ -178,7 +193,7 @@ const ClientForm = ({ let isValid = false; for (let key in form) { - if (!!form[key]) { + if (!!form[key] || key === "appIcon" || key === "authenticationMethod") { if (initClient) { switch (key) { case "appName": @@ -186,7 +201,7 @@ const ClientForm = ({ break; case "appIcon": - isValid = isValid || initClient.logoUrl !== form[key]; + isValid = isValid || initClient.name !== form[key]; break; case "description": @@ -204,6 +219,11 @@ const ClientForm = ({ case "privacyUrl": isValid = isValid || initClient.policyUrl !== form[key]; + break; + + case "termsUrl": + isValid = isValid || initClient.termsUrl !== form[key]; + break; } } @@ -266,35 +286,49 @@ const ClientForm = ({ - - - - - - - - - - - + {id && ( + + + + + + + + + + + + + + + + + )} @@ -316,15 +350,6 @@ const ClientForm = ({ onChange={onInputChange} /> - {/* - - - */} @@ -345,15 +370,7 @@ const ClientForm = ({ - {/* - - - */} + - {/* + - */} +
@@ -408,6 +425,9 @@ export default inject( fetchClient, fetchScopes, + tenant, + fetchTenant, + saveClient, updateClient, @@ -420,6 +440,9 @@ export default inject( fetchClient, fetchScopes, + tenant, + fetchTenant, + saveClient, updateClient, diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/EmptyScreen/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/EmptyScreen/index.tsx index 9f239763b4..56d563f34d 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/EmptyScreen/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/EmptyScreen/index.tsx @@ -1,5 +1,3 @@ -import React from "react"; - // @ts-ignore import EmptyScreenContainer from "@docspace/components/empty-screen-container"; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.js deleted file mode 100644 index efaff96bd2..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.js +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useState } from "react"; -import TableHeader from "@docspace/components/table-container/TableHeader"; - -import { useTranslation } from "react-i18next"; -import { inject, observer } from "mobx-react"; - -const TABLE_VERSION = "1"; -const TABLE_COLUMNS = `oauthConfigColumns_ver-${TABLE_VERSION}`; - -const getColumns = (defaultColumns, userId) => { - const storageColumns = localStorage.getItem(`${TABLE_COLUMNS}=${userId}`); - const columns = []; - - if (storageColumns) { - const splitColumns = storageColumns.split(","); - - for (let col of defaultColumns) { - const column = splitColumns.find((key) => key === col.key); - column ? (col.enable = true) : (col.enable = false); - - columns.push(col); - } - return columns; - } else { - return defaultColumns; - } -}; - -const Header = (props) => { - const { - userId, - sectionWidth, - tableRef, - columnStorageName, - columnInfoPanelStorageName, - setHideColumns, - } = props; - const { t } = useTranslation(["Webhooks", "Common"]); - - const defaultColumns = [ - { - key: "Logo", - title: "Logo", - enable: true, - active: true, - resizable: false, - defaultSize: 64, - onChange: onColumnChange, - }, - { - key: "Name", - title: t("Common:Name"), - resizable: true, - enable: true, - default: true, - active: true, - minWidth: 150, - onChange: onColumnChange, - }, - { - key: "Description", - title: "Description", - resizable: true, - enable: true, - minWidth: 150, - onChange: onColumnChange, - }, - { - key: "Enable", - title: "Enable", - enable: true, - resizable: false, - defaultSize: 64, - onChange: onColumnChange, - }, - ]; - - const [columns, setColumns] = useState(getColumns(defaultColumns, userId)); - - function onColumnChange(key, e) { - const columnIndex = columns.findIndex((c) => c.key === key); - - if (columnIndex === -1) return; - - setColumns((prevColumns) => - prevColumns.map((item, index) => - index === columnIndex ? { ...item, enabled: !item.enabled } : item - ) - ); - - const tableColumns = columns.map((c) => c.enabled && c.key); - localStorage.setItem(`${TABLE_COLUMNS}=${userId}`, tableColumns); - } - - return ( - - ); -}; - -export default inject(({ auth }) => { - return { - userId: auth.userStore.user.id, - }; -})(observer(Header)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.tsx new file mode 100644 index 0000000000..d66f945eee --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Header.tsx @@ -0,0 +1,68 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { inject, observer } from "mobx-react"; + +//@ts-ignore +import TableHeader from "@docspace/components/table-container/TableHeader"; + +const TABLE_VERSION = "1"; +const TABLE_COLUMNS = `oauthConfigColumns_ver-${TABLE_VERSION}`; + +interface HeaderProps { + sectionWidth: number; + tableRef: HTMLDivElement; + columnStorageName: string; +} + +const Header = (props: HeaderProps) => { + const { sectionWidth, tableRef, columnStorageName } = props; + const { t } = useTranslation(["Webhooks", "Common"]); + + const defaultColumns: { + [key: string]: + | string + | number + | boolean + | ((key: string, e: any) => void | undefined); + }[] = [ + { + key: "Name", + title: t("Common:Name"), + resizable: true, + enable: true, + default: true, + active: false, + minWidth: 210, + }, + { + key: "Description", + title: "Description", + resizable: true, + enable: true, + minWidth: 150, + }, + { + key: "Enable", + title: "Enable", + enable: true, + resizable: false, + defaultSize: 64, + }, + ]; + + return ( + + ); +}; + +export default Header; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.js deleted file mode 100644 index 0565cfb206..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.js +++ /dev/null @@ -1,148 +0,0 @@ -import React, { useState } from "react"; -import styled from "styled-components"; -import TableRow from "@docspace/components/table-container/TableRow"; -import TableCell from "@docspace/components/table-container/TableCell"; -import Text from "@docspace/components/text"; - -import ToggleButton from "@docspace/components/toggle-button"; -import SettingsIcon from "PUBLIC_DIR/images/catalog.settings.react.svg?url"; -import HistoryIcon from "PUBLIC_DIR/images/history.react.svg?url"; -import DeleteIcon from "PUBLIC_DIR/images/delete.react.svg?url"; -import LinuxIcon from "PUBLIC_DIR/images/linux.react.svg?url"; -//import StatusBadge from "../../StatusBadge"; - -import { useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; - -import { inject, observer } from "mobx-react"; - -const StyledWrapper = styled.div` - display: contents; -`; - -const StyledTableRow = styled(TableRow)` - .table-container_cell { - padding-right: 30px; - text-overflow: ellipsis; - } - - .mr-8 { - margin-right: 8px; - } - - .textOverflow { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .toggleButton { - display: contents; - } -`; - -const Row = (props) => { - const { - item, - setEnabled, - openDeleteModal, - setCurrentClient, - hideColumns, - } = props; - const navigate = useNavigate(); - - const { t } = useTranslation(["Webhooks", "Common"]); - - const [isChecked, setIsChecked] = useState(item.enabled); - - const openClientSettings = () => { - navigate(window.location.pathname + `/${item.id}`); - }; - - const handleToggleEnabled = () => { - setEnabled(item.id); - setIsChecked((prevIsChecked) => !prevIsChecked); - }; - - const onSettingsOpen = () => { - setCurrentClient(item); - openClientSettings(); - }; - - const onDeleteOpen = () => { - setCurrentClient(item); - openDeleteModal(); - }; - - const handleRowClick = (e) => { - if ( - e.target.closest(".checkbox") || - e.target.closest(".table-container_row-checkbox") || - e.target.closest(".type-combobox") || - e.target.closest(".table-container_row-context-menu-wrapper") || - e.target.closest(".toggleButton") || - e.detail === 0 - ) { - return; - } - - onSettingsOpen(); - }; - - const contextOptions = [ - { - key: "settings", - label: t("Common:Settings"), - icon: SettingsIcon, - onClick: onSettingsOpen, - }, - { - key: "Separator dropdownItem", - isSeparator: true, - }, - { - key: "delete", - label: t("Common:Delete"), - icon: DeleteIcon, - onClick: onDeleteOpen, - }, - ]; - - return ( - <> - - - - - - - - {item.name} - - - - - {item.description} - - - - - - - - - ); -}; - -export default inject(({ oauthStore }) => { - const { setCurrentClient, setEnabled } = oauthStore; - - return { setEnabled, setCurrentClient }; -})(observer(Row)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.tsx new file mode 100644 index 0000000000..64803a870f --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/Row.tsx @@ -0,0 +1,195 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import styled, { css } from "styled-components"; + +//@ts-ignore +import TableRow from "@docspace/components/table-container/TableRow"; + +//@ts-ignore +import TableCell from "@docspace/components/table-container/TableCell"; +import Text from "@docspace/components/text"; +import ToggleButton from "@docspace/components/toggle-button"; +import { Base } from "@docspace/components/themes"; + +import SettingsIcon from "PUBLIC_DIR/images/catalog.settings.react.svg?url"; +import DeleteIcon from "PUBLIC_DIR/images/delete.react.svg?url"; + +import { ClientProps } from "@docspace/common/utils/oauth/interfaces"; + +import NameCell from "./columns/name"; + +const StyledWrapper = styled.div` + display: contents; +`; + +const StyledTableRow = styled(TableRow)` + .table-container_cell { + text-overflow: ellipsis; + + padding-right: 8px; + } + + .mr-8 { + margin-right: 8px; + } + + .textOverflow { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .toggleButton { + display: contents; + + input { + position: relative; + + margin-left: -8px; + } + } + + .table-container_row-loader { + margin-left: 8px; + margin-right: 16px; + } + + :hover { + .table-container_cell { + cursor: pointer; + background: ${(props) => + `${props.theme.filesSection.tableView.row.backgroundActive} !important`}; + + margin-top: -1px; + + border-top: ${(props) => + `1px solid ${props.theme.filesSection.tableView.row.borderColor}`}; + } + + .table-container_file-name-cell { + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin-right: -24px; + padding-right: 24px; + ` + : css` + margin-left: -24px; + padding-left: 24px; + `} + } + .table-container_row-context-menu-wrapper { + ${(props) => + props.theme.interfaceDirection === "rtl" + ? css` + margin-left: -20px; + padding-left: 18px; + ` + : css` + margin-right: -20px; + padding-right: 18px; + `} + } + } +`; + +StyledTableRow.defaultProps = { theme: Base }; + +interface RowProps { + item: ClientProps; + isChecked: boolean; + inProgress: boolean; + setSelection?: (clientId: string) => void; + changeClientStatus?: (clientId: string, status: boolean) => Promise; +} + +const Row = (props: RowProps) => { + const { item, changeClientStatus, isChecked, inProgress, setSelection } = + props; + const navigate = useNavigate(); + + const { t } = useTranslation(["Webhooks", "Common"]); + + const editClient = () => { + navigate(window.location.pathname + `/${item.clientId}`); + }; + + const handleToggleEnabled = async () => { + if (!changeClientStatus) return; + await changeClientStatus(item.clientId, !item.enabled); + }; + + const onDeleteOpen = () => {}; + + const handleRowClick = (e: any) => { + if ( + e.target.closest(".checkbox") || + e.target.closest(".table-container_row-checkbox") || + e.target.closest(".type-combobox") || + e.target.closest(".table-container_row-context-menu-wrapper") || + e.target.closest(".toggleButton") || + e.detail === 0 + ) { + return; + } + + editClient(); + }; + + const contextOptions = [ + { + key: "settings", + label: t("Common:Settings"), + icon: SettingsIcon, + onClick: editClient, + }, + { + key: "Separator dropdownItem", + isSeparator: true, + }, + { + key: "delete", + label: t("Common:Delete"), + icon: DeleteIcon, + onClick: onDeleteOpen, + }, + ]; + + return ( + <> + + + + + + + {/* @ts-ignore */} + + {item.description} + + + + + + + + + ); +}; + +export default Row; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/columns/name.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/columns/name.tsx new file mode 100644 index 0000000000..a678abc0b3 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/columns/name.tsx @@ -0,0 +1,88 @@ +import React from "react"; +import styled from "styled-components"; + +import Text from "@docspace/components/text"; +import Checkbox from "@docspace/components/checkbox"; +//@ts-ignore +import TableCell from "@docspace/components/table-container/TableCell"; +import Loader from "@docspace/components/loader"; + +const StyledContainer = styled.div` + .table-container_row-checkbox { + margin-left: -8px; + + width: 16px; + + padding: 16px 8px 16px 16px; + } +`; + +const StyledImage = styled.img` + width: 32px; + height: 32px; +`; + +interface NameCellProps { + name: string; + icon?: string; + clientId: string; + inProgress?: boolean; + isChecked?: boolean; + setSelection?: (clientId: string) => void; +} + +const NameCell = ({ + name, + icon, + clientId, + inProgress, + isChecked, + setSelection, +}: NameCellProps) => { + const onChange = (e: React.ChangeEvent) => { + setSelection && setSelection(clientId); + }; + + return ( + <> + {inProgress ? ( + + ) : ( + + +
+ {icon && } +
+ +
+
+ )} + + {/* @ts-ignore */} + + {name} + + + ); +}; + +export default NameCell; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.js deleted file mode 100644 index 7284a941b0..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.js +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import { inject, observer } from "mobx-react"; -import { isMobile } from "react-device-detect"; - -import styled from "styled-components"; - -import TableContainer from "@docspace/components/table-container/TableContainer"; -import TableBody from "@docspace/components/table-container/TableBody"; - -import Row from "./Row"; -import Header from "./Header"; - -import { Base } from "@docspace/components/themes"; - -const TableWrapper = styled(TableContainer)` - margin-top: 16px; - - .header-container-text { - font-size: 12px; - } - - .table-container_header { - position: absolute; - } - - .table-list-item { - margin-top: -1px; - &:hover { - cursor: pointer; - background-color: ${(props) => - props.theme.isBase ? "#F8F9F9" : "#282828"}; - } - } -`; - -TableWrapper.defaultProps = { theme: Base }; - -const TABLE_VERSION = "1"; -const COLUMNS_SIZE = `oauthConfigColumnsSize_ver-${TABLE_VERSION}`; -const INFO_PANEL_COLUMNS_SIZE = `infoPanelOauthConfigColumnsSize_ver-${TABLE_VERSION}`; - -const TableView = (props) => { - const { - items, - getClients, - sectionWidth, - viewAs, - setViewAs, - openSettingsModal, - openDeleteModal, - userId, - } = props; - - const tableRef = useRef(null); - const [hideColumns, setHideColumns] = useState(false); - - useEffect(() => { - if (!sectionWidth) return; - if (sectionWidth < 1025 || isMobile) { - viewAs !== "row" && setViewAs("row"); - } else { - viewAs !== "table" && setViewAs("table"); - } - }, [sectionWidth]); - - const columnStorageName = `${COLUMNS_SIZE}=${userId}`; - const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`; - - return ( - -
- - {items.map((item, index) => ( - - ))} - - - ); -}; - -export default inject(({ oauthStore, setup, auth }) => { - const { getClients } = oauthStore; - - const { viewAs, setViewAs } = setup; - const { id: userId } = auth.userStore.user; - - return { - viewAs, - setViewAs, - getClients, - userId, - }; -})(observer(TableView)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.tsx new file mode 100644 index 0000000000..0c81652cd9 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/TableView/index.tsx @@ -0,0 +1,140 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import { isMobile } from "react-device-detect"; +import styled from "styled-components"; + +import { ClientProps } from "@docspace/common/utils/oauth/interfaces"; + +//@ts-ignore +import TableContainer from "@docspace/components/table-container/TableContainer"; +//@ts-ignore +import TableBody from "@docspace/components/table-container/TableBody"; +//@ts-ignore +import { OAuthStoreProps, ViewAsType } from "SRC_DIR/store/OAuthStore"; + +import Row from "./Row"; +import Header from "./Header"; + +const TableWrapper = styled(TableContainer)` + margin-top: 0px; + + .header-container-text { + font-size: 12px; + } + + .table-container_header { + position: absolute; + } +`; + +const TABLE_VERSION = "1"; +const COLUMNS_SIZE = `oauthConfigColumnsSize_ver-${TABLE_VERSION}`; + +interface TableViewProps { + items: ClientProps[]; + sectionWidth: number; + viewAs?: ViewAsType; + setViewAs?: (value: ViewAsType) => void; + userId?: string; + selection?: string[]; + setSelection?: (clientId: string) => void; + + bufferSelection?: ClientProps | null; + currentClient?: ClientProps | null; + setBufferSelection?: (clientId: string) => void; + changeClientStatus?: (clientId: string, status: boolean) => Promise; +} + +const TableView = ({ + items, + + sectionWidth, + + viewAs, + setViewAs, + + selection, + bufferSelection, + + setSelection, + + changeClientStatus, + + userId, +}: TableViewProps) => { + const tableRef = React.useRef(null); + + React.useEffect(() => { + if (!sectionWidth || !setViewAs) return; + if (sectionWidth < 1025 || isMobile) { + viewAs !== "row" && setViewAs("row"); + } else { + viewAs !== "table" && setViewAs("table"); + } + }, [sectionWidth, viewAs, setViewAs]); + + const columnStorageName = `${COLUMNS_SIZE}=${userId}`; + + return ( + +
+ console.log("call")} + hasMoreFiles={false} + itemCount={items.length} + > + {items.map((item, index) => ( + + ))} + + + ); +}; + +export default inject( + ({ auth, oauthStore }: { auth: any; oauthStore: OAuthStoreProps }) => { + const { id: userId } = auth.userStore.user; + + const { + viewAs, + setViewAs, + selection, + bufferSelection, + + setSelection, + setBufferSelection, + + changeClientStatus, + + currentClient, + } = oauthStore; + return { + viewAs, + setViewAs, + userId, + changeClientStatus, + selection, + bufferSelection, + + setSelection, + setBufferSelection, + currentClient, + }; + } +)(observer(TableView)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.js b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.js deleted file mode 100644 index 6663d3bc2e..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; - -import { inject, observer } from "mobx-react"; -import { Consumer } from "@docspace/components/utils/context"; - -import TableView from "./TableView"; - -const List = ({ viewAs, openSettingsModal, openDeleteModal, clients }) => { - return ( - - {(context) => ( - - )} - - ); -}; -export default inject(({ setup, oauthStore }) => { - const { viewAs } = setup; - const { clients } = oauthStore; - - return { - viewAs, - clients, - }; -})(observer(List)); diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.tsx new file mode 100644 index 0000000000..cfb38ade3a --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/index.tsx @@ -0,0 +1,94 @@ +import styled from "styled-components"; + +//@ts-ignore +import { ClientProps } from "@docspace/common/utils/oauth/interfaces"; + +import Text from "@docspace/components/text"; +//@ts-ignore +import { Consumer } from "@docspace/components/utils/context"; + +//@ts-ignore +import { ViewAsType } from "SRC_DIR/store/OAuthStore"; + +import TableView from "./TableView"; +import RegisterNewButton from "../RegisterNewButton"; + +const StyledContainer = styled.div` + width: 100%; + + display: flex; + flex-direction: column; + + .header { + margin-bottom: 8px; + } + + .description { + margin-bottom: 8px; + } + + button { + width: fit-content; + + margin-bottom: 12px; + } +`; + +interface ListProps { + t: any; + clients: ClientProps[]; + viewAs?: ViewAsType; + setViewAs?: (value: ViewAsType) => void; +} + +const List = ({ t, clients, viewAs, setViewAs }: ListProps) => { + return ( + + + {"OAuth applications"} + + + {"OAuth description"} + + + + {(context: { sectionWidth: number; sectionHeight: number }) => ( + <> + {viewAs === "table" ? ( + + ) : ( +
row
+ )} + + )} +
+
+ ); +}; + +export default List; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/RegisterNewButton/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/RegisterNewButton/index.tsx index 38e89981f5..e0536c142e 100644 --- a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/RegisterNewButton/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/RegisterNewButton/index.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { useNavigate } from "react-router-dom"; import { isMobile } from "react-device-detect"; diff --git a/packages/client/src/store/OAuthStore.ts b/packages/client/src/store/OAuthStore.ts index d5c2c9f2b4..f329704e41 100644 --- a/packages/client/src/store/OAuthStore.ts +++ b/packages/client/src/store/OAuthStore.ts @@ -1,108 +1,239 @@ import { makeAutoObservable } from "mobx"; +//@ts-ignore +import { getPortal } from "@docspace/common/api/portal"; + import { addClient, - deleteClient, getClient, + updateClient, + changeClientStatus, + regenerateSecret, + deleteClient, getClientList, getScope, getScopeList, - regenerateSecret, - updateClient, } from "@docspace/common/api/oauth"; import { - ClientDTO, - ClientListDTO, ClientListProps, ClientProps, - ScopeDTO, -} from "@docspace/common/utils/oauth/dto"; + Scope, +} from "@docspace/common/utils/oauth/interfaces"; + +const PAGE_LIMIT = 20; + +export type ViewAsType = "table" | "row"; export interface OAuthStoreProps { + viewAs: ViewAsType; + + deleteDialogVisible: boolean; + setDeleteDialogVisible: (value: boolean) => void; + clients: ClientProps[]; - currentClient: null | ClientProps; + currentPage: number; + totalPages: number; - scopes: ScopeDTO[]; + selection: string[]; + setSelection: (clientId: string) => void; - fetchClient: (clientId: string) => Promise; - fetchClients: (page: number, limit: number) => Promise; - saveClient: (client: ClientProps) => Promise; - updateClient: (clientId: string, client: ClientProps) => Promise; - regenerateSecret: (clientId: string) => Promise; + bufferSelection: ClientProps | null; + setBufferSelection: (clientId: string) => void; + + tenant: number; + fetchTenant: () => Promise; + + scopes: Scope[]; + + setViewAs: (value: "table" | "row") => void; + + fetchClient: (clientId: string) => Promise; + fetchClients: (page: number) => Promise; + saveClient: (client: ClientProps) => Promise; + updateClient: (clientId: string, client: ClientProps) => Promise; + changeClientStatus: (clientId: string, status: boolean) => Promise; + regenerateSecret: (clientId: string) => Promise; deleteClient: (clientId: string) => Promise; - fetchScope: (name: string) => Promise; + fetchScope: (name: string) => Promise; fetchScopes: () => Promise; clientList: ClientProps[]; - scopeList: ScopeDTO[]; + isEmptyClientList: boolean; + hasNextPage: boolean; + scopeList: Scope[]; } class OAuthStore implements OAuthStoreProps { - clients: ClientProps[] = []; - currentClient: ClientProps | null = null; + viewAs: "table" | "row" = "table"; - scopes: ScopeDTO[] = []; + currentPage: number = 0; + totalPages: number = 0; + + deleteDialogVisible: boolean = false; + + selection: string[] = []; + + bufferSelection: ClientProps | null = null; + + tenant: number = -1; + + clients: ClientProps[] = []; + + scopes: Scope[] = []; constructor() { makeAutoObservable(this); } + setViewAs = (value: "table" | "row") => { + this.viewAs = value; + }; + + setDeleteDialogVisible = (value: boolean) => { + this.deleteDialogVisible = value; + }; + + setSelection = (clientId: string) => { + if (this.selection.includes(clientId)) { + this.selection = this.selection.filter((s) => s !== clientId); + } else { + this.selection.push(clientId); + } + }; + + setBufferSelection = (clientId: string) => { + const client = this.clients.find((c) => c.clientId === clientId); + + if (client) { + this.bufferSelection = { ...client, scopes: [...client.scopes] }; + } + }; + + fetchTenant = async () => { + if (this.tenant > -1) return this.tenant; + + const { tenant } = await getPortal(); + + this.tenant = tenant; + return tenant; + }; + fetchClient = async (clientId: string) => { - const client = await getClient(clientId); + try { + const client = await getClient(clientId); - return client; + return client; + } catch (e) { + console.log(e); + } }; - fetchClients = async (page: number, limit: number) => { - const clientList: ClientListProps = await getClientList(0, 20); + fetchClients = async (page: number) => { + try { + const clientList: ClientListProps = await getClientList(0, PAGE_LIMIT); - this.clients = clientList.content; + this.totalPages = clientList.totalPages; + this.currentPage = page; + this.clients = clientList.content; + } catch (e) { + console.log(e); + } }; - //TODO: add tenant and other params + //TODO: OAuth, add tenant and other params saveClient = async (client: ClientProps) => { - client.tenant = 1; - client.authenticationMethod = "zxc"; - client.termsUrl = "zxc"; - const newClient = await addClient(client); + try { + client.tenant = 1; + client.authenticationMethod = "zxc"; + client.termsUrl = "zxc"; + const newClient = await addClient(client); - return newClient; + this.clients.push(newClient); + } catch (e) { + console.log(e); + } }; updateClient = async (clientId: string, client: ClientProps) => { - const newClient = await updateClient(clientId, client); + try { + const newClient = await updateClient(clientId, client); - return newClient; + const idx = this.clients.findIndex((c) => c.clientId === clientId); + + if (idx > -1) { + this.clients[idx] = newClient; + } + } catch (e) { + console.log(e); + } + }; + + changeClientStatus = async (clientId: string, status: boolean) => { + try { + await changeClientStatus(clientId, status); + + const idx = this.clients.findIndex((c) => c.clientId === clientId); + + if (idx > -1) { + this.clients[idx] = { ...this.clients[idx], enabled: status }; + } + } catch (e) { + console.log(e); + } }; regenerateSecret = async (clientId: string) => { - const secret = await regenerateSecret(clientId); + try { + const secret = await regenerateSecret(clientId); - return secret; + return secret; + } catch (e) { + console.log(e); + } }; deleteClient = async (clientId: string) => { - await deleteClient(clientId); + try { + await deleteClient(clientId); + } catch (e) { + console.log(e); + } }; fetchScope = async (name: string) => { - const scope = await getScope(name); + try { + const scope = await getScope(name); - return scope; + return scope; + } catch (e) { + console.log(e); + } }; fetchScopes = async () => { - const scopes = await getScopeList(); + try { + const scopes = await getScopeList(); - this.scopes = scopes; + this.scopes = scopes; + } catch (e) { + console.log(e); + } }; get clientList() { return this.clients; } + get isEmptyClientList() { + return this.clientList.length === 0; + } + + get hasNextPage() { + return this.totalPages - this.currentPage !== 0; + } + get scopeList() { return this.scopes; } diff --git a/packages/common/api/oauth/index.ts b/packages/common/api/oauth/index.ts index 9998ce3277..45a8c5fa9e 100644 --- a/packages/common/api/oauth/index.ts +++ b/packages/common/api/oauth/index.ts @@ -2,22 +2,23 @@ import axios, { AxiosRequestConfig } from "axios"; import { transformToClientProps, - transformToClientDTO, + transformToClientReqDTO, } from "./../../utils/oauth/index"; import { - ClientDTO, - ClientListDTO, - ClientListProps, ClientProps, - ScopeDTO, -} from "../../utils/oauth/dto"; + ClientResDTO, + ClientListProps, + ClientListDTO, + Scope, +} from "../../utils/oauth/interfaces"; const axiosConfig: AxiosRequestConfig = { baseURL: "/api", responseType: "json", timeout: 0, withCredentials: true, + // TODO: OAuth, remove X-Tenant into API headers: { "X-API-Version": "1", "X-Tenant": "1" }, }; @@ -36,11 +37,14 @@ const request = (options: any): Promise => { }; export const getClient = async (clientId: string): Promise => { - const client: ClientDTO = await request({ + const client: ClientResDTO = await request({ method: "get", url: `/clients/${clientId}`, + headers: {}, }); + client.enabled = true; + return transformToClientProps(client); }; @@ -58,6 +62,9 @@ export const getClientList = async ( data.content.forEach((item) => { const client = transformToClientProps(item); + // TODO: OAuth, get it from request + client.enabled = true; + clients.content.push({ ...client }); }); @@ -65,12 +72,15 @@ export const getClientList = async ( }; export const addClient = async (data: ClientProps): Promise => { - const client: ClientDTO = await request({ + const client: ClientResDTO = await request({ method: "post", url: `/clients`, - data: transformToClientDTO(data), + data: transformToClientReqDTO(data), }); + // TODO: OAuth, get it from request + client.enabled = true; + return transformToClientProps(client); }; @@ -78,15 +88,27 @@ export const updateClient = async ( clientId: string, data: ClientProps ): Promise => { - const client: ClientDTO = await request({ + const client: ClientResDTO = await request({ method: "put", url: `/clients/${clientId}`, - data: transformToClientDTO(data), + data: transformToClientReqDTO(data), }); + // TODO: OAuth, get it from request + client.enabled = true; + return transformToClientProps(client); }; +export const changeClientStatus = async ( + clientId: string, + status: boolean +): Promise => { + console.log(`Change client:${clientId} status to ${status}`); + + return !status; +}; + export const regenerateSecret = async (clientId: string): Promise => { const clientSecret: string = ( await request({ @@ -105,8 +127,8 @@ export const deleteClient = async (clientId: string): Promise => { }); }; -export const getScope = async (name: string): Promise => { - const scope: ScopeDTO = await request({ +export const getScope = async (name: string): Promise => { + const scope: Scope = await request({ method: "get", url: `/scopes/${name}`, }); @@ -114,8 +136,8 @@ export const getScope = async (name: string): Promise => { return scope; }; -export const getScopeList = async (): Promise => { - const scopeList: ScopeDTO[] = await request({ +export const getScopeList = async (): Promise => { + const scopeList: Scope[] = await request({ method: "get", url: `/scopes`, }); diff --git a/packages/common/utils/oauth/enums.ts b/packages/common/utils/oauth/enums.ts index 6ccfd0d237..e69de29bb2 100644 --- a/packages/common/utils/oauth/enums.ts +++ b/packages/common/utils/oauth/enums.ts @@ -1,10 +0,0 @@ -export const enum OauthScopes { - ReadFiles = "files:read", - WriteFiles = "files:write", - ReadRooms = "rooms:read", - WriteRooms = "rooms:write", - ReadAccount = "account.self:read", - WriteAccount = "account.self:write", - ReadAccounts = "accounts:read", - WriteAccounts = "accounts:write", -} diff --git a/packages/common/utils/oauth/index.ts b/packages/common/utils/oauth/index.ts index 2671e09316..fa63f3e69d 100644 --- a/packages/common/utils/oauth/index.ts +++ b/packages/common/utils/oauth/index.ts @@ -1,6 +1,8 @@ -import { ClientDTO, ClientProps } from "./dto"; +import { ClientResDTO, ClientReqDTO, ClientProps } from "./interfaces"; -export const transformToClientProps = (clientDto: ClientDTO): ClientProps => { +export const transformToClientProps = ( + clientDto: ClientResDTO +): ClientProps => { const { client_id, client_secret, @@ -8,13 +10,14 @@ export const transformToClientProps = (clientDto: ClientDTO): ClientProps => { terms_url, policy_url, logo_url, - authenticationMethod, + authentication_method, redirect_uri, logout_redirect_uri, scopes, tenant, invalidated, name, + enabled, } = clientDto; const client: ClientProps = { @@ -24,22 +27,24 @@ export const transformToClientProps = (clientDto: ClientDTO): ClientProps => { termsUrl: terms_url, policyUrl: policy_url, logoUrl: logo_url, - authenticationMethod, + authenticationMethod: authentication_method, redirectUri: redirect_uri, logoutRedirectUri: logout_redirect_uri, scopes, tenant, invalidated, name, + enabled, }; return client; }; -export const transformToClientDTO = (clientProps: ClientProps): ClientDTO => { +export const transformToClientReqDTO = ( + clientProps: ClientProps +): ClientReqDTO => { const { - clientId: client_id, - secret: client_secret, + name, description, termsUrl: terms_url, policyUrl: policy_url, @@ -49,24 +54,21 @@ export const transformToClientDTO = (clientProps: ClientProps): ClientDTO => { logoutRedirectUri: logout_redirect_uri, scopes, tenant, - invalidated, - name, } = clientProps; - const client: ClientDTO = { - client_id, - client_secret, + const client: ClientReqDTO = { + name, description, - terms_url, - policy_url, logo_url, - authenticationMethod, + redirect_uri, logout_redirect_uri, + terms_url, + policy_url, + scopes, + tenant, - invalidated, - name, }; return client; diff --git a/packages/common/utils/oauth/dto.ts b/packages/common/utils/oauth/interfaces.ts similarity index 76% rename from packages/common/utils/oauth/dto.ts rename to packages/common/utils/oauth/interfaces.ts index fb504c2510..25b26aaa41 100644 --- a/packages/common/utils/oauth/dto.ts +++ b/packages/common/utils/oauth/interfaces.ts @@ -1,4 +1,4 @@ -export type ScopeDTO = { +export type Scope = { name: string; description: string; }; @@ -6,34 +6,61 @@ export type ScopeDTO = { export interface ClientProps { clientId: string; secret: string; - description: string; - termsUrl?: string; - policyUrl: string; - logoUrl: string; - authenticationMethod?: string; - redirectUri: string; - logoutRedirectUri: string; - scopes: string[]; - tenant?: number; - invalidated?: boolean; - name: string; -} -export type ClientDTO = { - client_id: string; - client_secret: string; + name: string; description: string; - terms_url: string; - policy_url: string; - logo_url: string; + logoUrl?: string; + + redirectUri: string; + policyUrl: string; + termsUrl: string; + logoutRedirectUri: string; + authenticationMethod: string; - redirect_uri: string; - logout_redirect_uri: string; + scopes: string[]; + + enabled: boolean; tenant: number; invalidated?: boolean; +} + +export interface ClientReqDTO { name: string; -}; + description: string; + logo_url?: string; + + redirect_uri: string; + policy_url: string; + terms_url: string; + logout_redirect_uri: string; + + scopes: string[]; + + tenant: number; +} + +export interface ClientResDTO { + client_id: string; + client_secret: string; + + name: string; + description: string; + logo_url?: string; + + redirect_uri: string; + terms_url: string; + policy_url: string; + logout_redirect_uri: string; + + authentication_method: string; + + scopes: string[]; + + enabled: boolean; + tenant: number; + invalidated?: boolean; +} export interface ClientListProps { content: ClientProps[]; @@ -65,7 +92,7 @@ export interface ClientListProps { } export type ClientListDTO = { - content: ClientDTO[]; + content: ClientResDTO[]; empty: boolean; first: boolean; last: true; diff --git a/packages/components/input-block/index.js b/packages/components/input-block/index.js index 135965c60e..70a7b4e22d 100644 --- a/packages/components/input-block/index.js +++ b/packages/components/input-block/index.js @@ -127,8 +127,7 @@ class InputBlock extends React.Component { forwardedRef={forwardedRef} {...props} /> - { - //iconNames.includes(iconName) && ( + {iconName && (
- } + )} ); }