Web: Client: OAuth: Added view page

This commit is contained in:
Ilya Oleshko 2023-06-27 17:51:01 +03:00
parent fbaace1941
commit e173c5932d
8 changed files with 250 additions and 94 deletions

View File

@ -18,28 +18,103 @@ const Container = styled.div`
margin-top: 5px;
`;
const Property = styled.div`
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 16px;
`;
const OAuthDetails = (props) => {
const { t, setDocumentTitle } = props;
const { t, setDocumentTitle, currentClient } = props;
setDocumentTitle("OAuth");
return (
<>
{isMobile ? (
<BreakpointWarning sectionName={"OAuth"} />
) : (
<Container>Test</Container>
)}
<Container>
<Property>
<Label htmlFor="name" text="Name:" title="Fill the client name" />
<TextInput id="name" value={currentClient.name} />
</Property>
<Property>
<Label
htmlFor="description"
text="Description:"
title="Fill the client description"
/>
<TextInput id="description" value={currentClient.description} scale />
</Property>
<Property>
<Label htmlFor="id" text="Id:" title="Client id" />
<TextInput id="id" value={currentClient.client_id} isDisabled scale />
</Property>
<Property>
<Label htmlFor="secret" text="Secret:" title="Client secret" />
<TextInput
id="secret"
value={currentClient.client_secret}
isDisabled
scale
/>
</Property>
<Property>
<Label htmlFor="rootUrl" text="Root url:" title="Root url" />
<TextInput
id="rootUrl"
value={currentClient.root_url}
isReadOnly
scale
/>
</Property>
<Property>
<Label
htmlFor="redirectUris"
text="Redirect uris:"
title="Redirect uris"
/>
<TextInput
id="redirectUris"
value={currentClient.redirect_uris}
isReadOnly
scale
/>
</Property>
<Property>
<Label
htmlFor="allowedOrigins"
text="Allowed origins:"
title="Allowed origins"
/>
<TextInput
id="allowedOrigins"
value={currentClient.allowed_origins}
isReadOnly
scale
/>
</Property>
<Property>
<Label htmlFor="scopes" text="Scopes:" title="Scopes" />
<TextInput
id="scopes"
value={currentClient.scopes}
isReadOnly
scale
/>
</Property>
</Container>
</>
);
};
export default inject(({ setup, auth }) => {
export default inject(({ setup, auth, oauthStore }) => {
const { settingsStore, setDocumentTitle } = auth;
const { theme } = settingsStore;
const { currentClient } = oauthStore;
return {
theme,
setDocumentTitle,
currentClient,
};
})(withTranslation(["Common"])(observer(OAuthDetails)));

View File

@ -13,29 +13,49 @@ import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
import BreakpointWarning from "SRC_DIR/components/BreakpointWarning";
import List from "./sub-components/List";
import DeleteDialog from "./sub-components/DeleteDialog";
const OAuth = (props) => {
const { t, setDocumentTitle } = props;
const {
t,
setDocumentTitle,
getClients,
deleteClient,
currentClient,
} = props;
const [isDeleteOpened, setIsDeleteOpened] = useState(false);
const closeDeleteModal = () => setIsDeleteOpened(false);
const openDeleteModal = () => setIsDeleteOpened(true);
useEffect(() => getClients(), []);
setDocumentTitle("OAuth");
return (
<>
{isMobile ? (
<BreakpointWarning sectionName={"OAuth"} />
) : (
<List openSettingsModal={() => {}} openDeleteModal={() => {}} />
)}
<List openDeleteModal={openDeleteModal} />
<DeleteDialog
visible={isDeleteOpened}
onClose={closeDeleteModal}
handleSubmit={deleteClient}
currentClient={currentClient}
/>
</>
);
};
export default inject(({ setup, auth }) => {
export default inject(({ setup, auth, oauthStore }) => {
const { settingsStore, setDocumentTitle } = auth;
const { getClients, deleteClient, currentClient } = oauthStore;
const { theme } = settingsStore;
return {
theme,
setDocumentTitle,
getClients,
deleteClient,
currentClient,
};
})(withTranslation(["Common"])(observer(OAuth)));

View File

@ -0,0 +1,71 @@
import React, { useEffect } from "react";
import ModalDialog from "@docspace/components/modal-dialog";
import Button from "@docspace/components/button";
import styled from "styled-components";
import { useTranslation } from "react-i18next";
const StyledBodyText = styled.div`
line-height: 20px;
`;
const Footer = styled.div`
width: 100%;
display: flex;
button {
width: 100%;
}
button:first-of-type {
margin-right: 10px;
}
`;
const DeleteDialog = ({
visible,
onClose,
header,
handleSubmit,
currentClient,
}) => {
const onKeyPress = (e) =>
(e.key === "Esc" || e.key === "Escape") && onClose();
const { t } = useTranslation(["Common", "EmptyTrashDialog"]);
useEffect(() => {
window.addEventListener("keyup", onKeyPress);
return () => window.removeEventListener("keyup", onKeyPress);
});
const handleDeleteClick = () => {
handleSubmit(currentClient.id);
onClose();
};
return (
<ModalDialog visible={visible} onClose={onClose} displayType="modal">
<ModalDialog.Header>{`Delete profile`}</ModalDialog.Header>
<ModalDialog.Body>
<StyledBodyText>{`Do you want to delete profile: ${currentClient.name}`}</StyledBodyText>
</ModalDialog.Body>
<ModalDialog.Footer>
<Footer>
<Button
label={t("Common:Delete")}
size="normal"
primary={true}
onClick={handleDeleteClick}
/>
<Button
label={t("Common:CancelButton")}
size="normal"
onClick={onClose}
/>
</Footer>
</ModalDialog.Footer>
</ModalDialog>
);
};
export default DeleteDialog;

View File

@ -84,11 +84,11 @@ const Header = (props) => {
setColumns((prevColumns) =>
prevColumns.map((item, index) =>
index === columnIndex ? { ...item, enable: !item.enable } : item
index === columnIndex ? { ...item, enabled: !item.enabled } : item
)
);
const tableColumns = columns.map((c) => c.enable && c.key);
const tableColumns = columns.map((c) => c.enabled && c.key);
localStorage.setItem(`${TABLE_COLUMNS}=${userId}`, tableColumns);
}

View File

@ -45,21 +45,35 @@ const Row = (props) => {
const {
item,
setEnabled,
openSettingsModal,
openDeleteModal,
setCurrentProject,
setCurrentClient,
hideColumns,
} = props;
const navigate = useNavigate();
const { t } = useTranslation(["Webhooks", "Common"]);
const [isChecked, setIsChecked] = useState(item.token.enable);
const [isChecked, setIsChecked] = useState(item.enabled);
const redirectToHistory = () => {
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") ||
@ -72,20 +86,7 @@ const Row = (props) => {
return;
}
redirectToHistory();
};
const handleToggleEnabled = () => {
setEnabled(item.id);
setIsChecked((prevIsChecked) => !prevIsChecked);
};
const onSettingsOpen = () => {
setCurrentProject(item);
//openSettingsModal();
};
const onDeleteOpen = () => {
setCurrentProject(item);
//openDeleteModal();
onSettingsOpen();
};
const contextOptions = [
@ -119,12 +120,12 @@ const Row = (props) => {
</TableCell>
<TableCell>
<Text as="span" fontWeight={600} className="mr-8 textOverflow">
{item.general.name}
{item.name}
</Text>
</TableCell>
<TableCell>
<Text as="span" fontWeight={400} className="mr-8 textOverflow">
{item.general.description}
{item.description}
</Text>
</TableCell>
<TableCell>
@ -141,7 +142,7 @@ const Row = (props) => {
};
export default inject(({ oauthStore }) => {
const { setCurrentProject, setEnabled } = oauthStore;
const { setCurrentClient, setEnabled } = oauthStore;
return { setEnabled, setCurrentProject };
return { setEnabled, setCurrentClient };
})(observer(Row));

View File

@ -42,7 +42,7 @@ const INFO_PANEL_COLUMNS_SIZE = `infoPanelOauthConfigColumnsSize_ver-${TABLE_VER
const TableView = (props) => {
const {
items,
getProjects,
getClients,
sectionWidth,
viewAs,
setViewAs,
@ -82,7 +82,7 @@ const TableView = (props) => {
columnStorageName={columnStorageName}
columnInfoPanelStorageName={columnInfoPanelStorageName}
filesLength={items.length}
fetchMoreFiles={getProjects}
fetchMoreFiles={getClients}
hasMoreFiles={false}
itemCount={items.length}
>
@ -102,7 +102,7 @@ const TableView = (props) => {
};
export default inject(({ oauthStore, setup, auth }) => {
const { getProjects } = oauthStore;
const { getClients } = oauthStore;
const { viewAs, setViewAs } = setup;
const { id: userId } = auth.userStore.user;
@ -110,7 +110,7 @@ export default inject(({ oauthStore, setup, auth }) => {
return {
viewAs,
setViewAs,
getProjects,
getClients,
userId,
};
})(observer(TableView));

View File

@ -5,12 +5,12 @@ import { Consumer } from "@docspace/components/utils/context";
import TableView from "./TableView";
const List = ({ viewAs, openSettingsModal, openDeleteModal, projects }) => {
const List = ({ viewAs, openSettingsModal, openDeleteModal, clients }) => {
return (
<Consumer>
{(context) => (
<TableView
items={projects}
items={clients}
sectionWidth={context.sectionWidth}
openSettingsModal={openSettingsModal}
openDeleteModal={openDeleteModal}
@ -21,10 +21,10 @@ const List = ({ viewAs, openSettingsModal, openDeleteModal, projects }) => {
};
export default inject(({ setup, oauthStore }) => {
const { viewAs } = setup;
const { projects } = oauthStore;
const { clients } = oauthStore;
return {
viewAs,
projects,
clients,
};
})(observer(List));

View File

@ -1,78 +1,67 @@
import { makeAutoObservable, runInAction } from "mobx";
const projects = [...Array(10)].map((value, index) => {
const clients = [...Array(5)].map((value, index) => {
return {
id: index,
general: {
name: `Project ${index}`,
description: `Description ${index}`,
},
credentials: {
client_id: "random_client_id",
client_secret: "random_client_secret",
},
token: {
enable: true,
bearer_only: true,
public_client: false,
},
scopes: {
files: {
read: true,
write: true,
},
workspaces: {
read: false,
write: false,
},
users: {
read: false,
write: false,
},
},
links: {
installation_url: "https://example.com/install",
redirect_url: "https://example.com/redirect",
allowed_origins: "https://example.com",
},
name: `46192a5a-e19c-${index}`,
description: "Demo description",
client_id: "46192a5a-e19c-453c-aec3-50617290edbe",
client_secret: "e5ff57e4-4ce2-4dac-a265-88bc7e726684",
root_url: "https://google.com",
redirect_uris: ["https://openidconnect.net/callback"],
allowed_origins: [
"https://google.com",
"https://openidconnect.net/callback",
],
scopes: [
"files:write",
"accounts:write",
"files:read",
"account.self:write",
"rooms:read",
"accounts:read",
"account.self:read",
"rooms:write",
],
enabled: true,
};
});
class OAuthStore {
projects = projects;
currentProject = {};
clients = [];
currentClient = clients[0];
constructor() {
makeAutoObservable(this);
}
getProjects = () => {
this.projects = projects;
getClients = () => {
this.clients = clients;
};
setCurrentProject = (project) => {
this.currentProject = project;
setCurrentClient = (client) => {
this.currentClient = client;
};
addProject = (project) => {
this.projects = [...this.projects, project];
addClient = (client) => {
this.clients = [...this.clients, client];
};
setEnabled = (id) => {
const index = this.projects.findIndex((proj) => proj.id === id);
const index = this.clients.findIndex((proj) => proj.id === id);
this.projects[index].token.enable = !this.projects[index].token.enable;
this.clients[index].enabled = !this.clients[index].enabled;
};
deleteProject = (id) => {
this.projects = this.projects.filter((proj) => proj.id !== id);
deleteClient = (id) => {
this.clients = this.clients.filter((proj) => proj.id !== id);
};
editProject = (project) => {
const index = this.projects.findIndex((proj) => proj.id === project.id);
editClient = (client) => {
const index = this.clients.findIndex((proj) => proj.id === client.id);
runInAction(() => {
this.projects[index] = project;
this.clients[index] = client;
});
};
}