MM-61297 - remove unused code (#29354)
* MM-61297 - remove unused code * remove unused code for install plugin in backend * fix translations
Этот коммит содержится в:
@@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {isCustomPostProps, type CustomPostProps} from '.';
|
||||
|
||||
describe('isCustomPostProps', () => {
|
||||
it('no content', () => {
|
||||
const props: CustomPostProps = {
|
||||
requested_plugins_by_plugin_ids: {},
|
||||
requested_plugins_by_user_ids: {},
|
||||
};
|
||||
expect(isCustomPostProps(props)).toBe(true);
|
||||
});
|
||||
|
||||
it('content but no elements', () => {
|
||||
const props: CustomPostProps = {
|
||||
requested_plugins_by_plugin_ids: {'some id': []},
|
||||
requested_plugins_by_user_ids: {'some id': []},
|
||||
};
|
||||
expect(isCustomPostProps(props)).toBe(true);
|
||||
});
|
||||
|
||||
it('content with elements', () => {
|
||||
const props: CustomPostProps = {
|
||||
requested_plugins_by_plugin_ids: {'some id': [{
|
||||
user_id: '123',
|
||||
}]},
|
||||
requested_plugins_by_user_ids: {'some id': [{
|
||||
user_id: '123',
|
||||
}]},
|
||||
};
|
||||
expect(isCustomPostProps(props)).toBe(true);
|
||||
});
|
||||
|
||||
it('all values are required', () => {
|
||||
const baseProp: CustomPostProps = {
|
||||
requested_plugins_by_plugin_ids: {},
|
||||
requested_plugins_by_user_ids: {},
|
||||
};
|
||||
|
||||
expect(isCustomPostProps(baseProp)).toBe(true);
|
||||
|
||||
for (const key of Object.keys(baseProp)) {
|
||||
const wrongProp: Partial<CustomPostProps> = {...baseProp};
|
||||
delete wrongProp[key as keyof CustomPostProps];
|
||||
expect(isCustomPostProps(wrongProp)).toBe(false);
|
||||
}
|
||||
|
||||
const wrongProp: DeepPartial<CustomPostProps> = {
|
||||
requested_plugins_by_plugin_ids: {'some id': [{}]},
|
||||
requested_plugins_by_user_ids: {'some id': []},
|
||||
};
|
||||
expect(isCustomPostProps(wrongProp)).toBe(false);
|
||||
});
|
||||
|
||||
it('common false cases', () => {
|
||||
expect(isCustomPostProps('')).toBe(false);
|
||||
expect(isCustomPostProps(undefined)).toBe(false);
|
||||
expect(isCustomPostProps(true)).toBe(false);
|
||||
expect(isCustomPostProps(1)).toBe(false);
|
||||
expect(isCustomPostProps([])).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -1,342 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import uniqWith from 'lodash/uniqWith';
|
||||
import React, {useEffect, useMemo} from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useSelector, useDispatch} from 'react-redux';
|
||||
import {Link} from 'react-router-dom';
|
||||
|
||||
import type {MarketplacePlugin} from '@mattermost/types/marketplace';
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
import {isArrayOf, isRecordOf} from '@mattermost/types/utilities';
|
||||
|
||||
import {getMissingProfilesByIds} from 'mattermost-redux/actions/users';
|
||||
import {getUsers} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {fetchListing, installPlugin} from 'actions/marketplace';
|
||||
import {getError, getInstalledListing, getInstalling, getPlugins} from 'selectors/views/marketplace';
|
||||
|
||||
import Markdown from 'components/markdown';
|
||||
import MarketplaceModal from 'components/plugin_marketplace/marketplace_modal';
|
||||
import ToggleModalButton from 'components/toggle_modal_button';
|
||||
|
||||
import {ModalIdentifiers} from 'utils/constants';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
// We only define the props used in this component for
|
||||
// clarity. If more props are needed in the future,
|
||||
// feel free to add them.
|
||||
type PluginRequest = {
|
||||
user_id: string;
|
||||
}
|
||||
|
||||
function isPluginRequest(v: unknown): v is PluginRequest {
|
||||
if (typeof v !== 'object' || v === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const request = v as PluginRequest;
|
||||
|
||||
if (typeof request.user_id !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
type RequestedPlugins = Record<string, PluginRequest[]>
|
||||
|
||||
export type CustomPostProps = {
|
||||
requested_plugins_by_plugin_ids: RequestedPlugins;
|
||||
requested_plugins_by_user_ids: RequestedPlugins;
|
||||
}
|
||||
|
||||
export function isCustomPostProps(v: unknown): v is CustomPostProps {
|
||||
if (typeof v !== 'object' || !v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const props = v as CustomPostProps;
|
||||
|
||||
if (!isRecordOf(props.requested_plugins_by_plugin_ids, (e) => isArrayOf(e, isPluginRequest))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isRecordOf(props.requested_plugins_by_user_ids, (e) => isArrayOf(e, isPluginRequest))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const usersListStyle = {
|
||||
margin: '20px 0',
|
||||
};
|
||||
|
||||
const InstallLink = (props: {pluginId: string; pluginName: string}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<Link
|
||||
to='#'
|
||||
onClick={() => dispatch(installPlugin(props.pluginId))}
|
||||
style={{color: 'var(--denim-button-bg)', fontWeight: '600'}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='marketplace_modal.list.install.plugin'
|
||||
defaultMessage={'Install {plugin}'}
|
||||
values={{
|
||||
plugin: props.pluginName,
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const ConfigureLink = (props: {pluginId: string; pluginName: string}) => {
|
||||
return (
|
||||
<>
|
||||
<FormattedMessage
|
||||
id='postypes.custom_open_plugin_install_post_rendered.plugins_installed'
|
||||
defaultMessage={`${props.pluginName} is now installed.`}
|
||||
values={{
|
||||
pluginName: props.pluginName,
|
||||
}}
|
||||
/>
|
||||
{' '}
|
||||
<Link
|
||||
to={'/admin_console/plugins/plugin_' + props.pluginId}
|
||||
style={{color: 'var(--denim-button-bg)', fontWeight: '600'}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='marketplace_modal.list.configure.plugin'
|
||||
defaultMessage={'Configure {plugin}'}
|
||||
values={{
|
||||
plugin: props.pluginName,
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const InstallAndConfigureLink = (props: {pluginId: string; pluginName: string}) => {
|
||||
const installedListing = useSelector(getInstalledListing) as MarketplacePlugin[];
|
||||
const error = useSelector((state: GlobalState) => getError(state, props.pluginId));
|
||||
|
||||
const isInstalled = installedListing.some((plugin) => plugin.manifest.id === props.pluginId);
|
||||
const installing = useSelector((state: GlobalState) => getInstalling(state, props.pluginId));
|
||||
if (installing) {
|
||||
return (
|
||||
<span style={{fontStyle: 'italic', color: 'var(--online-indicator)', fontWeight: '600'}}>
|
||||
<FormattedMessage
|
||||
id='marketplace_modal.installing'
|
||||
defaultMessage='Installing...'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
} else if (!isInstalled && !error) {
|
||||
return (
|
||||
<InstallLink
|
||||
pluginId={props.pluginId}
|
||||
pluginName={props.pluginName}
|
||||
/>);
|
||||
} else if (isInstalled && !error) {
|
||||
return (
|
||||
<ConfigureLink
|
||||
pluginId={props.pluginId}
|
||||
pluginName={props.pluginName}
|
||||
/>);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default function OpenPluginInstallPost(props: {post: Post}) {
|
||||
const customMessageBody = [];
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const {formatMessage, formatList} = useIntl();
|
||||
|
||||
const postProps = isCustomPostProps(props.post.props) ? props.post.props : undefined;
|
||||
const requestedPluginsByPluginIds = postProps?.requested_plugins_by_plugin_ids;
|
||||
const requestedPluginsByUserIds = postProps?.requested_plugins_by_user_ids;
|
||||
|
||||
const userProfiles = useSelector(getUsers);
|
||||
const marketplacePlugins: MarketplacePlugin[] = useSelector(getPlugins);
|
||||
const marketplacePluginsNamesById = useMemo(() => {
|
||||
return marketplacePlugins.reduce<Record<string, string>>((acc, v) => {
|
||||
acc[v.manifest.id] = v.manifest.name;
|
||||
return acc;
|
||||
}, {});
|
||||
}, [marketplacePlugins]);
|
||||
|
||||
const getUserIdsForUsersThatRequestedFeature = (requests: PluginRequest[]): string[] => requests.map((request: PluginRequest) => request.user_id);
|
||||
|
||||
useEffect(() => {
|
||||
if (!marketplacePlugins.length) {
|
||||
dispatch(fetchListing());
|
||||
}
|
||||
}, [dispatch, marketplacePlugins.length]);
|
||||
|
||||
useEffect(() => {
|
||||
// process the plugins once the marketplace plugins are fetched and the plugins are available from the props
|
||||
if (requestedPluginsByPluginIds && marketplacePlugins.length) {
|
||||
for (const pluginId of Object.keys(requestedPluginsByPluginIds)) {
|
||||
dispatch(getMissingProfilesByIds(getUserIdsForUsersThatRequestedFeature(requestedPluginsByPluginIds[pluginId])));
|
||||
}
|
||||
}
|
||||
}, [dispatch, marketplacePlugins, requestedPluginsByPluginIds]);
|
||||
|
||||
const createUsernameMessage = (requests: PluginRequest[]) => {
|
||||
if (requests.length >= 5) {
|
||||
return formatMessage({
|
||||
id: 'postypes.custom_open_pricing_modal_post_renderer.members',
|
||||
defaultMessage: '{members} members',
|
||||
}, {members: requests.length});
|
||||
}
|
||||
|
||||
let usernameMessage;
|
||||
const users = getUserNamesForUsersThatRequestedFeature(requests);
|
||||
|
||||
if (users.length === 1) {
|
||||
usernameMessage = users[0];
|
||||
} else {
|
||||
const lastUser = users.splice(-1, 1)[0];
|
||||
users.push(formatMessage({id: 'postypes.custom_open_pricing_modal_post_renderer.and', defaultMessage: 'and'}) + ' ' + lastUser);
|
||||
usernameMessage = users.join(', ').replace(/,([^,]*)$/, '$1');
|
||||
}
|
||||
|
||||
return usernameMessage;
|
||||
};
|
||||
const getUserNamesForUsersThatRequestedFeature = (requests: PluginRequest[]): string[] => {
|
||||
const userNames = requests.map((req: PluginRequest) => {
|
||||
return getUserNameForUser(req.user_id);
|
||||
});
|
||||
return userNames;
|
||||
};
|
||||
|
||||
const getUserNameForUser = (userId: string) => {
|
||||
const unknownName = formatMessage({id: 'postypes.custom_open_pricing_modal_post_renderer.unknown', defaultMessage: '@unknown'});
|
||||
const username = userProfiles[userId]?.username;
|
||||
return username ? '@' + username : unknownName;
|
||||
};
|
||||
|
||||
const markDownOptions = {
|
||||
atSumOfMembersMentions: true,
|
||||
atPlanMentions: true,
|
||||
markdown: false,
|
||||
};
|
||||
const pluginIds = Object.keys(requestedPluginsByPluginIds || {});
|
||||
if (pluginIds.length && requestedPluginsByUserIds && requestedPluginsByPluginIds) {
|
||||
let post;
|
||||
const messageBuilder: string[] = [];
|
||||
const userIds = Object.keys(requestedPluginsByUserIds);
|
||||
if (userIds.length === 1 && pluginIds.length === 1) {
|
||||
const pluginName = marketplacePluginsNamesById[pluginIds[0]];
|
||||
messageBuilder.push('@' + userProfiles[userIds[0]]?.username);
|
||||
messageBuilder.push(' ' + formatMessage({id: 'postypes.custom_open_plugin_install_post_rendered.plugin_request', defaultMessage: 'requested installing the {pluginRequests} app.'}, {pluginRequests: pluginName}));
|
||||
|
||||
const instructions = (
|
||||
<FormattedMessage
|
||||
id='postypes.custom_open_plugin_install_post_rendered.plugin_instructions'
|
||||
defaultMessage='<pluginApp></pluginApp> or visit <marketplaceLink>Marketplace</marketplaceLink> to view all plugins.'
|
||||
values={{
|
||||
marketplaceLink: (text: string) => (
|
||||
<ToggleModalButton
|
||||
id='marketplaceModal'
|
||||
className='color--link'
|
||||
modalId={ModalIdentifiers.PLUGIN_MARKETPLACE}
|
||||
dialogType={MarketplaceModal}
|
||||
>
|
||||
{text}
|
||||
</ToggleModalButton>
|
||||
),
|
||||
pluginApp: () => (
|
||||
<InstallAndConfigureLink
|
||||
pluginId={pluginIds[0]}
|
||||
pluginName={pluginName}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>);
|
||||
|
||||
const message = formatList(messageBuilder, {style: 'narrow', type: 'unit'});
|
||||
post = (
|
||||
<>
|
||||
<Markdown
|
||||
postId={props.post.id}
|
||||
message={message}
|
||||
options={markDownOptions}
|
||||
userIds={getUserIdsForUsersThatRequestedFeature(requestedPluginsByUserIds[userIds[0]])}
|
||||
/>
|
||||
{' '}
|
||||
{instructions}
|
||||
</>);
|
||||
customMessageBody.push(post);
|
||||
} else {
|
||||
messageBuilder.push(formatMessage({id: 'postypes.custom_open_plugin_install_post_rendered.app_installation_request_text', defaultMessage: 'You’ve received the following app installation requests:'}));
|
||||
post = (
|
||||
<ul
|
||||
style={usersListStyle}
|
||||
key={pluginIds.join('')}
|
||||
>
|
||||
{pluginIds.map((pluginId) => {
|
||||
const plugins = requestedPluginsByPluginIds[pluginId];
|
||||
const pluginName = marketplacePluginsNamesById[pluginId];
|
||||
const uniqueUserRequestsForPlugins = uniqWith(plugins, (one, two) => one.user_id === two.user_id);
|
||||
const installRequests = [];
|
||||
installRequests.push(createUsernameMessage(uniqueUserRequestsForPlugins));
|
||||
installRequests.push(' ' + formatMessage({id: 'postypes.custom_open_plugin_install_post_rendered.plugin_request', defaultMessage: 'requested installing the {pluginRequests} app.'}, {pluginRequests: pluginName}));
|
||||
|
||||
return (
|
||||
<li key={pluginId}>
|
||||
<Markdown
|
||||
postId={props.post.id}
|
||||
message={installRequests.join('')}
|
||||
options={markDownOptions}
|
||||
userIds={getUserIdsForUsersThatRequestedFeature(requestedPluginsByUserIds[userIds[0]])}
|
||||
/>
|
||||
{' '}
|
||||
<InstallAndConfigureLink
|
||||
pluginId={pluginId}
|
||||
pluginName={pluginName}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
|
||||
const instructions = (
|
||||
<FormattedMessage
|
||||
id='postypes.custom_open_plugin_install_post_rendered.plugins_instructions'
|
||||
defaultMessage='Install the apps or visit <marketplaceLink>Marketplace</marketplaceLink> to view all plugins.'
|
||||
values={{
|
||||
marketplaceLink: (text: string) => (
|
||||
<ToggleModalButton
|
||||
id='marketplaceModal'
|
||||
className='color--link'
|
||||
modalId={ModalIdentifiers.PLUGIN_MARKETPLACE}
|
||||
dialogType={MarketplaceModal}
|
||||
dialogProps={{openedFrom: 'open_plugin_install_post'}}
|
||||
>
|
||||
{text}
|
||||
</ToggleModalButton>
|
||||
),
|
||||
}}
|
||||
/>);
|
||||
|
||||
customMessageBody.push(messageBuilder);
|
||||
customMessageBody.push(post);
|
||||
customMessageBody.push(instructions);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{customMessageBody}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import {measurePageLoadTelemetry, temporarilySetPageLoadContext, trackEvent, tra
|
||||
import BrowserStore from 'stores/browser_store';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import OpenPluginInstallPost from 'components/custom_open_plugin_install_post_renderer';
|
||||
import GlobalHeader from 'components/global_header/global_header';
|
||||
import {HFRoute} from 'components/header_footer_route/header_footer_route';
|
||||
import {HFTRoute, LoggedInHFTRoute} from 'components/header_footer_template_route';
|
||||
@@ -360,9 +359,6 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
|
||||
this.initiateMeRequests();
|
||||
|
||||
// See figma design on issue https://mattermost.atlassian.net/browse/MM-43649
|
||||
this.props.actions.registerCustomPostRenderer('custom_pl_notification', OpenPluginInstallPost, 'plugin_install_post_message_renderer');
|
||||
|
||||
measurePageLoadTelemetry();
|
||||
trackSelectorMetrics();
|
||||
|
||||
|
||||
@@ -4281,9 +4281,7 @@
|
||||
"marketplace_modal.install_plugins": "Install plugins",
|
||||
"marketplace_modal.installing": "Installing...",
|
||||
"marketplace_modal.list.configure": "Configure",
|
||||
"marketplace_modal.list.configure.plugin": "Configure {plugin}",
|
||||
"marketplace_modal.list.install": "Install",
|
||||
"marketplace_modal.list.install.plugin": "Install {plugin}",
|
||||
"marketplace_modal.list.installed": "Installed",
|
||||
"marketplace_modal.list.try_again": "Try Again",
|
||||
"marketplace_modal.list.update": "Update",
|
||||
@@ -4723,14 +4721,7 @@
|
||||
"postlist.toast.searchHint": "Tip: Try {searchShortcut} to search this channel",
|
||||
"posts_view.loadMore": "Load More messages",
|
||||
"posts_view.newMsg": "New Messages",
|
||||
"postypes.custom_open_plugin_install_post_rendered.app_installation_request_text": "You’ve received the following app installation requests:",
|
||||
"postypes.custom_open_plugin_install_post_rendered.plugin_instructions": "<pluginApp></pluginApp> or visit <marketplaceLink>Marketplace</marketplaceLink> to view all plugins.",
|
||||
"postypes.custom_open_plugin_install_post_rendered.plugin_request": "requested installing the {pluginRequests} app.",
|
||||
"postypes.custom_open_plugin_install_post_rendered.plugins_instructions": "Install the apps or visit <marketplaceLink>Marketplace</marketplaceLink> to view all plugins.",
|
||||
"postypes.custom_open_pricing_modal_post_renderer.and": "and",
|
||||
"postypes.custom_open_pricing_modal_post_renderer.members": "{members} members",
|
||||
"postypes.custom_open_pricing_modal_post_renderer.membersThatRequested": "Members that requested ",
|
||||
"postypes.custom_open_pricing_modal_post_renderer.unknown": "@unknown",
|
||||
"pricing_modal.addons.dedicatedDB": "Dedicated database",
|
||||
"pricing_modal.addons.dedicatedDeployment": "Dedicated virtual secure cloud deployment (Cloud)",
|
||||
"pricing_modal.addons.dedicatedEncryption": "Dedicated encryption keys",
|
||||
|
||||
Ссылка в новой задаче
Block a user