Web:Client: add feature for disabling plugin-system from server

This commit is contained in:
TimofeyBoyko 2022-08-24 12:34:53 +03:00
parent 2a2cf185e5
commit 4a29d2fab2
10 changed files with 169 additions and 85 deletions

View File

@ -31,7 +31,6 @@ import { useThemeDetector } from "SRC_DIR/helpers/utils";
import { isMobileOnly } from "react-device-detect";
import IndicatorLoader from "./components/IndicatorLoader";
import DialogsWrapper from "./components/dialogs/DialogsWrapper";
import { initPluginStore } from "./helpers/plugins";
// const { proxyURL } = AppServerConfig;
// const homepage = config.homepage;
@ -383,10 +382,6 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
});
};
useEffect(() => {
initPluginStore();
}, []);
useEffect(() => {
if (!isLoaded) return;

View File

@ -40,6 +40,7 @@ const ArticleMainButtonContent = (props) => {
currentFolderId,
isRoomsFolder,
isArchiveFolder,
enablePlugins,
} = props;
const inputFilesElement = React.useRef(null);
const inputFolderElement = React.useRef(null);
@ -239,16 +240,17 @@ const ArticleMainButtonContent = (props) => {
menuModel.push(...uploadActions);
setUploadActions(uploadActions);
}
if (enablePlugins) {
const pluginOptions = getMainButtonItems();
const pluginOptions = getMainButtonItems();
if (pluginOptions) {
pluginOptions.forEach((option) => {
menuModel.splice(option.value.position, 0, {
key: option.key,
...option.value,
if (pluginOptions) {
pluginOptions.forEach((option) => {
menuModel.splice(option.value.position, 0, {
key: option.key,
...option.value,
});
});
});
}
}
setModel(menuModel);
@ -258,6 +260,7 @@ const ArticleMainButtonContent = (props) => {
isPrivacy,
currentFolderId,
isRoomsFolder,
enablePlugins,
onCreate,
onCreateRoom,
onShowSelectFileDialog,
@ -346,6 +349,8 @@ export default inject(
const isArticleLoading = (!isLoaded || isLoading) && firstLoad;
const { enablePlugins } = auth.settingsStore;
const currentFolderId = selectedFolderStore.id;
return {
@ -372,6 +377,8 @@ export default inject(
isLoaded,
firstLoad,
currentFolderId,
enablePlugins,
};
}
)(

View File

@ -105,7 +105,7 @@ class SectionHeaderContent extends React.Component {
uploadToFolder = () => console.log("Upload To Folder click");
getContextOptionsPlus = () => {
const { t, isPrivacyFolder, isRoomsFolder } = this.props;
const { t, isPrivacyFolder, isRoomsFolder, enablePlugins } = this.props;
const options = isRoomsFolder
? [
@ -178,15 +178,17 @@ class SectionHeaderContent extends React.Component {
},*/
];
const pluginOptions = getMainButtonItems();
if (enablePlugins) {
const pluginOptions = getMainButtonItems();
if (pluginOptions) {
pluginOptions.forEach((option) => {
options.splice(option.value.position, 0, {
key: option.key,
...option.value,
if (pluginOptions) {
pluginOptions.forEach((option) => {
options.splice(option.value.position, 0, {
key: option.key,
...option.value,
});
});
});
}
}
return options;
@ -591,6 +593,8 @@ export default inject(
navigationPath,
} = selectedFolderStore;
const { enablePlugins } = auth.settingsStore;
const isRoom = !!roomType;
return {
@ -652,6 +656,8 @@ export default inject(
setAlreadyFetchingRooms,
categoryType,
enablePlugins,
};
}
)(

View File

@ -25,7 +25,13 @@ const StyledContainer = styled.div`
}
`;
const PortalPlugins = ({ t, setDocumentTitle, theme }) => {
const PortalPlugins = ({
t,
setDocumentTitle,
theme,
withDelete,
withUpload,
}) => {
const [plugins, setPlugins] = React.useState(null);
setDocumentTitle(`Portal plugins`);
@ -80,7 +86,7 @@ const PortalPlugins = ({ t, setDocumentTitle, theme }) => {
return (
<StyledContainer>
<UploadButton t={t} addPlugin={addPlugin} />
{withUpload && <UploadButton t={t} addPlugin={addPlugin} />}
{plugins && (
<PluginList
plugins={plugins}
@ -88,6 +94,7 @@ const PortalPlugins = ({ t, setDocumentTitle, theme }) => {
onDelete={onDelete}
theme={theme}
t={t}
withDelete={withDelete}
/>
)}
</StyledContainer>
@ -96,11 +103,16 @@ const PortalPlugins = ({ t, setDocumentTitle, theme }) => {
export default inject(({ auth }) => {
const { settingsStore, setDocumentTitle } = auth;
const { theme } = settingsStore;
const { theme, pluginOptions } = settingsStore;
const withUpload = pluginOptions.includes("upload");
const withDelete = pluginOptions.includes("delete");
return {
theme,
setDocumentTitle,
withUpload,
withDelete,
};
})(
withTranslation([

View File

@ -30,7 +30,7 @@ const StyledHeader = styled.div`
.plugins__text-container {
display: flex;
margin-left: 6px;
width: 70%;
width: 30%;
}
.plugins__separator {
@ -48,9 +48,24 @@ const StyledRow = styled(Row)`
.row-main-container-wrapper {
margin-right: 40px;
}
.plugin-version {
margin-left: 8px;
}
.plugin-status {
margin-left: 30px;
}
`;
const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
const PluginList = ({
t,
plugins,
onActivate,
onDelete,
withDelete,
theme,
}) => {
const onActivateAction = React.useCallback(
(e) => {
const { dataset } = (e.originalEvent || e).currentTarget;
@ -73,6 +88,7 @@ const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
const getContextOptions = React.useCallback(
(plugin, index) => {
const options = [];
const activateItem = plugin.isActive
? {
key: `${index}_disable`,
@ -96,9 +112,13 @@ const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
onClick: onDeleteAction,
};
return [activateItem, deleteItem];
options.push(activateItem);
withDelete && options.push(deleteItem);
return options;
},
[onActivateAction, onDeleteAction]
[onActivateAction, onDeleteAction, withDelete]
);
return (
@ -113,7 +133,19 @@ const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
>
{t("Common: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
>
{t("People:UserStatus")}
</Text>
</div>
<div className="plugins__text-container">
<div className="plugins__separator" />
@ -149,9 +181,21 @@ const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
noSelect
containerWidth="30%"
>
{name} {version}
{name}
</Text>
<div></div>
<Text
className="plugin-version"
as="div"
type="page"
fontSize="13px"
fontWeight={600}
title={plugin.name}
noSelect
containerWidth="30%"
>
{version}
</Text>
<Text
as="div"
@ -160,7 +204,8 @@ const PluginList = ({ t, plugins, onActivate, onDelete, theme }) => {
fontWeight={600}
title={plugin.isActive ? "Active" : "Disabled"}
noSelect
containerWidth="70%"
containerWidth="40%"
className="plugin-status"
>
{plugin.isActive ? "Active" : "Disabled"}
</Text>

View File

@ -2,7 +2,7 @@ import React from "react";
import Button from "@docspace/components/button";
import api from "SRC_DIR/helpers/plugins/api";
import api from "@docspace/common/api";
import { initPlugin } from "SRC_DIR/helpers/plugins";
const UploadButton = ({ t, addPlugin }) => {
@ -19,7 +19,7 @@ const UploadButton = ({ t, addPlugin }) => {
}
try {
const plugin = await api.uploadPlugin(formData);
const plugin = await api.plugins.uploadPlugin(formData);
initPlugin(plugin, addPlugin);
// addPlugin(plugin);

View File

@ -17,7 +17,7 @@ import AppLoader from "@docspace/common/components/AppLoader";
import SSOLoader from "./sub-components/ssoLoader";
const IntegrationWrapper = (props) => {
const { t, tReady, history, loadBaseInfo } = props;
const { t, tReady, history, loadBaseInfo, enablePlugins } = props;
const [currentTab, setCurrentTab] = useState(0);
const [isLoading, setIsLoading] = useState(false);
@ -48,7 +48,7 @@ const IntegrationWrapper = (props) => {
if (!isMobile) {
data.push(integrationData);
data.push(pluginData);
enablePlugins && data.push(pluginData);
}
const load = async () => {
@ -79,13 +79,16 @@ const IntegrationWrapper = (props) => {
return <Submenu data={data} startSelect={currentTab} onSelect={onSelect} />;
};
export default inject(({ setup }) => {
export default inject(({ setup, auth }) => {
const { initSettings } = setup;
const { enablePlugins } = auth.settingsStore;
return {
loadBaseInfo: async () => {
await initSettings();
},
enablePlugins,
};
})(
withTranslation(["Settings", "SingleSignOn"])(

View File

@ -368,6 +368,9 @@ class ContextOptionsStore {
getFilesContextOptions = (item, t) => {
const { contextOptions } = item;
const { enablePlugins } = this.settingsStore;
const isRootThirdPartyFolder =
item.providerKey && item.id === item.rootFolderId;
@ -721,29 +724,30 @@ class ContextOptionsStore {
const options = this.filterModel(optionsModel, contextOptions);
const pluginOptions = getContextMenuItems();
if (enablePlugins) {
const pluginOptions = getContextMenuItems();
if (pluginOptions) {
pluginOptions.forEach((option) => {
if (contextOptions.includes(option.key)) {
const value = option.value;
if (!value.onClick) {
options.splice(value.position, 0, {
key: option.key,
...value,
});
} else {
options.splice(value.position, 0, {
key: option.key,
label: value.label,
icon: value.icon,
onClick: () => value.onClick(item),
});
if (pluginOptions) {
pluginOptions.forEach((option) => {
if (contextOptions.includes(option.key)) {
const value = option.value;
if (!value.onClick) {
options.splice(value.position, 0, {
key: option.key,
...value,
});
} else {
options.splice(value.position, 0, {
key: option.key,
label: value.label,
icon: value.icon,
onClick: () => value.onClick(item),
});
}
}
}
});
});
}
}
return options;
};

View File

@ -1041,6 +1041,8 @@ class FilesStore {
canFormFillingDocs,
} = this.filesSettingsStore;
const { enablePlugins } = this.settingsStore;
const isThirdPartyFolder =
item.providerKey && item.id === item.rootFolderId;
const isShareItem = isShare(item.rootFolderType);
@ -1050,9 +1052,8 @@ class FilesStore {
const { personal } = this.settingsStore;
const { isDesktopClient } = this.authStore.settingsStore;
const pluginAllKeys = getContextMenuKeysByType(
PluginContextMenuItemType.All
);
const pluginAllKeys =
enablePlugins && getContextMenuKeysByType(PluginContextMenuItemType.All);
if (isFile) {
const shouldFillForm = canFormFillingDocs(item.fileExst);
@ -1239,13 +1240,16 @@ class FilesStore {
} else {
fileOptions = this.removeOptions(fileOptions, ["restore"]);
const pluginFilesKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Files
);
if (enablePlugins) {
const pluginFilesKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Files
);
pluginAllKeys && pluginAllKeys.forEach((key) => fileOptions.push(key));
pluginFilesKeys &&
pluginFilesKeys.forEach((key) => fileOptions.push(key));
pluginAllKeys &&
pluginAllKeys.forEach((key) => fileOptions.push(key));
pluginFilesKeys &&
pluginFilesKeys.forEach((key) => fileOptions.push(key));
}
}
if (!isFullAccess) {
@ -1400,13 +1404,16 @@ class FilesStore {
"unarchive-room",
]);
const pluginRoomsKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Rooms
);
if (enablePlugins) {
const pluginRoomsKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Rooms
);
pluginAllKeys && pluginAllKeys.forEach((key) => roomOptions.push(key));
pluginRoomsKeys &&
pluginRoomsKeys.forEach((key) => roomOptions.push(key));
pluginAllKeys &&
pluginAllKeys.forEach((key) => roomOptions.push(key));
pluginRoomsKeys &&
pluginRoomsKeys.forEach((key) => roomOptions.push(key));
}
}
return roomOptions;
@ -1484,14 +1491,16 @@ class FilesStore {
} else {
folderOptions = this.removeOptions(folderOptions, ["restore"]);
const pluginFoldersKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Folders
);
if (enablePlugins) {
const pluginFoldersKeys = getContextMenuKeysByType(
PluginContextMenuItemType.Folders
);
pluginAllKeys &&
pluginAllKeys.forEach((key) => folderOptions.push(key));
pluginFoldersKeys &&
pluginFoldersKeys.forEach((key) => folderOptions.push(key));
pluginAllKeys &&
pluginAllKeys.forEach((key) => folderOptions.push(key));
pluginFoldersKeys &&
pluginFoldersKeys.forEach((key) => folderOptions.push(key));
}
}
if (!isFullAccess) {

View File

@ -90,6 +90,7 @@ class ProfileActionsStore {
};
getActions = (t) => {
const { enablePlugins } = this.authStore.settingsStore;
const isAdmin = this.authStore.isAdmin;
// const settingsModule = modules.find((module) => module.id === "settings");
// const peopleAvailable = modules.some((m) => m.appName === "people");
@ -195,15 +196,17 @@ class ProfileActionsStore {
});
}
const pluginActions = getProfileMenuItems();
if (enablePlugins) {
const pluginActions = getProfileMenuItems();
if (pluginActions) {
pluginActions.forEach((option) => {
actions.splice(option.value.position, 0, {
key: option.key,
...option.value,
if (pluginActions) {
pluginActions.forEach((option) => {
actions.splice(option.value.position, 0, {
key: option.key,
...option.value,
});
});
});
}
}
return actions;