[MM-36432][MM-37072][MM-37073] Logic to support Focalboard and Playbooks tabs (#1680)
* Tab stuff * Inter-tab navigation * Close tab functionality * [MM-36342][MM-37072] Logic to support Focalboard and Playbooks tabs * Update to version 5.0 * Update config.yml * Updated routes * Update names for products * [MM-37073] Close unneeded tabs when not using v6.0 * Merge'd * Update config.yml * Update config.yml * Fix menu names * PR feedback * blank * blank * blank * PR feedback * Update config.yml * PR feedback Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
export const SWITCH_SERVER = 'switch-server';
|
||||
export const SWITCH_TAB = 'switch-tab';
|
||||
export const CLOSE_TAB = 'close-tab';
|
||||
export const OPEN_TAB = 'open-tab';
|
||||
export const SET_ACTIVE_VIEW = 'set-active-view';
|
||||
export const MARK_READ = 'mark-read';
|
||||
export const FOCUS_BROWSERVIEW = 'focus-browserview';
|
||||
@@ -92,3 +94,5 @@ export const UPDATE_DROPDOWN_MENTIONS = 'update-dropdown-mentions';
|
||||
export const REQUEST_TEAMS_DROPDOWN_INFO = 'request-teams-dropdown-info';
|
||||
export const RECEIVE_DROPDOWN_MENU_SIZE = 'receive-dropdown-menu-size';
|
||||
export const SEND_DROPDOWN_MENU_SIZE = 'send-dropdown-menu-size';
|
||||
|
||||
export const BROWSER_HISTORY_PUSH = 'browser-history-push';
|
||||
|
@@ -1,12 +1,14 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getFormattedPathName} from 'common/utils/url';
|
||||
|
||||
import BaseTabView from './BaseTabView';
|
||||
import {TabType, TAB_FOCALBOARD} from './TabView';
|
||||
|
||||
export default class FocalboardTabView extends BaseTabView {
|
||||
get url(): URL {
|
||||
return this.server.url;
|
||||
return new URL(`${this.server.url.origin}${getFormattedPathName(this.server.url.pathname)}boards`);
|
||||
}
|
||||
|
||||
get type(): TabType {
|
||||
|
@@ -1,12 +1,14 @@
|
||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {getFormattedPathName} from 'common/utils/url';
|
||||
|
||||
import BaseTabView from './BaseTabView';
|
||||
import {TabType, TAB_PLAYBOOKS} from './TabView';
|
||||
|
||||
export default class PlaybooksTabView extends BaseTabView {
|
||||
get url(): URL {
|
||||
return this.server.url;
|
||||
return new URL(`${this.server.url.origin}${getFormattedPathName(this.server.url.pathname)}playbooks`);
|
||||
}
|
||||
|
||||
get type(): TabType {
|
||||
|
@@ -29,14 +29,17 @@ export function getDefaultTeamWithTabsFromTeam(team: Team) {
|
||||
{
|
||||
name: TAB_MESSAGING,
|
||||
order: 0,
|
||||
isClosed: false,
|
||||
},
|
||||
{
|
||||
name: TAB_FOCALBOARD,
|
||||
order: 1,
|
||||
isClosed: false,
|
||||
},
|
||||
{
|
||||
name: TAB_PLAYBOOKS,
|
||||
order: 2,
|
||||
isClosed: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -59,3 +62,21 @@ export function getServerView(srv: MattermostServer, tab: Tab) {
|
||||
export function getTabViewName(serverName: string, tabType: string) {
|
||||
return `${serverName}___${tabType}`;
|
||||
}
|
||||
|
||||
export function getTabDisplayName(tabType: TabType) {
|
||||
switch (tabType) {
|
||||
case TAB_MESSAGING:
|
||||
return 'Channels';
|
||||
case TAB_FOCALBOARD:
|
||||
return 'Boards';
|
||||
case TAB_PLAYBOOKS:
|
||||
return 'Playbooks';
|
||||
default:
|
||||
throw new Error('Not implemeneted');
|
||||
}
|
||||
}
|
||||
|
||||
export function canCloseTab(tabType: TabType) {
|
||||
// TODO: maybe rework to make the property belong to the class somehow
|
||||
return tabType !== TAB_MESSAGING;
|
||||
}
|
||||
|
@@ -79,10 +79,14 @@ function getServerInfo(serverUrl: URL | string) {
|
||||
|
||||
// does the server have a subpath?
|
||||
const pn = parsedServer.pathname.toLowerCase();
|
||||
const subpath = pn.endsWith('/') ? pn.toLowerCase() : `${pn}/`;
|
||||
const subpath = getFormattedPathName(pn);
|
||||
return {subpath, url: parsedServer};
|
||||
}
|
||||
|
||||
export function getFormattedPathName(pn: string) {
|
||||
return pn.endsWith('/') ? pn.toLowerCase() : `${pn}/`;
|
||||
}
|
||||
|
||||
function getManagedResources() {
|
||||
if (!buildConfig) {
|
||||
return [];
|
||||
@@ -164,25 +168,24 @@ function getView(inputURL: URL | string, teams: TeamWithTabs[], ignoreScheme = f
|
||||
if (!parsedURL) {
|
||||
return undefined;
|
||||
}
|
||||
let parsedServerUrl;
|
||||
let firstOption;
|
||||
let secondOption;
|
||||
teams.forEach((team) => {
|
||||
const srv = new MattermostServer(team.name, team.url);
|
||||
team.tabs.forEach((tab) => {
|
||||
const tabView = getServerView(srv, tab);
|
||||
parsedServerUrl = parseURL(tabView.url);
|
||||
const parsedServerUrl = parseURL(tabView.url);
|
||||
if (parsedServerUrl) {
|
||||
// check server and subpath matches (without subpath pathname is \ so it always matches)
|
||||
if (equalUrlsWithSubpath(parsedServerUrl, parsedURL, ignoreScheme)) {
|
||||
firstOption = {name: tabView.name, url: parsedServerUrl};
|
||||
firstOption = {name: tabView.name, url: parsedServerUrl.toString()};
|
||||
}
|
||||
if (equalUrlsIgnoringSubpath(parsedServerUrl, parsedURL, ignoreScheme)) {
|
||||
// in case the user added something on the path that doesn't really belong to the server
|
||||
// there might be more than one that matches, but we can't differentiate, so last one
|
||||
// is as good as any other in case there is no better match (e.g.: two subpath servers with the same origin)
|
||||
// e.g.: https://community.mattermost.com/core
|
||||
secondOption = {name: tabView.name, url: parsedServerUrl};
|
||||
secondOption = {name: tabView.name, url: parsedServerUrl.toString()};
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -214,7 +217,8 @@ function isTrustedURL(url: URL | string, teams: TeamWithTabs[]) {
|
||||
}
|
||||
|
||||
function isCustomLoginURL(url: URL | string, server: ServerFromURL, teams: TeamWithTabs[]): boolean {
|
||||
const subpath = server ? server.url.pathname : '';
|
||||
const serverURL = parseURL(server.url);
|
||||
const subpath = server && serverURL ? serverURL.pathname : '';
|
||||
const parsedURL = parseURL(url);
|
||||
if (!parsedURL) {
|
||||
return false;
|
||||
|
@@ -37,8 +37,34 @@ function shorten(string: string, max?: number) {
|
||||
return string;
|
||||
}
|
||||
|
||||
export function isServerVersionGreaterThanOrEqualTo(currentVersion: string, compareVersion: string): boolean {
|
||||
if (currentVersion === compareVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We only care about the numbers
|
||||
const currentVersionNumber = (currentVersion || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null);
|
||||
const compareVersionNumber = (compareVersion || '').split('.').filter((x) => (/^[0-9]+$/).exec(x) !== null);
|
||||
|
||||
for (let i = 0; i < Math.max(currentVersionNumber.length, compareVersionNumber.length); i++) {
|
||||
const currentVersion = parseInt(currentVersionNumber[i], 10) || 0;
|
||||
const compareVersion = parseInt(compareVersionNumber[i], 10) || 0;
|
||||
if (currentVersion > compareVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentVersion < compareVersion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If all components are equal, then return true
|
||||
return true;
|
||||
}
|
||||
|
||||
export default {
|
||||
getDisplayBoundaries,
|
||||
runMode,
|
||||
shorten,
|
||||
isServerVersionGreaterThanOrEqualTo,
|
||||
};
|
||||
|
Reference in New Issue
Block a user