[MM-56795] Improve help options in the Help menu (#3216)

* [MM-56795] Improve help options in the Help menu

* Fix i18n

* Remove extra separator
This commit is contained in:
Devin Binnie
2024-11-22 10:18:38 -05:00
committed by GitHub
parent fad05fd774
commit 513a7e0a86
11 changed files with 87 additions and 22 deletions

View File

@@ -67,13 +67,15 @@
"main.menus.app.file.signInToAnotherServer": "Sign in to Another Server", "main.menus.app.file.signInToAnotherServer": "Sign in to Another Server",
"main.menus.app.file.unhide": "Show All", "main.menus.app.file.unhide": "Show All",
"main.menus.app.help": "Hel&p", "main.menus.app.help": "Hel&p",
"main.menus.app.help.academy": "Mattermost Academy",
"main.menus.app.help.checkForUpdates": "Check for Updates", "main.menus.app.help.checkForUpdates": "Check for Updates",
"main.menus.app.help.commitString": " commit: {hashVersion}", "main.menus.app.help.commitString": " commit: {hashVersion}",
"main.menus.app.help.downloadUpdate": "Download Update", "main.menus.app.help.downloadUpdate": "Download Update",
"main.menus.app.help.learnMore": "Learn More...", "main.menus.app.help.reportProblem": "Report a problem",
"main.menus.app.help.restartAndUpdate": "Restart and Update", "main.menus.app.help.restartAndUpdate": "Restart and Update",
"main.menus.app.help.RunDiagnostics": "Run diagnostics", "main.menus.app.help.RunDiagnostics": "Run diagnostics",
"main.menus.app.help.ShowLogs": "Show logs", "main.menus.app.help.ShowLogs": "Show logs",
"main.menus.app.help.userGuide": "User guide",
"main.menus.app.help.versionString": "Version {version}{commit}", "main.menus.app.help.versionString": "Version {version}{commit}",
"main.menus.app.history": "&History", "main.menus.app.history": "&History",
"main.menus.app.history.back": "Back", "main.menus.app.history.back": "Back",

View File

@@ -4,6 +4,8 @@
import type {BuildConfig} from 'types/config'; import type {BuildConfig} from 'types/config';
import {DEFAULT_ACADEMY_LINK, DEFAULT_HELP_LINK} from '../../common/constants';
// For detailed guides, please refer to https://docs.mattermost.com/deployment/desktop-app-deployment.html // For detailed guides, please refer to https://docs.mattermost.com/deployment/desktop-app-deployment.html
/** /**
@@ -27,7 +29,8 @@ const buildConfig: BuildConfig = {
url: 'https://example.com' url: 'https://example.com'
} }
*/], */],
helpLink: 'https://docs.mattermost.com/messaging/managing-desktop-app-servers.html', helpLink: DEFAULT_HELP_LINK,
academyLink: DEFAULT_ACADEMY_LINK,
enableServerManagement: true, enableServerManagement: true,
enableAutoUpdater: true, enableAutoUpdater: true,
managedResources: ['trusted'], managedResources: ['trusted'],

View File

