From ca73c5b0c41c8bdcb8ebf41e24775860485b6d4b Mon Sep 17 00:00:00 2001 From: Timofey Boyko Date: Thu, 28 Sep 2023 10:21:43 +0300 Subject: [PATCH] Web:Client:OAuth: add row view --- .../OAuth/sub-components/List/RowView/Row.tsx | 85 ++++++++++++++++ .../List/RowView/RowContent.tsx | 57 +++++++++++ .../List/RowView/RowView.styled.ts | 67 +++++++++++++ .../List/RowView/RowView.types.ts | 49 +++++++++ .../sub-components/List/RowView/index.tsx | 99 +++++++++++++++++++ .../sub-components/List/TableView/Row.tsx | 2 +- .../OAuth/sub-components/List/index.tsx | 9 +- packages/client/src/store/OAuthStore.ts | 35 +++++-- 8 files changed, 392 insertions(+), 11 deletions(-) create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/Row.tsx create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowContent.tsx create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.styled.ts create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.types.ts create mode 100644 packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/index.tsx diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/Row.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/Row.tsx new file mode 100644 index 0000000000..62328b4895 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/Row.tsx @@ -0,0 +1,85 @@ +import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; + +//@ts-ignore +import Row from "@docspace/components/row"; +import ToggleButton from "@docspace/components/toggle-button"; + +import { RowContent } from "./RowContent"; +import { RowProps } from "./RowView.types"; + +export const OAuthRow = (props: RowProps) => { + const { + item, + sectionWidth, + changeClientStatus, + isChecked, + inProgress, + getContextMenuItems, + setSelection, + } = props; + const navigate = useNavigate(); + + const { t } = useTranslation(["Common"]); + + const editClient = () => { + navigate(`${item.clientId}`); + }; + + const handleToggleEnabled = async () => { + if (!changeClientStatus) return; + await changeClientStatus(item.clientId, !item.enabled); + }; + + const handleRowClick = (e: any) => { + if ( + e.target.closest(".checkbox") || + e.target.closest(".table-container_row-checkbox") || + e.detail === 0 + ) { + return; + } + + if ( + e.target.closest(".table-container_row-context-menu-wrapper") || + e.target.closest(".toggleButton") || + e.target.closest(".row_context-menu-wrapper") + ) { + return setSelection && setSelection(""); + } + + editClient(); + }; + + const contextOptions = getContextMenuItems && getContextMenuItems(t, item); + + const element = {"App; + + return ( + <> + setSelection && setSelection(item.clientId)} + > + + + + ); +}; + +export default OAuthRow; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowContent.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowContent.tsx new file mode 100644 index 0000000000..e4f0ac6269 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowContent.tsx @@ -0,0 +1,57 @@ +import React from "react"; + +import Text from "@docspace/components/text"; + +import ToggleButton from "@docspace/components/toggle-button"; + +import { isMobileOnly } from "react-device-detect"; + +import { + StyledRowContent, + ContentWrapper, + FlexWrapper, + ToggleButtonWrapper, +} from "./RowView.styled"; +import { RowContentProps } from "./RowView.types"; + +export const RowContent = ({ + sectionWidth, + item, + + handleToggleEnabled, +}: RowContentProps) => { + return ( + + + + {/* @ts-ignore */} + + {item.name} + + + + {!isMobileOnly && ( + <> + {/* @ts-ignore */} + + {item.description} + + + )} + + + + + + + ); +}; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.styled.ts b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.styled.ts new file mode 100644 index 0000000000..0e1a142fb9 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.styled.ts @@ -0,0 +1,67 @@ +import styled from "styled-components"; + +//@ts-ignore +import RowContainer from "@docspace/components/row-container"; +//@ts-ignore +import RowContent from "@docspace/components/row-content"; + +export const StyledRowContainer = styled(RowContainer)` + margin-top: 0px; + + .row-list-item { + padding-left: 21px; + } + + .row-loader { + width: calc(100% - 46px) !important; + padding-left: 21px; + } + + img { + width: 32px; + max-width: 32px; + + height: 32px; + max-height: 32px; + } +`; + +export const StyledRowContent = styled(RowContent)` + display: flex; + padding-bottom: 10px; + + .rowMainContainer { + height: 100%; + width: 100%; + } + + .mainIcons { + min-width: 76px; + } +`; + +export const ContentWrapper = styled.div` + display: flex; + flex-direction: column; + justify-items: center; +`; + +export const ToggleButtonWrapper = styled.div` + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: flex-end; + + label { + margin-top: 1px; + position: relative; + gap: 0px; + + margin-right: -8px; + } +`; + +export const FlexWrapper = styled.div` + display: flex; +`; diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.types.ts b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.types.ts new file mode 100644 index 0000000000..fc3ab07033 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/RowView.types.ts @@ -0,0 +1,49 @@ +import { ClientProps } from "@docspace/common/utils/oauth/interfaces"; + +//@ts-ignore +import { ViewAsType } from "SRC_DIR/store/OAuthStore"; + +export interface RowViewProps { + items: ClientProps[]; + sectionWidth: number; + viewAs?: ViewAsType; + setViewAs?: (value: ViewAsType) => void; + selection?: string[]; + setSelection?: (clientId: string) => void; + getContextMenuItems?: ( + t: any, + item: ClientProps + ) => { + [key: string]: any | string | boolean | ((clientId: string) => void); + }[]; + activeClients?: string[]; + hasNextPage?: boolean; + totalElements?: number; + fetchNextClients?: (startIndex: number) => Promise; + changeClientStatus?: (clientId: string, status: boolean) => Promise; +} + +export interface RowProps { + item: ClientProps; + isChecked: boolean; + inProgress: boolean; + sectionWidth: number; + getContextMenuItems?: ( + t: any, + item: ClientProps + ) => { + [key: string]: any | string | boolean | ((clientId: string) => void); + }[]; + setSelection?: (clientId: string) => void; + changeClientStatus?: (clientId: string, status: boolean) => Promise; +} + +export interface RowContentProps { + sectionWidth: number; + item: ClientProps; + isChecked: boolean; + inProgress: boolean; + handleToggleEnabled: () => void; + setSelection?: (clientId: string) => void; + changeClientStatus?: (clientId: string, status: boolean) => Promise; +} diff --git a/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/index.tsx b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/index.tsx new file mode 100644 index 0000000000..d4e2a1d166 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/developer-tools/OAuth/sub-components/List/RowView/index.tsx @@ -0,0 +1,99 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import { isMobile } from "react-device-detect"; + +//@ts-ignore +import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore"; + +import OAuthRow from "./Row"; + +import { RowViewProps } from "./RowView.types"; +import { StyledRowContainer } from "./RowView.styled"; + +const RowView = (props: RowViewProps) => { + const { + items, + sectionWidth, + viewAs, + setViewAs, + + changeClientStatus, + selection, + setSelection, + + activeClients, + getContextMenuItems, + hasNextPage, + totalElements, + fetchNextClients, + } = props; + + React.useEffect(() => { + if (viewAs !== "table" && viewAs !== "row") return; + + if (sectionWidth < 1025 || isMobile) { + viewAs !== "row" && setViewAs && setViewAs("row"); + } else { + viewAs !== "table" && setViewAs && setViewAs("table"); + } + }, [viewAs, setViewAs, sectionWidth]); + + return ( + fetchNextClients && fetchNextClients(startIndex)} + hasMoreFiles={hasNextPage} + itemCount={totalElements} + useReactWindow={true} + > + {items.map((item) => ( + + ))} + + ); +}; + +export default inject( + ({ oauthStore }: { auth: any; oauthStore: OAuthStoreProps }) => { + const { + viewAs, + setViewAs, + selection, + setSelection, + changeClientStatus, + getContextMenuItems, + activeClients, + hasNextPage, + totalElements, + fetchNextClients, + } = oauthStore; + + return { + viewAs, + setViewAs, + changeClientStatus, + selection, + setSelection, + activeClients, + getContextMenuItems, + hasNextPage, + totalElements, + fetchNextClients, + }; + } +)(observer(RowView)); 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 index c6dfdf7a9c..33159e68a4 100644 --- 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 @@ -22,7 +22,7 @@ const Row = (props: RowProps) => { } = props; const navigate = useNavigate(); - const { t } = useTranslation(["Webhooks", "Common"]); + const { t } = useTranslation(["Common"]); const editClient = () => { navigate(`${item.clientId}`); 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 index cfb38ade3a..c2921094c7 100644 --- 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 @@ -11,6 +11,8 @@ import { Consumer } from "@docspace/components/utils/context"; import { ViewAsType } from "SRC_DIR/store/OAuthStore"; import TableView from "./TableView"; +import RowView from "./RowView"; + import RegisterNewButton from "../RegisterNewButton"; const StyledContainer = styled.div` @@ -82,7 +84,12 @@ const List = ({ t, clients, viewAs, setViewAs }: ListProps) => { sectionWidth={context.sectionWidth} /> ) : ( -
row
+ )} )} diff --git a/packages/client/src/store/OAuthStore.ts b/packages/client/src/store/OAuthStore.ts index 0e77e09411..4970e2584e 100644 --- a/packages/client/src/store/OAuthStore.ts +++ b/packages/client/src/store/OAuthStore.ts @@ -37,6 +37,9 @@ export interface OAuthStoreProps { deleteDialogVisible: boolean; setDeleteDialogVisible: (value: boolean) => void; + clientsIsLoading: boolean; + setClientsIsLoading: (value: boolean) => void; + editClient: (clientId: string) => void; clients: ClientProps[]; @@ -85,7 +88,7 @@ export interface OAuthStoreProps { class OAuthStore implements OAuthStoreProps { viewAs: "table" | "row" = "table"; - currentPage: number = 0; + currentPage: number = -1; totalPages: number = 0; totalElements: number = 0; @@ -103,6 +106,8 @@ class OAuthStore implements OAuthStoreProps { scopes: Scope[] = []; + clientsIsLoading: boolean = true; + constructor() { makeAutoObservable(this); } @@ -135,6 +140,10 @@ class OAuthStore implements OAuthStoreProps { } }; + setClientsIsLoading = (value: boolean) => { + this.clientsIsLoading = value; + }; + setActiveClient = (clientId: string) => { if (!clientId) { this.activeClients = []; @@ -175,10 +184,7 @@ class OAuthStore implements OAuthStoreProps { fetchClients = async () => { try { - runInAction(() => { - this.currentPage = 1; - }); - + this.setClientsIsLoading(true); const clientList: ClientListProps = await getClientList(0, PAGE_LIMIT); runInAction(() => { @@ -186,14 +192,23 @@ class OAuthStore implements OAuthStoreProps { this.totalElements = clientList.totalElements; this.clients = clientList.content; + this.selection = []; + this.currentPage = 1; }); + this.setClientsIsLoading(false); } catch (e) { console.log(e); } }; fetchNextClients = async (startIndex: number) => { + if (this.clientsIsLoading) return; + this.setClientsIsLoading(true); + const page = startIndex / PAGE_LIMIT; + + console.log(page); + runInAction(() => { this.currentPage = page + 1; }); @@ -205,6 +220,8 @@ class OAuthStore implements OAuthStoreProps { this.totalElements = clientList.totalElements; this.clients = [...this.clients, ...clientList.content]; }); + + this.setClientsIsLoading(false); }; //TODO: OAuth, add tenant and other params @@ -338,21 +355,21 @@ class OAuthStore implements OAuthStoreProps { const settingsOption = { key: "settings", icon: SettingsIcon, - label: t("Common:Settings"), + label: t("Settings"), onClick: () => this.editClient(clientId), }; const enableOption = { key: "enable", icon: EnableReactSvgUrl, - label: t("Common:Enable"), + label: t("Enable"), onClick: () => onEnable(true), }; const disableOption = { key: "disable", icon: RemoveReactSvgUrl, - label: t("Common:Disable"), + label: t("Disable"), onClick: () => onEnable(false), }; @@ -363,7 +380,7 @@ class OAuthStore implements OAuthStoreProps { }, { key: "delete", - label: t("Common:Delete"), + label: t("Delete"), icon: DeleteIcon, onClick: () => onDelete(), },