Client:PortalSettings:OAuth: fix fetch clients

This commit is contained in:
Timofey Boyko 2023-11-01 12:34:24 +03:00
parent 8318dbb8f5
commit b593aa13f3
15 changed files with 201 additions and 80 deletions

View File

@ -1,12 +1,17 @@
//@ts-ignore
import { ClientProps } from "@docspace/common/utils/oauth/dto";
import { DeviceUnionType } from "@docspace/common/hooks/useViewEffect";
import { IClientProps } from "@docspace/common/utils/oauth/interfaces";
//@ts-ignore
import { ViewAsType } from "SRC_DIR/store/OAuthStore";
export interface OAuthProps {
viewAs: ViewAsType;
clientList: ClientProps[];
setViewAs: (viewAs: ViewAsType) => void;
clientList: IClientProps[];
isEmptyClientList: boolean;
fetchClients: () => Promise<void>;
currentDeviceType: DeviceUnionType;
}

View File

@ -2,6 +2,8 @@ import React from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import { useViewEffect } from "@docspace/common/hooks";
//@ts-ignore
import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore";
//@ts-ignore
@ -19,7 +21,9 @@ const OAuth = ({
clientList,
viewAs,
isEmptyClientList,
setViewAs,
fetchClients,
currentDeviceType,
}: OAuthProps) => {
const { t } = useTranslation(["OAuth"]);
@ -45,6 +49,12 @@ const OAuth = ({
setIsLoading(false);
}, []);
useViewEffect({
view: viewAs,
setView: setViewAs,
currentDeviceType,
});
React.useEffect(() => {
startLoadingRef.current = new Date();
getClientList();
@ -67,7 +77,18 @@ const OAuth = ({
);
};
export default inject(({ oauthStore }: { oauthStore: OAuthStoreProps }) => {
const { viewAs, clientList, isEmptyClientList, fetchClients } = oauthStore;
return { viewAs, clientList, isEmptyClientList, fetchClients };
})(observer(OAuth));
export default inject(
({ oauthStore, auth }: { oauthStore: OAuthStoreProps; auth: any }) => {
const { currentDeviceType } = auth.settingsStore;
const { viewAs, setViewAs, clientList, isEmptyClientList, fetchClients } =
oauthStore;
return {
viewAs,
setViewAs,
clientList,
isEmptyClientList,
fetchClients,
currentDeviceType,
};
}
)(observer(OAuth));

View File

@ -26,8 +26,22 @@ const Header = (props: HeaderProps) => {
minWidth: 210,
},
{
key: "Description",
title: "Description",
key: "Creator",
title: "Creator",
resizable: true,
enable: true,
minWidth: 150,
},
{
key: "Modified",
title: "Modified",
resizable: true,
enable: true,
minWidth: 150,
},
{
key: "Scopes",
title: "Scopes",
resizable: true,
enable: true,
minWidth: 150,

View File

@ -10,6 +10,7 @@ import NameCell from "./columns/name";
import { StyledRowWrapper, StyledTableRow } from "./TableView.styled";
import { RowProps } from "./TableView.types";
import CreatorCell from "./columns/creator";
const Row = (props: RowProps) => {
const {
@ -65,13 +66,19 @@ const Row = (props: RowProps) => {
<TableCell className={"table-container_file-name-cell"}>
<NameCell
name={item.name}
icon={item.logoUrl}
icon={item.logo}
isChecked={isChecked}
inProgress={inProgress}
clientId={item.clientId}
setSelection={setSelection}
/>
</TableCell>
<TableCell>
<CreatorCell
avatar={item.creatorAvatar || ""}
displayName={item.creatorDisplayName || ""}
/>
</TableCell>
<TableCell>
{/* @ts-ignore */}
<Text as="span" fontWeight={400} className="mr-8 textOverflow">

View File

@ -1,26 +1,22 @@
import { ClientProps } from "@docspace/common/utils/oauth/interfaces";
//@ts-ignore
import { ViewAsType } from "SRC_DIR/store/OAuthStore";
import { IClientProps } from "@docspace/common/utils/oauth/interfaces";
export interface TableViewProps {
items: ClientProps[];
items: IClientProps[];
sectionWidth: number;
viewAs?: ViewAsType;
setViewAs?: (value: ViewAsType) => void;
userId?: string;
selection?: string[];
setSelection?: (clientId: string) => void;
getContextMenuItems?: (
t: any,
item: ClientProps
item: IClientProps
) => {
[key: string]: any | string | boolean | ((clientId: string) => void);
}[];
bufferSelection?: ClientProps | null;
bufferSelection?: IClientProps | null;
activeClients?: string[];
hasNextPage?: boolean;
totalElements?: number;
itemCount?: number;
fetchNextClients?: (startIndex: number) => Promise<void>;
changeClientStatus?: (clientId: string, status: boolean) => Promise<void>;
}
@ -32,12 +28,12 @@ export interface HeaderProps {
}
export interface RowProps {
item: ClientProps;
item: IClientProps;
isChecked: boolean;
inProgress: boolean;
getContextMenuItems?: (
t: any,
item: ClientProps
item: IClientProps
) => {
[key: string]: any | string | boolean | ((clientId: string) => void);
}[];

View File

@ -0,0 +1,54 @@
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";
import Avatar from "@docspace/components/avatar";
const StyledContainer = styled.div`
.table-container_row-checkbox {
margin-left: -8px;
width: 16px;
padding: 16px 8px 16px 16px;
}
`;
const StyledAvatar = styled(Avatar)`
width: 16px;
min-width: 16px;
max-width: 16px;
height: 16px;
margin-right: 4px;
`;
interface CreatorCellProps {
avatar: string;
displayName: string;
}
const CreatorCell = ({ avatar, displayName }: CreatorCellProps) => {
return (
<>
<StyledAvatar source={avatar} size={"min"} />
{/* @ts-ignore */}
<Text
type="page"
title={name}
fontWeight="600"
fontSize="13px"
isTextOverflow
>
{displayName}
</Text>
</>
);
};
export default CreatorCell;

View File

@ -1,6 +1,5 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
//@ts-ignore
import TableBody from "@docspace/components/table-container/TableBody";
@ -19,8 +18,6 @@ const COLUMNS_SIZE = `oauthConfigColumnsSize_ver-${TABLE_VERSION}`;
const TableView = ({
items,
sectionWidth,
viewAs,
setViewAs,
selection,
activeClients,
setSelection,
@ -28,20 +25,11 @@ const TableView = ({
changeClientStatus,
userId,
hasNextPage,
totalElements,
itemCount,
fetchNextClients,
}: TableViewProps) => {
const tableRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
if (!sectionWidth || !setViewAs) return;
if (sectionWidth < 1025 || isMobile) {
viewAs !== "row" && setViewAs("row");
} else {
viewAs !== "table" && setViewAs("table");
}
}, [sectionWidth, viewAs, setViewAs]);
const clickOutside = React.useCallback(
(e: any) => {
if (
@ -87,7 +75,7 @@ const TableView = ({
stopIndex: number;
}) => fetchNextClients && fetchNextClients(startIndex)}
hasMoreFiles={hasNextPage}
itemCount={totalElements}
itemCount={itemCount}
>
{items.map((item) => (
<Row
@ -109,6 +97,8 @@ export default inject(
({ auth, oauthStore }: { auth: any; oauthStore: OAuthStoreProps }) => {
const { id: userId } = auth.userStore.user;
const { currentDeviceType } = auth.settingsStore;
const {
viewAs,
setViewAs,
@ -119,7 +109,7 @@ export default inject(
getContextMenuItems,
activeClients,
hasNextPage,
totalElements,
itemCount,
fetchNextClients,
} = oauthStore;
@ -134,8 +124,9 @@ export default inject(
activeClients,
getContextMenuItems,
hasNextPage,
totalElements,
itemCount,
fetchNextClients,
currentDeviceType,
};
}
)(observer(TableView));

View File

@ -39,11 +39,10 @@ const StyledContainer = styled.div`
interface ListProps {
t: any;
clients: ClientProps[];
viewAs?: ViewAsType;
setViewAs?: (value: ViewAsType) => void;
viewAs: ViewAsType;
}
const List = ({ t, clients, viewAs, setViewAs }: ListProps) => {
const List = ({ t, clients, viewAs }: ListProps) => {
return (
<StyledContainer>
<Text
@ -78,15 +77,11 @@ const List = ({ t, clients, viewAs, setViewAs }: ListProps) => {
<>
{viewAs === "table" ? (
<TableView
viewAs={viewAs}
setViewAs={setViewAs}
items={clients || []}
sectionWidth={context.sectionWidth}
/>
) : (
<RowView
viewAs={viewAs}
setViewAs={setViewAs}
items={clients || []}
sectionWidth={context.sectionWidth}
/>

View File

@ -16,6 +16,7 @@ import {
IClientListProps,
IClientProps,
IClientReqDTO,
INoAuthClientProps,
IScope,
} from "@docspace/common/utils/oauth/interfaces";
@ -41,7 +42,9 @@ export interface OAuthStoreProps {
editClient: (clientId: string) => void;
clients: IClientProps[];
fetchClient: (clientId: string) => Promise<IClientProps | undefined>;
fetchClient: (
clientId: string
) => Promise<IClientProps | INoAuthClientProps | undefined>;
fetchClients: () => Promise<void>;
fetchNextClients: (startIndex: number) => Promise<void>;
@ -56,8 +59,8 @@ export interface OAuthStoreProps {
deleteClient: (clientId: string) => Promise<void>;
currentPage: number;
totalPages: number;
totalElements: number;
nextPage: number | null;
itemCount: number;
selection: string[];
setSelection: (clientId: string) => void;
@ -88,9 +91,9 @@ export interface OAuthStoreProps {
class OAuthStore implements OAuthStoreProps {
viewAs: ViewAsType = "table";
currentPage: number = -1;
totalPages: number = 0;
totalElements: number = 0;
currentPage: number = 0;
nextPage: number | null = null;
itemCount: number = 0;
deleteDialogVisible: boolean = false;
@ -177,12 +180,15 @@ class OAuthStore implements OAuthStoreProps {
const clientList: IClientListProps = await getClientList(0, PAGE_LIMIT);
runInAction(() => {
this.totalPages = clientList.totalPages;
this.totalElements = clientList.totalElements;
this.clients = clientList.content;
this.selection = [];
this.currentPage = 1;
this.currentPage = clientList.page;
this.nextPage = clientList.next || null;
if (clientList.next) {
this.itemCount = clientList.content.length + 2;
} else {
this.itemCount = clientList.content.length;
}
});
this.setClientsIsLoading(false);
} catch (e) {
@ -192,22 +198,23 @@ class OAuthStore implements OAuthStoreProps {
fetchNextClients = async (startIndex: number) => {
if (this.clientsIsLoading) return;
this.setClientsIsLoading(true);
const page = startIndex / PAGE_LIMIT;
console.log(page);
runInAction(() => {
this.currentPage = page + 1;
});
const clientList: ClientListProps = await getClientList(page, PAGE_LIMIT);
const clientList: IClientListProps = await getClientList(page, PAGE_LIMIT);
runInAction(() => {
this.totalPages = clientList.totalPages;
this.totalElements = clientList.totalElements;
this.currentPage = clientList.page;
this.nextPage = clientList.next || null;
this.clients = [...this.clients, ...clientList.content];
this.itemCount += clientList.content.length;
});
this.setClientsIsLoading(false);
@ -304,7 +311,7 @@ class OAuthStore implements OAuthStoreProps {
}
};
getContextMenuItems = (t: any, item: ClientProps) => {
getContextMenuItems = (t: any, item: IClientProps) => {
const { clientId } = item;
const isGroupContext = this.selection.length;
@ -416,7 +423,7 @@ class OAuthStore implements OAuthStoreProps {
}
get hasNextPage() {
return this.totalPages - this.currentPage !== 0;
return !!this.nextPage;
}
get scopeList() {

View File

@ -151,7 +151,8 @@ export const onOAuthSubmit = (
formData.append("client_id", clientId);
formData.append("state", clientState);
formData.append("scope", scope.join(","));
formData.append("scope", "accounts:write");
// formData.append("scope", scope.join(","));
return request({
method: "post",

View File

@ -5,7 +5,7 @@ import { DeviceType } from "../constants";
import { Context } from "@docspace/components/utils/context";
import { isTablet, isMobile } from "@docspace/components/utils/device";
type DeviceUnionType = (typeof DeviceType)[keyof typeof DeviceType];
export type DeviceUnionType = (typeof DeviceType)[keyof typeof DeviceType];
type useViewEffectProps = {
view: string;

View File

@ -31,6 +31,8 @@ export const transformToClientProps = (
modified_on,
website_url,
allowed_origins,
creator_avatar,
creator_display_name,
} = clientDto;
const client: IClientProps = {
@ -54,6 +56,8 @@ export const transformToClientProps = (
modifiedOn: modified_on,
websiteUrl: website_url,
allowedOrigins: allowed_origins,
creatorAvatar: creator_avatar,
creatorDisplayName: creator_display_name,
};
return client;

View File

@ -40,12 +40,15 @@ export interface IClientProps {
enabled: boolean;
invalidated: boolean;
scopes: string[];
createdOn: Date;
modifiedOn: Date;
createdBy: string;
modifiedBy: string;
websiteUrl: string;
allowedOrigins: string[];
createdOn?: Date;
modifiedOn?: Date;
createdBy?: string;
modifiedBy?: string;
creatorAvatar?: string;
creatorDisplayName?: string;
}
export interface IClientReqDTO {
@ -83,23 +86,30 @@ export interface IClientResDTO {
enabled: boolean;
tenant: number;
invalidated: boolean;
created_on: Date;
modified_on: Date;
created_by: string;
modified_by: string;
website_url: string;
allowed_origins: string[];
created_on?: Date;
modified_on?: Date;
created_by?: string;
modified_by?: string;
creator_avatar?: string;
creator_display_name?: string;
}
export interface IClientListProps {
content: IClientProps[];
page: number;
next?: number;
previous?: number;
limit: number;
}
export interface IClientListDTO {
data: IClientResDTO[];
page: number;
next?: number;
previous?: number;
limit: number;
}

View File

@ -81,10 +81,22 @@ const Consent = ({ oauth, theme, setIsConsentScreen }: IConsentProps) => {
const onAllowClick = () => {
const clientId = oauth.clientId;
const clientState = oauth.state || getCookie("client_state");
let clientState = oauth.state;
const scope = oauth.client.scopes;
api.oauth.onOAuthSubmit(clientId, clientState, scope);
const cookie = document.cookie.split(";");
if (!clientState) {
console.log(document.cookie);
cookie.forEach((c) => {
if (c.includes("client_state")) clientState = c.split("=")[1];
});
}
console.log(clientState);
// api.oauth.onOAuthSubmit(clientId, clientState, scope);
};
const onDenyClick = () => {

View File

@ -205,14 +205,18 @@
"NotFoundTitle": "Nothing found",
"NotSupportedFormat": "Sorry, this file format isn't supported",
"NOV": "NOV",
"OAuthFilesReadDescription": "View all files and folders",
"OAuthFilesWriteDescription": "View and manage all files and folders",
"OAuthRoomsReadDescription": "View all rooms",
"OAuthRoomsWriteDescription": "View and manage all rooms",
"OAuthAccountsName": "Accounts",
"OAuthAccountsReadDescription": "View all accounts",
"OAuthAccountsWriteDescription": "View and manage all accounts",
"OAuthProfileReadDescription": "View basic information about your profile",
"OAuthProfileWriteDescription": "View and manage basic information about your profile",
"OAuthFilesName": "Files & Folders",
"OAuthFilesReadDescription": "View all files and folders",
"OAuthFilesWriteDescription": "View and manage all files and folders",
"OAuthProfilesName": "Profile",
"OAuthProfilesReadDescription": "View basic information about your profile",
"OAuthProfilesWriteDescription": "View and manage basic information about your profile",
"OAuthRoomsName": "Rooms",
"OAuthRoomsReadDescription": "View all rooms",
"OAuthRoomsWriteDescription": "View and manage all rooms",
"OCT": "OCT",
"OFORMsGallery": "OFORMs gallery",
"OkButton": "Ok",