@@ -216,6 +216,9 @@ export class Config extends EventEmitter {
get helpLink() { get helpLink() {
return this.combinedData?.helpLink; return this.combinedData?.helpLink;
} }
get academyLink() {
return this.combinedData?.academyLink;
}
get minimizeToTray() { get minimizeToTray() {
return this.combinedData?.minimizeToTray; return this.combinedData?.minimizeToTray;
} }

View File

@@ -1,16 +1,13 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import type {DownloadItemTypeEnum} from 'main/downloadsManager'; import type {DownloadedItem, DownloadItemTypeEnum} from 'types/downloads';
import type {DownloadedItem} from 'types/downloads';
/** /**
* This string includes special characters so that it's not confused with * This string includes special characters so that it's not confused with
* a file that may have the same filename (eg APP_UPDATE) * a file that may have the same filename (eg APP_UPDATE)
*/ */
export const APP_UPDATE_KEY = '#:(APP_UPDATE):#'; export const APP_UPDATE_KEY = '#:(APP_UPDATE):#';
export const UPDATE_DOWNLOAD_ITEM: Omit<DownloadedItem, 'filename' | 'state'> = { export const UPDATE_DOWNLOAD_ITEM: Omit<DownloadedItem, 'filename' | 'state'> = {
type: 'update' as DownloadItemTypeEnum, type: 'update' as DownloadItemTypeEnum,
progress: 0, progress: 0,
@@ -46,3 +43,8 @@ export const IS_ONLINE_ENDPOINT = 'https://community.mattermost.com/api/v4/syste
export const COOKIE_NAME_USER_ID = 'MMUSERID'; export const COOKIE_NAME_USER_ID = 'MMUSERID';
export const COOKIE_NAME_CSRF = 'MMCSRF'; export const COOKIE_NAME_CSRF = 'MMCSRF';
export const COOKIE_NAME_AUTH_TOKEN = 'MMAUTHTOKEN'; export const COOKIE_NAME_AUTH_TOKEN = 'MMAUTHTOKEN';
export const DEFAULT_HELP_LINK = 'https://docs.mattermost.com/guides/collaborate.html';
export const DEFAULT_ACADEMY_LINK = 'https://academy.mattermost.com/';
export const DEFAULT_TE_REPORT_PROBLEM_LINK = 'https://mattermost.com/pl/report-a-bug';
export const DEFAULT_EE_REPORT_PROBLEM_LINK = 'https://support.mattermost.com/hc/en-us/requests/new';

View File

@@ -36,18 +36,13 @@ import {doubleSecToMs, getPercentage, isStringWithLength, readFilenameFromConten
import ViewManager from 'main/views/viewManager'; import ViewManager from 'main/views/viewManager';
import MainWindow from 'main/windows/mainWindow'; import MainWindow from 'main/windows/mainWindow';
import type {DownloadedItem, DownloadItemDoneEventState, DownloadedItems, DownloadItemState, DownloadItemUpdatedEventState} from 'types/downloads'; import {type DownloadedItem, type DownloadItemDoneEventState, type DownloadedItems, type DownloadItemState, type DownloadItemUpdatedEventState, DownloadItemTypeEnum} from 'types/downloads';
import appVersionManager from './AppVersionManager'; import appVersionManager from './AppVersionManager';
import {downloadsJson} from './constants'; import {downloadsJson} from './constants';
const log = new Logger('DownloadsManager'); const log = new Logger('DownloadsManager');
export enum DownloadItemTypeEnum {
FILE = 'file',
UPDATE = 'update',
}
export class DownloadsManager extends JsonFileManager<DownloadedItems> { export class DownloadsManager extends JsonFileManager<DownloadedItems> {
autoCloseTimeout: NodeJS.Timeout | null; autoCloseTimeout: NodeJS.Timeout | null;
open: boolean; open: boolean;

View File

@@ -68,6 +68,7 @@ jest.mock('common/servers/serverManager', () => ({
hasServers: jest.fn(), hasServers: jest.fn(),
getOrderedServers: jest.fn(), getOrderedServers: jest.fn(),
getOrderedTabsForServer: jest.fn(), getOrderedTabsForServer: jest.fn(),
getRemoteInfo: jest.fn(),
})); }));
jest.mock('app/serverViewState', () => ({ jest.mock('app/serverViewState', () => ({
switchServer: jest.fn(), switchServer: jest.fn(),
@@ -302,6 +303,7 @@ describe('main/menus/app', () => {
} }
return id; return id;
}); });
ServerManager.hasServers.mockReturnValue(true);
ServerViewState.getCurrentServer.mockImplementation(() => ({id: servers[0].id})); ServerViewState.getCurrentServer.mockImplementation(() => ({id: servers[0].id}));
const modifiedViews = [...Array(15).keys()].map((key) => ({ const modifiedViews = [...Array(15).keys()].map((key) => ({

View File

@@ -10,6 +10,7 @@ import log from 'electron-log';
import ServerViewState from 'app/serverViewState'; import ServerViewState from 'app/serverViewState';
import {OPEN_SERVERS_DROPDOWN, SHOW_NEW_SERVER_MODAL} from 'common/communication'; import {OPEN_SERVERS_DROPDOWN, SHOW_NEW_SERVER_MODAL} from 'common/communication';
import type {Config} from 'common/config'; import type {Config} from 'common/config';
import {DEFAULT_EE_REPORT_PROBLEM_LINK, DEFAULT_TE_REPORT_PROBLEM_LINK} from 'common/constants';
import ServerManager from 'common/servers/serverManager'; import ServerManager from 'common/servers/serverManager';
import {t} from 'common/utils/util'; import {t} from 'common/utils/util';
import {getViewDisplayName} from 'common/views/View'; import {getViewDisplayName} from 'common/views/View';
@@ -312,6 +313,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
}); });
const servers = ServerManager.getOrderedServers(); const servers = ServerManager.getOrderedServers();
const currentServer = ServerManager.hasServers() ? ServerViewState.getCurrentServer() : undefined;
const windowMenu = { const windowMenu = {
id: 'window', id: 'window',
label: localizeMessage('main.menus.app.window', '&Window'), label: localizeMessage('main.menus.app.window', '&Window'),
@@ -347,7 +349,7 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
ServerViewState.switchServer(server.id); ServerViewState.switchServer(server.id);
}, },
}); });
if (ServerViewState.getCurrentServer().id === server.id) { if (currentServer?.id === server.id) {
ServerManager.getOrderedTabsForServer(server.id).slice(0, 9).forEach((view, i) => { ServerManager.getOrderedTabsForServer(server.id).slice(0, 9).forEach((view, i) => {
items.push({ items.push({
label: ` ${localizeMessage(`common.views.${view.type}`, getViewDisplayName(view.type as ViewType))}`, label: ` ${localizeMessage(`common.views.${view.type}`, getViewDisplayName(view.type as ViewType))}`,
@@ -380,6 +382,8 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
], ],
}; };
template.push(windowMenu); template.push(windowMenu);
const currentRemoteInfo = currentServer ? ServerManager.getRemoteInfo(currentServer.id) : undefined;
const submenu = []; const submenu = [];
if (updateManager && config.canUpgrade) { if (updateManager && config.canUpgrade) {
if (updateManager.versionDownloaded) { if (updateManager.versionDownloaded) {
@@ -404,17 +408,29 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
}, },
}); });
} }
}
if (config.helpLink) {
submenu.push({
label: localizeMessage('main.menus.app.help.learnMore', 'Learn More...'),
click() {
shell.openExternal(config.helpLink!);
},
});
submenu.push(separatorItem); submenu.push(separatorItem);
} }
const helpLink = currentRemoteInfo?.helpLink ?? config.helpLink;
if (helpLink) {
submenu.push({
label: localizeMessage('main.menus.app.help.userGuide', 'User guide'),
click() {
shell.openExternal(helpLink);
},
});
}
const academyLink = config.academyLink;
if (academyLink) {
submenu.push({
label: localizeMessage('main.menus.app.help.academy', 'Mattermost Academy'),
click() {
shell.openExternal(academyLink);
},
});
}
submenu.push(separatorItem);
submenu.push({ submenu.push({
id: 'Show logs', id: 'Show logs',
label: localizeMessage('main.menus.app.help.ShowLogs', 'Show logs'), label: localizeMessage('main.menus.app.help.ShowLogs', 'Show logs'),
@@ -430,6 +446,27 @@ export function createTemplate(config: Config, updateManager: UpdateManager) {
Diagnostics.run(); Diagnostics.run();
}, },
}); });
let reportProblemLink = currentRemoteInfo?.reportProblemLink;
if (!reportProblemLink) {
switch (currentRemoteInfo?.licenseSku) {
case 'enterprise':
case 'professional':
reportProblemLink = DEFAULT_EE_REPORT_PROBLEM_LINK;
break;
default:
reportProblemLink = DEFAULT_TE_REPORT_PROBLEM_LINK;
break;
}
}
if (reportProblemLink) {
submenu.push({
label: localizeMessage('main.menus.app.help.reportProblem', 'Report a problem'),
click() {
shell.openExternal(reportProblemLink!);
},
});
}
submenu.push(separatorItem); submenu.push(separatorItem);
const version = localizeMessage('main.menus.app.help.versionString', 'Version {version}{commit}', { const version = localizeMessage('main.menus.app.help.versionString', 'Version {version}{commit}', {

View File

@@ -32,6 +32,10 @@ export class ServerInfo {
this.onGetPlugins, this.onGetPlugins,
parseURL(`${this.server.url}/api/v4/plugins/webapp`), parseURL(`${this.server.url}/api/v4/plugins/webapp`),
); );
await this.getRemoteInfo<{SkuShortName: string}>(
this.onGetLicense,
parseURL(`${this.server.url}/api/v4/license/client?format=old`),
);
return this.remoteInfo; return this.remoteInfo;
}; };
@@ -66,10 +70,17 @@ export class ServerInfo {
this.remoteInfo.siteURL = data.SiteURL; this.remoteInfo.siteURL = data.SiteURL;
this.remoteInfo.siteName = data.SiteName; this.remoteInfo.siteName = data.SiteName;
this.remoteInfo.hasFocalboard = this.remoteInfo.hasFocalboard || data.BuildBoards === 'true'; this.remoteInfo.hasFocalboard = this.remoteInfo.hasFocalboard || data.BuildBoards === 'true';
this.remoteInfo.helpLink = data.HelpLink;
this.remoteInfo.reportProblemLink = data.ReportAProblemLink;
};
private onGetLicense = (data: {SkuShortName: string}) => {
this.remoteInfo.licenseSku = data.SkuShortName;
}; };
private onGetPlugins = (data: Array<{id: string; version: string}>) => { private onGetPlugins = (data: Array<{id: string; version: string}>) => {
this.remoteInfo.hasFocalboard = this.remoteInfo.hasFocalboard || data.some((plugin) => plugin.id === 'focalboard'); this.remoteInfo.hasFocalboard = this.remoteInfo.hasFocalboard || data.some((plugin) => plugin.id === 'focalboard');
this.remoteInfo.hasPlaybooks = data.some((plugin) => plugin.id === 'playbooks'); this.remoteInfo.hasPlaybooks = data.some((plugin) => plugin.id === 'playbooks');
this.remoteInfo.hasUserSurvey = data.some((plugin) => plugin.id === 'com.mattermost.nps');
}; };
} }

