Web:Client: add feature for disabling plugin-system from server
This commit is contained in:
parent
2a2cf185e5
commit
4a29d2fab2
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -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([
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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"])(
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user