Web:PortalSettings:PortalPlugins: add simple plugins list and upload button

This commit is contained in:
TimofeyBoyko 2022-08-03 18:45:49 +03:00
parent 177e415b83
commit 6445e83f24
3 changed files with 311 additions and 0 deletions

View File

@ -0,0 +1,86 @@
import React from "react";
import styled from "styled-components";
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
import UploadButton from "./sub-components/upload-button";
import PluginList from "./sub-components/plugin-list";
const StyledContainer = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.plugins__upload-button {
width: 110px;
margin-bottom: 24px;
}
.custom-plugin-input {
display: none;
}
`;
const PortalPlugins = ({ t, setDocumentTitle, theme }) => {
const [plugins, setPlugins] = React.useState(null);
setDocumentTitle(`Portal plugins`);
const onActivate = React.useCallback(
(id, status) => {
setPlugins((val) => {
const newPlugins = val;
const idx = newPlugins.findIndex((plugin) => +plugin.id === +id);
if (idx > -1) {
newPlugins[idx].isActive = status === "true";
}
return [...newPlugins];
});
},
[plugins]
);
const addPlugin = React.useCallback((plugin) => {
setPlugins((value) => {
if (value) return [...value, plugin];
return [plugin];
});
}, []);
React.useEffect(() => {
const newPlugins = [];
Array.from(window.PluginStore.plugins, ([key, value]) =>
newPlugins.push(value)
);
setPlugins(newPlugins);
}, [window.PluginStore]);
return (
<StyledContainer>
<UploadButton t={t} addPlugin={addPlugin} />
{plugins && (
<PluginList plugins={plugins} onActivate={onActivate} theme={theme} />
)}
</StyledContainer>
);
};
export default inject(({ auth }) => {
const { settingsStore, setDocumentTitle } = auth;
const { theme } = settingsStore;
return {
theme,
setDocumentTitle,
};
})(withTranslation(["Settings", "Common"])(observer(PortalPlugins)));

View File

@ -0,0 +1,160 @@
import React from "react";
import styled from "styled-components";
import { isMobile } from "react-device-detect";
import RowContainer from "@docspace/components/row-container";
import RowContent from "@docspace/components/row-content";
import Row from "@docspace/components/row";
import Text from "@docspace/components/text";
import { tablet } from "@docspace/components/utils/device";
import { Base } from "@docspace/components/themes";
import { activatePlugin } from "SRC_DIR/helpers/plugins";
const StyledHeader = styled.div`
display: ${isMobile ? "none" : "flex"};
border-bottom: ${(props) => props.theme.connectedClouds.borderBottom};
padding-bottom: 12px;
@media ${tablet} {
display: none;
}
.plugins__plugin {
width: 30%;
margin-right: 12px;
}
.plugins__text-container {
display: flex;
margin-left: 6px;
width: 70%;
}
.plugins__separator {
display: block;
height: 10px;
margin: 4px 8px 0 0;
z-index: 1;
border-right: ${(props) => props.theme.connectedClouds.borderRight};
}
`;
StyledHeader.defaultProps = { theme: Base };
const StyledRow = styled(Row)`
.row-main-container-wrapper {
margin-right: 40px;
}
`;
const PluginList = ({ plugins, onActivate, theme }) => {
const onActivateAction = React.useCallback(
(e) => {
const { dataset } = (e.originalEvent || e).currentTarget;
activatePlugin(dataset.id, dataset.status);
onActivate(dataset.id, dataset.status);
},
[onActivate]
);
const getContextOptions = React.useCallback(
(plugin, index) => {
const activateItem = plugin.isActive
? {
key: `${index}_disable`,
"data-id": plugin.id,
"data-status": !plugin.isActive,
label: "Disable",
onClick: onActivateAction,
}
: {
key: `${index}_activate`,
"data-id": plugin.id,
"data-status": !plugin.isActive,
label: "Activate",
onClick: onActivateAction,
};
return [activateItem];
},
[onActivateAction]
);
return (
<>
<StyledHeader>
<Text
className="plugins__plugin"
fontSize="12px"
fontWeight={600}
color={theme.connectedClouds.color}
noSelect
>
Plugin
</Text>
<div></div>
<div className="plugins__text-container">
<div className="plugins__separator" />
<Text
className="plugins__status"
fontSize="12px"
fontWeight={600}
color={theme.connectedClouds.color}
noSelect
>
Status
</Text>
</div>
</StyledHeader>
<RowContainer useReactWindow={false}>
{plugins
? plugins.map((plugin, index) => {
const name = plugin.getPluginName();
const version = plugin.getPluginVersion();
return (
<StyledRow
key={plugin.id}
contextOptions={getContextOptions(plugin, index)}
>
<RowContent>
<Text
as="div"
type="page"
fontSize="13px"
fontWeight={600}
title={plugin.name}
noSelect
containerWidth="30%"
>
{name} {version}
</Text>
<div></div>
<Text
as="div"
type="page"
fontSize="13px"
fontWeight={600}
title={plugin.isActive ? "Active" : "Disabled"}
noSelect
containerWidth="70%"
>
{plugin.isActive ? "Active" : "Disabled"}
</Text>
</RowContent>
</StyledRow>
);
})
: "Loading"}
</RowContainer>
</>
);
};
export default React.memo(PluginList);

View File

@ -0,0 +1,65 @@
import React from "react";
import Button from "@docspace/components/button";
import api from "SRC_DIR/helpers/plugins/api";
import { initPlugin } from "SRC_DIR/helpers/plugins";
const UploadButton = ({ t, addPlugin }) => {
const inputPluginElement = React.useRef(null);
const uploadPlugin = React.useCallback(
async (files) => {
if (!files) return;
let formData = new FormData();
for (let index in Object.keys(files)) {
formData.append(files[index].name, files[index]);
}
try {
const plugin = await api.uploadPlugin(formData);
initPlugin(plugin, addPlugin);
// addPlugin(plugin);
} catch (e) {
console.log(e);
}
},
[addPlugin]
);
const onInput = React.useCallback(
(e) => {
uploadPlugin(e.target.files);
e.target.value = null;
},
[uploadPlugin]
);
const onUploadPluginClick = React.useCallback(() => {
inputPluginElement.current.click();
}, [inputPluginElement.current]);
return (
<>
<Button
className={"plugins__upload-button"}
size={"small"}
label={"Upload plugin"}
primary
onClick={onUploadPluginClick}
/>
<input
ref={inputPluginElement}
id="customPluginInput"
className="custom-plugin-input"
type="file"
onInput={onInput}
/>
</>
);
};
export default React.memo(UploadButton);