View File

@@ -106,6 +106,7 @@ export type AnyConfig = ConfigV3 | ConfigV2 | ConfigV1 | ConfigV0;
export type BuildConfig = { export type BuildConfig = {
defaultServers?: Server[]; defaultServers?: Server[];
helpLink: string; helpLink: string;
academyLink: string;
enableServerManagement: boolean; enableServerManagement: boolean;
enableAutoUpdater: boolean; enableAutoUpdater: boolean;
managedResources: string[]; managedResources: string[];

View File

@@ -1,7 +1,10 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import type {DownloadItemTypeEnum} from 'main/downloadsManager'; export enum DownloadItemTypeEnum {
FILE = 'file',
UPDATE = 'update',
}
export type DownloadItemUpdatedEventState = 'interrupted' | 'progressing'; export type DownloadItemUpdatedEventState = 'interrupted' | 'progressing';
export type DownloadItemDoneEventState = 'completed' | 'cancelled' | 'interrupted'; export type DownloadItemDoneEventState = 'completed' | 'cancelled' | 'interrupted';

View File

@@ -5,8 +5,12 @@ export type RemoteInfo = {
serverVersion?: string; serverVersion?: string;
siteName?: string; siteName?: string;
siteURL?: string; siteURL?: string;
licenseSku?: string;
helpLink?: string;
reportProblemLink?: string;
hasFocalboard?: boolean; hasFocalboard?: boolean;
hasPlaybooks?: boolean; hasPlaybooks?: boolean;
hasUserSurvey?: boolean;
}; };
export type ClientConfig = { export type ClientConfig = {
@@ -14,6 +18,8 @@ export type ClientConfig = {
SiteURL: string; SiteURL: string;
SiteName: string; SiteName: string;
BuildBoards: string; BuildBoards: string;
HelpLink: string;
ReportAProblemLink: string;
} }
export type URLValidationResult = { export type URLValidationResult = {