mirror of
https://github.com/mattermost/mattermost.git
synced 2026-05-12 20:00:48 +00:00
MM-64380 Remove compass components (#33744)
* Remove Flex component * Remove Heading component * Remove StatusIcon component * Migrate IconButton from Compass Components repo * Remove unused variants of IconButton and move into GlobalHeader We only actually used IconButton in a limited set of locations (all currently in the global header), and if I tried to test other variations, they seemed to often have issues (like white text on a white background). Most of those seemed to be because the theme in the CompassThemeProvider was missing fields and fell back to defaults that didn't make sense, but there were also enough errors in IconButtonRoot (like invalid transitions or other logical errors) that lead me to just rip out everything we don't currently use. * Remove CompassThemeProvider * Remove remaining references to @mattermost/compass-components * Remove prop that's no longer needed
This commit is contained in:
-15
@@ -1061,21 +1061,6 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## @mattermost/compass-components
|
||||
|
||||
This product contains '@mattermost/compass-components' by Mattermost.
|
||||
|
||||
components aligning to the compass design system
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/mattermost/compass-components#readme
|
||||
|
||||
* LICENSE: MIT
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## @mattermost/compass-icons
|
||||
|
||||
@@ -37,7 +37,7 @@ const config = {
|
||||
['jest-junit', {outputDirectory: 'build', outputName: 'test-results.xml'}],
|
||||
],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!react-native|react-router|pdfjs-dist|p-queue|p-timeout|@mattermost/compass-components|@mattermost/compass-icons|cidr-regex|ip-regex|serialize-error)',
|
||||
'node_modules/(?!react-native|react-router|pdfjs-dist|p-queue|p-timeout|@mattermost/compass-icons|cidr-regex|ip-regex|serialize-error)',
|
||||
],
|
||||
transform: {
|
||||
'^.+\\.(js|jsx|ts|tsx|mjs)$': 'babel-jest',
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"@giphy/react-components": "8.1.0",
|
||||
"@guyplusplus/turndown-plugin-gfm": "1.0.7",
|
||||
"@mattermost/client": "10.11.0",
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/desktop-api": "5.10.0-2",
|
||||
"@mattermost/dynamic-virtualized-list": "github:mattermost/dynamic-virtualized-list#08dde0c34a12d0384740db27d55e398d139d7a51",
|
||||
"@mattermost/types": "10.11.0",
|
||||
@@ -172,9 +171,6 @@
|
||||
"yargs": "17.7.2"
|
||||
},
|
||||
"overrides": {
|
||||
"@mattermost/compass-components": {
|
||||
"axios": "1.7.9"
|
||||
},
|
||||
"@mattermost/desktop-api": {
|
||||
"typescript": "$typescript"
|
||||
}
|
||||
|
||||
@@ -91,7 +91,6 @@ describe('CloudUsageModal', () => {
|
||||
props = {
|
||||
title: '',
|
||||
onClose: jest.fn(),
|
||||
needsTheme: false,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -2,16 +2,12 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import type {Limits} from '@mattermost/types/cloud';
|
||||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import useGetLimits from 'components/common/hooks/useGetLimits';
|
||||
import useGetUsage from 'components/common/hooks/useGetUsage';
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
|
||||
import type {Message} from 'utils/i18n';
|
||||
|
||||
@@ -33,17 +29,13 @@ export interface Props {
|
||||
backdrop?: boolean;
|
||||
backdropClassName?: string;
|
||||
className?: string;
|
||||
|
||||
// e.g. in contexts where the CompassThemeProvider isn't already applied, like the system console
|
||||
needsTheme?: boolean;
|
||||
}
|
||||
|
||||
export default function CloudUsageModal(props: Props) {
|
||||
const [limits] = useGetLimits();
|
||||
const usage = useGetUsage();
|
||||
const theme = useSelector(getTheme);
|
||||
|
||||
const modal = (
|
||||
return (
|
||||
<GenericModal
|
||||
handleCancel={props.onClose}
|
||||
compassDesign={true}
|
||||
@@ -68,14 +60,4 @@ export default function CloudUsageModal(props: Props) {
|
||||
</>
|
||||
</GenericModal>
|
||||
);
|
||||
|
||||
if (!props.needsTheme) {
|
||||
return modal;
|
||||
}
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
{modal}
|
||||
</CompassThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ export default function useShowAdminLimitReached() {
|
||||
onClose: () => {
|
||||
dispatch(closeModal(ModalIdentifiers.CLOUD_LIMITS));
|
||||
},
|
||||
needsTheme: true,
|
||||
};
|
||||
|
||||
// Only show primary action if not air-gapped
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
|
||||
import ThemeProvider, {lightTheme} from '@mattermost/compass-components/utilities/theme'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const CompassThemeProvider = ({
|
||||
theme,
|
||||
children,
|
||||
}: Props) => {
|
||||
const compassTheme = useMemo(() => {
|
||||
const base = {
|
||||
...lightTheme,
|
||||
noStyleReset: true,
|
||||
noDefaultStyle: true,
|
||||
noFontFaces: true,
|
||||
};
|
||||
|
||||
return {
|
||||
...base,
|
||||
palette: {
|
||||
...base.palette,
|
||||
primary: {
|
||||
...base.palette.primary,
|
||||
main: theme.sidebarHeaderBg,
|
||||
contrast: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
alert: {
|
||||
...base.palette.alert,
|
||||
main: theme.dndIndicator,
|
||||
},
|
||||
},
|
||||
action: {
|
||||
...base.action,
|
||||
hover: theme.sidebarHeaderTextColor,
|
||||
disabled: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
badges: {
|
||||
...base.badges,
|
||||
online: theme.onlineIndicator,
|
||||
away: theme.awayIndicator,
|
||||
dnd: theme.dndIndicator,
|
||||
},
|
||||
text: {
|
||||
...base.text,
|
||||
primary: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
};
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={compassTheme}>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default CompassThemeProvider;
|
||||
@@ -9,11 +9,8 @@ import type {DayModifiers, DayPickerProps} from 'react-day-picker';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useSelector} from 'react-redux';
|
||||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {getCurrentLocale} from 'selectors/i18n';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import DatePicker from 'components/date_picker';
|
||||
import * as Menu from 'components/menu';
|
||||
import Timestamp from 'components/timestamp';
|
||||
@@ -77,7 +74,6 @@ const DateTimeInputContainer: React.FC<Props> = ({
|
||||
const [isTimeMenuOpen, setIsTimeMenuOpen] = useState(false);
|
||||
const [menuWidth, setMenuWidth] = useState<string>('200px');
|
||||
const {formatMessage} = useIntl();
|
||||
const theme = useSelector(getTheme);
|
||||
const timeContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handlePopperOpenState = useCallback((isOpen: boolean) => {
|
||||
@@ -175,83 +171,81 @@ const DateTimeInputContainer: React.FC<Props> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<div className='dateTime'>
|
||||
<div className='dateTime__date'>
|
||||
<DatePicker
|
||||
isPopperOpen={isPopperOpen}
|
||||
handlePopperOpenState={handlePopperOpenState}
|
||||
locale={locale}
|
||||
datePickerProps={datePickerProps}
|
||||
label={formatMessage({
|
||||
id: 'datetime.date',
|
||||
defaultMessage: 'Date',
|
||||
})}
|
||||
icon={calendarIcon}
|
||||
value={formatDate(time)}
|
||||
>
|
||||
<></>
|
||||
</DatePicker>
|
||||
</div>
|
||||
<div
|
||||
className='dateTime__time'
|
||||
ref={timeContainerRef}
|
||||
<div className='dateTime'>
|
||||
<div className='dateTime__date'>
|
||||
<DatePicker
|
||||
isPopperOpen={isPopperOpen}
|
||||
handlePopperOpenState={handlePopperOpenState}
|
||||
locale={locale}
|
||||
datePickerProps={datePickerProps}
|
||||
label={formatMessage({
|
||||
id: 'datetime.date',
|
||||
defaultMessage: 'Date',
|
||||
})}
|
||||
icon={calendarIcon}
|
||||
value={formatDate(time)}
|
||||
>
|
||||
<Menu.Container
|
||||
menuButton={{
|
||||
id: 'time_button',
|
||||
dataTestId: 'time_button',
|
||||
'aria-label': formatMessage({
|
||||
id: 'datetime.time',
|
||||
defaultMessage: 'Time',
|
||||
}),
|
||||
class: isTimeMenuOpen ? 'date-time-input date-time-input--open' : 'date-time-input',
|
||||
children: (
|
||||
<>
|
||||
<span className='date-time-input__label'>{formatMessage({
|
||||
id: 'datetime.time',
|
||||
defaultMessage: 'Time',
|
||||
})}</span>
|
||||
<span className='date-time-input__icon'>{clockIcon}</span>
|
||||
<span className='date-time-input__value'>
|
||||
<Timestamp
|
||||
useRelative={false}
|
||||
useDate={false}
|
||||
value={time.toString()}
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
menu={{
|
||||
id: 'expiryTimeMenu',
|
||||
'aria-label': formatMessage({id: 'time_dropdown.choose_time', defaultMessage: 'Choose a time'}),
|
||||
onToggle: handleTimeMenuToggle,
|
||||
width: menuWidth,
|
||||
className: 'time-menu-scrollable',
|
||||
}}
|
||||
>
|
||||
{timeOptions.map((option, index) => (
|
||||
<Menu.Item
|
||||
key={index}
|
||||
id={`time_option_${index}`}
|
||||
data-testid={`time_option_${index}`}
|
||||
labels={
|
||||
<span>
|
||||
<Timestamp
|
||||
useRelative={false}
|
||||
useDate={false}
|
||||
value={option}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
onClick={() => handleTimeChange(option)}
|
||||
/>
|
||||
))}
|
||||
</Menu.Container>
|
||||
</div>
|
||||
<></>
|
||||
</DatePicker>
|
||||
</div>
|
||||
</CompassThemeProvider>
|
||||
<div
|
||||
className='dateTime__time'
|
||||
ref={timeContainerRef}
|
||||
>
|
||||
<Menu.Container
|
||||
menuButton={{
|
||||
id: 'time_button',
|
||||
dataTestId: 'time_button',
|
||||
'aria-label': formatMessage({
|
||||
id: 'datetime.time',
|
||||
defaultMessage: 'Time',
|
||||
}),
|
||||
class: isTimeMenuOpen ? 'date-time-input date-time-input--open' : 'date-time-input',
|
||||
children: (
|
||||
<>
|
||||
<span className='date-time-input__label'>{formatMessage({
|
||||
id: 'datetime.time',
|
||||
defaultMessage: 'Time',
|
||||
})}</span>
|
||||
<span className='date-time-input__icon'>{clockIcon}</span>
|
||||
<span className='date-time-input__value'>
|
||||
<Timestamp
|
||||
useRelative={false}
|
||||
useDate={false}
|
||||
value={time.toString()}
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
menu={{
|
||||
id: 'expiryTimeMenu',
|
||||
'aria-label': formatMessage({id: 'time_dropdown.choose_time', defaultMessage: 'Choose a time'}),
|
||||
onToggle: handleTimeMenuToggle,
|
||||
width: menuWidth,
|
||||
className: 'time-menu-scrollable',
|
||||
}}
|
||||
>
|
||||
{timeOptions.map((option, index) => (
|
||||
<Menu.Item
|
||||
key={index}
|
||||
id={`time_option_${index}`}
|
||||
data-testid={`time_option_${index}`}
|
||||
labels={
|
||||
<span>
|
||||
<Timestamp
|
||||
useRelative={false}
|
||||
useDate={false}
|
||||
value={option}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
onClick={() => handleTimeChange(option)}
|
||||
/>
|
||||
))}
|
||||
</Menu.Container>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+23
-29
@@ -8,9 +8,6 @@ import {FormattedMessage, injectIntl, type WrappedComponentProps} from 'react-in
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import type {UserStatus} from '@mattermost/types/users';
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import DateTimeInput from 'components/datetime_input/datetime_input';
|
||||
|
||||
import Constants, {UserStatuses} from 'utils/constants';
|
||||
@@ -26,7 +23,6 @@ type Props = {
|
||||
currentDate: Date;
|
||||
locale: string;
|
||||
|
||||
theme: Theme;
|
||||
actions: {
|
||||
setStatus: (status: UserStatus) => void;
|
||||
};
|
||||
@@ -121,31 +117,29 @@ export default injectIntl(class DndCustomTimePicker extends React.PureComponent<
|
||||
const {selectedDateTime} = this.state;
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={this.props.theme}>
|
||||
<GenericModal
|
||||
compassDesign={true}
|
||||
ariaLabel={localizeMessage({id: 'dnd_custom_time_picker_modal.defaultMsg', defaultMessage: 'Disable notifications until'})}
|
||||
onExited={this.props.onExited}
|
||||
modalHeaderText={modalHeaderText}
|
||||
confirmButtonText={confirmButtonText}
|
||||
handleConfirm={this.handleConfirm}
|
||||
handleEnterKeyPress={this.handleConfirm}
|
||||
id='dndCustomTimePickerModal'
|
||||
className={'DndModal modal-overflow'}
|
||||
tabIndex={-1}
|
||||
keyboardEscape={true}
|
||||
enforceFocus={false}
|
||||
>
|
||||
<div className='DndModal__content'>
|
||||
<DateTimeInput
|
||||
time={selectedDateTime}
|
||||
handleChange={this.handleDateTimeChange}
|
||||
timezone={this.props.locale}
|
||||
relativeDate={true}
|
||||
/>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</CompassThemeProvider>
|
||||
<GenericModal
|
||||
compassDesign={true}
|
||||
ariaLabel={localizeMessage({id: 'dnd_custom_time_picker_modal.defaultMsg', defaultMessage: 'Disable notifications until'})}
|
||||
onExited={this.props.onExited}
|
||||
modalHeaderText={modalHeaderText}
|
||||
confirmButtonText={confirmButtonText}
|
||||
handleConfirm={this.handleConfirm}
|
||||
handleEnterKeyPress={this.handleConfirm}
|
||||
id='dndCustomTimePickerModal'
|
||||
className={'DndModal modal-overflow'}
|
||||
tabIndex={-1}
|
||||
keyboardEscape={true}
|
||||
enforceFocus={false}
|
||||
>
|
||||
<div className='DndModal__content'>
|
||||
<DateTimeInput
|
||||
time={selectedDateTime}
|
||||
handleChange={this.handleDateTimeChange}
|
||||
timezone={this.props.locale}
|
||||
relativeDate={true}
|
||||
/>
|
||||
</div>
|
||||
</GenericModal>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@ import {bindActionCreators} from 'redux';
|
||||
import type {Dispatch} from 'redux';
|
||||
|
||||
import {setStatus} from 'mattermost-redux/actions/users';
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {getCurrentLocale} from 'selectors/i18n';
|
||||
@@ -21,12 +20,10 @@ const DndCustomTimePicker = makeAsyncComponent('DndCustomTimePicker', React.lazy
|
||||
function mapStateToProps(state: GlobalState) {
|
||||
const userId = getCurrentUserId(state);
|
||||
const locale = getCurrentLocale(state);
|
||||
const theme = getTheme(state);
|
||||
|
||||
return {
|
||||
userId,
|
||||
locale,
|
||||
theme,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
.GlobalSearchNav {
|
||||
display: flex;
|
||||
max-width: 432px;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: initial;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
+4
-9
@@ -4,8 +4,6 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import Flex from '@mattermost/compass-components/utilities/layout/Flex'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {closeRightHandSide, showMentions} from 'actions/views/rhs';
|
||||
import {getRhsState} from 'selectors/rhs';
|
||||
|
||||
@@ -19,6 +17,8 @@ import * as Keyboard from 'utils/keyboard';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import './global_search_nav.css';
|
||||
|
||||
const GlobalSearchNav = (): JSX.Element => {
|
||||
const dispatch = useDispatch();
|
||||
const rhsState = useSelector((state: GlobalState) => getRhsState(state));
|
||||
@@ -44,14 +44,9 @@ const GlobalSearchNav = (): JSX.Element => {
|
||||
}, [rhsState, dispatch]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
row={true}
|
||||
width={432}
|
||||
flex={1}
|
||||
alignment='center'
|
||||
>
|
||||
<div className='GlobalSearchNav'>
|
||||
<NewSearch/>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+3
-12
@@ -15,16 +15,13 @@ exports[`components/channel_header/components/UserGuideDropdown should match sna
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ForwardRef
|
||||
<HeaderIconButton
|
||||
active={false}
|
||||
aria-controls="AddChannelDropdown"
|
||||
aria-expanded={false}
|
||||
aria-label="Help"
|
||||
compact={true}
|
||||
icon="help-circle-outline"
|
||||
inverted={true}
|
||||
onClick={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</WithTooltip>
|
||||
<Menu
|
||||
@@ -90,16 +87,13 @@ exports[`components/channel_header/components/UserGuideDropdown should match sna
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ForwardRef
|
||||
<HeaderIconButton
|
||||
active={false}
|
||||
aria-controls="AddChannelDropdown"
|
||||
aria-expanded={false}
|
||||
aria-label="Help"
|
||||
compact={true}
|
||||
icon="help-circle-outline"
|
||||
inverted={true}
|
||||
onClick={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</WithTooltip>
|
||||
<Menu
|
||||
@@ -157,16 +151,13 @@ exports[`components/channel_header/components/UserGuideDropdown should match sna
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ForwardRef
|
||||
<HeaderIconButton
|
||||
active={false}
|
||||
aria-controls="AddChannelDropdown"
|
||||
aria-expanded={false}
|
||||
aria-label="Help"
|
||||
compact={true}
|
||||
icon="help-circle-outline"
|
||||
inverted={true}
|
||||
onClick={[Function]}
|
||||
size="sm"
|
||||
/>
|
||||
</WithTooltip>
|
||||
<Menu
|
||||
|
||||
+1
-5
@@ -5,10 +5,9 @@ import React from 'react';
|
||||
import {FormattedMessage, injectIntl} from 'react-intl';
|
||||
import type {WrappedComponentProps} from 'react-intl';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
import KeyboardShortcutsModal from 'components/keyboard_shortcuts/keyboard_shortcuts_modal/keyboard_shortcuts_modal';
|
||||
import Menu from 'components/widgets/menu/menu';
|
||||
import MenuWrapper from 'components/widgets/menu/menu_wrapper';
|
||||
@@ -139,12 +138,9 @@ class UserGuideDropdown extends React.PureComponent<Props, State> {
|
||||
title={tooltipText}
|
||||
>
|
||||
<IconButton
|
||||
size={'sm'}
|
||||
icon={'help-circle-outline'}
|
||||
onClick={() => {}} // icon button currently requires onclick ... needs to revisit
|
||||
active={this.state.buttonActive}
|
||||
inverted={true}
|
||||
compact={true}
|
||||
aria-controls='AddChannelDropdown'
|
||||
aria-expanded={this.state.buttonActive}
|
||||
aria-label={intl.formatMessage({id: 'channel_header.userHelpGuide', defaultMessage: 'Help'})}
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
|
||||
import {useCurrentProductId} from 'utils/products';
|
||||
|
||||
import CenterControls from './center_controls/center_controls';
|
||||
@@ -39,20 +34,17 @@ const GlobalHeaderContainer = styled.header`
|
||||
const GlobalHeader = (): JSX.Element | null => {
|
||||
const isLoggedIn = useIsLoggedIn();
|
||||
const currentProductID = useCurrentProductId();
|
||||
const theme = useSelector(getTheme);
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<GlobalHeaderContainer id='global-header'>
|
||||
<LeftControls/>
|
||||
<CenterControls productId={currentProductID}/>
|
||||
<RightControls productId={currentProductID}/>
|
||||
</GlobalHeaderContainer>
|
||||
</CompassThemeProvider>
|
||||
<GlobalHeaderContainer id='global-header'>
|
||||
<LeftControls/>
|
||||
<CenterControls productId={currentProductID}/>
|
||||
<RightControls productId={currentProductID}/>
|
||||
</GlobalHeaderContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/* stylelint-disable no-duplicate-selectors */
|
||||
|
||||
.HeaderIconButton {
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
width: auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
padding: 6px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
margin: 0;
|
||||
|
||||
background: rgba(var(--bg-color), var(--bg-opacity));
|
||||
color: rgba(var(--text-color), var(--text-opacity));
|
||||
font: inherit;
|
||||
outline: none;
|
||||
text-align: inherit;
|
||||
|
||||
--bg-color: var(--sidebar-header-text-color-rgb);
|
||||
--text-color: var(--sidebar-header-text-color-rgb);
|
||||
&--toggled:not(:disabled) {
|
||||
--text-color: var(--sidebar-header-bg-rgb);
|
||||
}
|
||||
|
||||
&:not(:disabled) {
|
||||
--bg-opacity: 0;
|
||||
--text-opacity: 0.56;
|
||||
|
||||
&:hover {
|
||||
--bg-opacity: 0.08;
|
||||
--text-opacity: 0.72;
|
||||
}
|
||||
|
||||
&.HeaderIconButton--toggled {
|
||||
--bg-opacity: 1;
|
||||
--text-opacity: 1;
|
||||
|
||||
&:hover {
|
||||
--bg-opacity: 0.92;
|
||||
--text-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.HeaderIconButton--active, &:active {
|
||||
--bg-opacity: 0.16;
|
||||
--text-opacity: 1;
|
||||
}
|
||||
}
|
||||
&:disabled {
|
||||
cursor: no-allowed;
|
||||
|
||||
--bg-opacity: 0;
|
||||
--text-opacity: 0.32;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.32),
|
||||
inset 0 0 0 2px var(--sidebar-header-bg);
|
||||
}
|
||||
|
||||
& > i {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
padding: 0;
|
||||
|
||||
color: inherit;
|
||||
|
||||
&::before {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
letter-spacing: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
import './header_icon_button.scss';
|
||||
|
||||
type HeaderIconButtonProps = React.HTMLAttributes<HTMLButtonElement> & {
|
||||
icon: string;
|
||||
|
||||
active?: boolean;
|
||||
toggled?: boolean;
|
||||
};
|
||||
|
||||
const HeaderIconButton = React.forwardRef<HTMLButtonElement, HeaderIconButtonProps>(({
|
||||
icon = 'mattermost',
|
||||
active,
|
||||
toggled,
|
||||
...otherProps
|
||||
}, ref) => {
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
className={classNames('HeaderIconButton', {
|
||||
'HeaderIconButton--toggled': toggled,
|
||||
'HeaderIconButton--active': active,
|
||||
})}
|
||||
{...otherProps}
|
||||
>
|
||||
<i className={`icon-${icon}`}/>
|
||||
</button>
|
||||
);
|
||||
});
|
||||
HeaderIconButton.displayName = 'HeaderIconButton';
|
||||
export default HeaderIconButton;
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import HeaderIconButton from './header_icon_button';
|
||||
|
||||
export default HeaderIconButton;
|
||||
+1
-8
@@ -6,10 +6,9 @@ import {useIntl} from 'react-intl';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
import KeyboardShortcutSequence, {
|
||||
KEYBOARD_SHORTCUTS,
|
||||
} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
|
||||
@@ -78,9 +77,6 @@ const HistoryButtons = (): JSX.Element => {
|
||||
<IconButton
|
||||
icon={'arrow-left'}
|
||||
onClick={goBack}
|
||||
size={'sm'}
|
||||
compact={true}
|
||||
inverted={true}
|
||||
disabled={!canGoBack}
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.channel_navigator.goBackLabel', defaultMessage: 'Back'})}
|
||||
/>
|
||||
@@ -91,9 +87,6 @@ const HistoryButtons = (): JSX.Element => {
|
||||
<IconButton
|
||||
icon={'arrow-right'}
|
||||
onClick={goForward}
|
||||
size={'sm'}
|
||||
compact={true}
|
||||
inverted={true}
|
||||
disabled={!canGoForward}
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.channel_navigator.goForwardLabel', defaultMessage: 'Forward'})}
|
||||
/>
|
||||
|
||||
+6
-15
@@ -7,14 +7,11 @@ exports[`components/ProductBranding should show correct icon glyph when we are o
|
||||
<ProductBoardsIcon
|
||||
size={24}
|
||||
/>
|
||||
<Heading
|
||||
<h1
|
||||
className="sr-only"
|
||||
element="h1"
|
||||
margin="none"
|
||||
size={200}
|
||||
>
|
||||
Boards
|
||||
</Heading>
|
||||
</h1>
|
||||
<ProductBrandingHeading>
|
||||
Boards
|
||||
</ProductBrandingHeading>
|
||||
@@ -28,14 +25,11 @@ exports[`components/ProductBranding should show correct icon glyph when we are o
|
||||
<ProductChannelsIcon
|
||||
size={24}
|
||||
/>
|
||||
<Heading
|
||||
<h1
|
||||
className="sr-only"
|
||||
element="h1"
|
||||
margin="none"
|
||||
size={200}
|
||||
>
|
||||
Channels
|
||||
</Heading>
|
||||
</h1>
|
||||
<ProductBrandingHeading>
|
||||
Channels
|
||||
</ProductBrandingHeading>
|
||||
@@ -49,14 +43,11 @@ exports[`components/ProductBranding should show correct icon glyph when we are o
|
||||
<ProductPlaybooksIcon
|
||||
size={24}
|
||||
/>
|
||||
<Heading
|
||||
<h1
|
||||
className="sr-only"
|
||||
element="h1"
|
||||
margin="none"
|
||||
size={200}
|
||||
>
|
||||
Playbooks
|
||||
</Heading>
|
||||
</h1>
|
||||
<ProductBrandingHeading>
|
||||
Playbooks
|
||||
</ProductBrandingHeading>
|
||||
|
||||
+2
-13
@@ -4,7 +4,6 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import Heading from '@mattermost/compass-components/components/heading'; // eslint-disable-line no-restricted-imports
|
||||
import glyphMap, {ProductChannelsIcon} from '@mattermost/compass-icons/components';
|
||||
|
||||
import {useCurrentProduct} from 'utils/products';
|
||||
@@ -14,8 +13,6 @@ const ProductBrandingContainer = styled.span`
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
// Every style here except for 'margin-left' and 'font-family'is from the deprecated 'Heading' element.
|
||||
// https://github.com/mattermost/compass-components/blob/362e96a4eb3489efc8c1852652859ef14a51eb64/src/components/heading/Heading.mixins.ts#L9-L74
|
||||
const ProductBrandingHeading = styled.span`
|
||||
font-family: 'Metropolis';
|
||||
font-size: 16px;
|
||||
@@ -35,17 +32,9 @@ const ProductBranding = (): JSX.Element => {
|
||||
return (
|
||||
<ProductBrandingContainer tabIndex={-1}>
|
||||
<Icon size={24}/>
|
||||
|
||||
{/* Heading for screen readers since an h1 shouldn't be inside a button */}
|
||||
<Heading
|
||||
element='h1'
|
||||
size={200}
|
||||
margin='none'
|
||||
className='sr-only'
|
||||
>
|
||||
<h1 className='sr-only'>
|
||||
{currentProduct ? currentProduct.switcherText : 'Channels'}
|
||||
</Heading>
|
||||
|
||||
</h1>
|
||||
<ProductBrandingHeading>
|
||||
{currentProduct ? currentProduct.switcherText : 'Channels'}
|
||||
</ProductBrandingHeading>
|
||||
|
||||
+1
-4
@@ -27,15 +27,12 @@ exports[`components/global/AtMentionsButton should match snapshot 1`] = `
|
||||
</React.Fragment>
|
||||
}
|
||||
>
|
||||
<ForwardRef
|
||||
<HeaderIconButton
|
||||
aria-controls="searchContainer"
|
||||
aria-expanded={false}
|
||||
aria-label="Recent mentions"
|
||||
compact={true}
|
||||
icon="at"
|
||||
inverted={true}
|
||||
onClick={[Function]}
|
||||
size="sm"
|
||||
toggled={false}
|
||||
/>
|
||||
</WithTooltip>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
|
||||
+1
-5
@@ -5,11 +5,10 @@ import React from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {closeRightHandSide, showMentions} from 'actions/views/rhs';
|
||||
import {getRhsState} from 'selectors/rhs';
|
||||
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
import KeyboardShortcutSequence, {KEYBOARD_SHORTCUTS} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
@@ -48,12 +47,9 @@ const AtMentionsButton = (): JSX.Element => {
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
size={'sm'}
|
||||
icon={'at'}
|
||||
toggled={rhsState === RHSStates.MENTION}
|
||||
onClick={mentionButtonClick}
|
||||
inverted={true}
|
||||
compact={true}
|
||||
aria-expanded={rhsState === RHSStates.MENTION}
|
||||
aria-controls='searchContainer' // Must be changed if the ID of the container changes
|
||||
aria-label={formatMessage({id: 'channel_header.recentMentions', defaultMessage: 'Recent mentions'})}
|
||||
|
||||
+1
-4
@@ -9,15 +9,12 @@ exports[`components/global/AtMentionsButton should match snapshot 1`] = `
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ForwardRef
|
||||
<HeaderIconButton
|
||||
aria-controls="searchContainer"
|
||||
aria-expanded={false}
|
||||
aria-label="Saved messages"
|
||||
compact={true}
|
||||
icon="bookmark-outline"
|
||||
inverted={true}
|
||||
onClick={[Function]}
|
||||
size="sm"
|
||||
toggled={false}
|
||||
/>
|
||||
</WithTooltip>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
|
||||
+1
-5
@@ -5,11 +5,10 @@ import React from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {closeRightHandSide, showFlaggedPosts} from 'actions/views/rhs';
|
||||
import {getRhsState} from 'selectors/rhs';
|
||||
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
import {RHSStates} from 'utils/constants';
|
||||
@@ -40,12 +39,9 @@ const SavedPostsButton = (): JSX.Element | null => {
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
size={'sm'}
|
||||
icon={'bookmark-outline'}
|
||||
toggled={rhsState === RHSStates.FLAG}
|
||||
onClick={savedPostsButtonClick}
|
||||
inverted={true}
|
||||
compact={true}
|
||||
aria-expanded={rhsState === RHSStates.FLAG}
|
||||
aria-controls='searchContainer' // Must be changed if the ID of the container changes
|
||||
aria-label={formatMessage({id: 'channel_header.flagged', defaultMessage: 'Saved messages'})}
|
||||
|
||||
+1
-5
@@ -4,8 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
|
||||
import IconButton from '@mattermost/compass-components/components/icon-button'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import IconButton from 'components/global_header/header_icon_button';
|
||||
import UserSettingsModal from 'components/user_settings/modal';
|
||||
import WithTooltip from 'components/with_tooltip';
|
||||
|
||||
@@ -32,13 +31,10 @@ const SettingsButton = (props: Props): JSX.Element | null => {
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
size={'sm'}
|
||||
icon={'settings-outline'}
|
||||
onClick={(): void => {
|
||||
props.actions.openModal({modalId: ModalIdentifiers.USER_SETTINGS, dialogType: UserSettingsModal, dialogProps: {isContentProductSettings: true, focusOriginElement: 'settings_button'}});
|
||||
}}
|
||||
inverted={true}
|
||||
compact={true}
|
||||
aria-haspopup='dialog'
|
||||
aria-label={formatMessage({id: 'global_header.productSettings', defaultMessage: 'Settings'})}
|
||||
/>
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {Team} from '@mattermost/types/teams';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import deepFreeze from 'mattermost-redux/utils/deep_freeze';
|
||||
|
||||
import {mountWithThemedIntl} from 'tests/helpers/themed-intl-test-helper';
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {SelfHostedProducts} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
@@ -116,7 +116,7 @@ describe('InvitationModal', () => {
|
||||
});
|
||||
|
||||
it('shows invite view when view state is invite', () => {
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InvitationModal {...props}/>
|
||||
</Provider>,
|
||||
@@ -125,7 +125,7 @@ describe('InvitationModal', () => {
|
||||
});
|
||||
|
||||
it('shows result view when view state is result', () => {
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InvitationModal {...props}/>
|
||||
</Provider>,
|
||||
@@ -142,7 +142,7 @@ describe('InvitationModal', () => {
|
||||
canAddUsers: false,
|
||||
canInviteGuests: false,
|
||||
};
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InvitationModal {...props}/>
|
||||
</Provider>,
|
||||
@@ -172,7 +172,7 @@ describe('InvitationModal', () => {
|
||||
invitableChannels: [regularChannel, policyEnforcedChannel],
|
||||
};
|
||||
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InvitationModal {...props}/>
|
||||
</Provider>,
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {Team} from '@mattermost/types/teams';
|
||||
|
||||
import deepFreeze from 'mattermost-redux/utils/deep_freeze';
|
||||
|
||||
import {mountWithThemedIntl} from 'tests/helpers/themed-intl-test-helper';
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {SelfHostedProducts} from 'utils/constants';
|
||||
import {TestHelper as TH} from 'utils/test_helper';
|
||||
@@ -127,7 +127,7 @@ describe('InviteView', () => {
|
||||
|
||||
it('shows InviteAs component when user can choose to invite guests or users', async () => {
|
||||
await act(async () => {
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InviteView {...props}/>
|
||||
</Provider>,
|
||||
@@ -143,7 +143,7 @@ describe('InviteView', () => {
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InviteView {...props}/>
|
||||
</Provider>,
|
||||
@@ -159,7 +159,7 @@ describe('InviteView', () => {
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
const wrapper = mountWithThemedIntl(
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<InviteView {...props}/>
|
||||
</Provider>,
|
||||
|
||||
@@ -5,11 +5,8 @@ import React, {lazy} from 'react';
|
||||
import type {RouteComponentProps} from 'react-router-dom';
|
||||
import {Route} from 'react-router-dom';
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {makeAsyncComponent} from 'components/async_load';
|
||||
import CloudPreviewModalController from 'components/cloud_preview_modal/cloud_preview_modal_controller';
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import LoggedIn from 'components/logged_in';
|
||||
|
||||
const OnBoardingTaskList = makeAsyncComponent('OnboardingTaskList', lazy(() => import('components/onboarding_tasklist')));
|
||||
@@ -17,23 +14,18 @@ const OnBoardingTaskList = makeAsyncComponent('OnboardingTaskList', lazy(() => i
|
||||
type Props = {
|
||||
component: React.ComponentType<RouteComponentProps<any>>;
|
||||
path: string | string[];
|
||||
theme?: Theme; // the routes that send the theme are the ones that will actually need to show the onboarding tasklist
|
||||
};
|
||||
|
||||
export default function LoggedInRoute(props: Props) {
|
||||
const {component: Component, theme, ...rest} = props;
|
||||
const {component: Component, ...rest} = props;
|
||||
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={(routeProps) => (
|
||||
<LoggedIn {...routeProps}>
|
||||
{theme && (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<OnBoardingTaskList/>
|
||||
<CloudPreviewModalController/>
|
||||
</CompassThemeProvider>
|
||||
)}
|
||||
<OnBoardingTaskList/>
|
||||
<CloudPreviewModalController/>
|
||||
<Component {...(routeProps)}/>
|
||||
</LoggedIn>
|
||||
)}
|
||||
|
||||
@@ -15,14 +15,12 @@ import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general
|
||||
import {
|
||||
getBool,
|
||||
getMyPreferences as getMyPreferencesSelector,
|
||||
getTheme,
|
||||
} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
import {getShowTaskListBool} from 'selectors/onboarding';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import {useFirstAdminUser, useIsCurrentUserSystemAdmin} from 'components/global_header/hooks';
|
||||
import {
|
||||
useTasksListWithStatus,
|
||||
@@ -157,7 +155,6 @@ const OnBoardingTaskList = (): JSX.Element | null => {
|
||||
getShowTaskListBool,
|
||||
(a, b) => a[0] === b[0] && a[1] === b[1],
|
||||
);
|
||||
const theme = useSelector(getTheme);
|
||||
|
||||
const startTask = (taskName: string) => {
|
||||
toggleTaskList();
|
||||
@@ -254,7 +251,7 @@ const OnBoardingTaskList = (): JSX.Element | null => {
|
||||
}
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<>
|
||||
<CompletedAnimation completed={showAnimation}/>
|
||||
<Button
|
||||
onClick={toggleTaskList}
|
||||
@@ -315,7 +312,7 @@ const OnBoardingTaskList = (): JSX.Element | null => {
|
||||
)}
|
||||
</TaskItems>
|
||||
</TaskListPopover>
|
||||
</CompassThemeProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+29
-26
@@ -4,8 +4,6 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import StatusIcon from '@mattermost/compass-components/components/status-icon'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
const Animation = styled.div`
|
||||
position: absolute;
|
||||
z-index: 30;
|
||||
@@ -33,6 +31,23 @@ const Animation = styled.div`
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.icon-check-circle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: var(--online-indicator);
|
||||
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
::before {
|
||||
font-size: 18px;
|
||||
letter-spacing: 18px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.x1 {
|
||||
opacity: 0;
|
||||
animation-delay: 150ms;
|
||||
@@ -64,34 +79,34 @@ const Animation = styled.div`
|
||||
}
|
||||
}
|
||||
@keyframes moveUp {
|
||||
0% {
|
||||
0% {
|
||||
top: 0;
|
||||
}
|
||||
100% {
|
||||
100% {
|
||||
top: -50px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes opacity {
|
||||
0% {
|
||||
0% {
|
||||
opacity:0;
|
||||
}
|
||||
50% {
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scale {
|
||||
0% {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
50% {
|
||||
transform: scale(2);
|
||||
}
|
||||
100% {
|
||||
100% {
|
||||
transform: scale(4);
|
||||
}
|
||||
}
|
||||
@@ -101,22 +116,10 @@ const Animation = styled.div`
|
||||
export const CompletedAnimation = (props: {completed: boolean}) => {
|
||||
return (
|
||||
<Animation className={props.completed ? 'completed' : ''}>
|
||||
<StatusIcon
|
||||
status={'online'}
|
||||
className={'x1'}
|
||||
/>
|
||||
<StatusIcon
|
||||
status={'online'}
|
||||
className={'x2'}
|
||||
/>
|
||||
<StatusIcon
|
||||
status={'online'}
|
||||
className={'x3'}
|
||||
/>
|
||||
<StatusIcon
|
||||
status={'online'}
|
||||
className={'x4'}
|
||||
/>
|
||||
<i className='icon-check-circle x1'/>
|
||||
<i className='icon-check-circle x2'/>
|
||||
<i className='icon-check-circle x3'/>
|
||||
<i className='icon-check-circle x4'/>
|
||||
</Animation>
|
||||
);
|
||||
};
|
||||
|
||||
-3
@@ -5,8 +5,6 @@ import {screen, fireEvent} from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import {ModalIdentifiers} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
@@ -22,7 +20,6 @@ describe('components/post_edit_history/edited_post_item', () => {
|
||||
message: 'post message',
|
||||
}),
|
||||
isCurrent: false,
|
||||
theme: {} as Theme,
|
||||
postCurrentVersion: TestHelper.getPostMock({
|
||||
id: 'post_current_version_id',
|
||||
message: 'post current version message',
|
||||
|
||||
+30
-35
@@ -10,13 +10,11 @@ import {CheckIcon} from '@mattermost/compass-icons/components';
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
|
||||
import {getPostEditHistory, restorePostVersion} from 'mattermost-redux/actions/posts';
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {ensureString} from 'mattermost-redux/utils/post_utils';
|
||||
|
||||
import {removeDraft} from 'actions/views/drafts';
|
||||
import {getConnectionId} from 'selectors/general';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
import FileAttachmentListContainer from 'components/file_attachment_list';
|
||||
import InfoToast from 'components/info_toast/info_toast';
|
||||
import PostAriaLabelDiv from 'components/post_view/post_aria_label_div';
|
||||
@@ -58,10 +56,9 @@ const itemMessages = defineMessages({
|
||||
export type Props = PropsFromRedux & {
|
||||
post: Post;
|
||||
isCurrent?: boolean;
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
const EditedPostItem = ({post, isCurrent = false, postCurrentVersion, theme, actions}: Props) => {
|
||||
const EditedPostItem = ({post, isCurrent = false, postCurrentVersion, actions}: Props) => {
|
||||
const {formatMessage} = useIntl();
|
||||
const [open, setOpen] = useState(isCurrent);
|
||||
|
||||
@@ -220,40 +217,38 @@ const EditedPostItem = ({post, isCurrent = false, postCurrentVersion, theme, act
|
||||
const timeStampValue = post.edit_at === 0 ? post.create_at : post.edit_at;
|
||||
|
||||
return (
|
||||
<CompassThemeProvider theme={theme}>
|
||||
<div
|
||||
className={postContainerClass}
|
||||
onClick={togglePost}
|
||||
<div
|
||||
className={postContainerClass}
|
||||
onClick={togglePost}
|
||||
>
|
||||
<PostAriaLabelDiv
|
||||
className={'a11y__section post'}
|
||||
id={'searchResult_' + post.id}
|
||||
post={post}
|
||||
>
|
||||
<PostAriaLabelDiv
|
||||
className={'a11y__section post'}
|
||||
id={'searchResult_' + post.id}
|
||||
post={post}
|
||||
<div
|
||||
className='edit-post-history__title__container'
|
||||
>
|
||||
<div
|
||||
className='edit-post-history__title__container'
|
||||
>
|
||||
<div className='edit-post-history__date__badge__container'>
|
||||
<button
|
||||
aria-label='Toggle to see an old message.'
|
||||
className='edit-post-history__icon__button toggleCollapseButton'
|
||||
>
|
||||
<i className={`icon ${open ? 'icon-chevron-down' : 'icon-chevron-right'}`}/>
|
||||
</button>
|
||||
<span className='edit-post-history__date'>
|
||||
<Timestamp
|
||||
value={timeStampValue}
|
||||
ranges={DATE_RANGES}
|
||||
/>
|
||||
</span>
|
||||
{currentVersionIndicator}
|
||||
</div>
|
||||
{restoreButton}
|
||||
<div className='edit-post-history__date__badge__container'>
|
||||
<button
|
||||
aria-label='Toggle to see an old message.'
|
||||
className='edit-post-history__icon__button toggleCollapseButton'
|
||||
>
|
||||
<i className={`icon ${open ? 'icon-chevron-down' : 'icon-chevron-right'}`}/>
|
||||
</button>
|
||||
<span className='edit-post-history__date'>
|
||||
<Timestamp
|
||||
value={timeStampValue}
|
||||
ranges={DATE_RANGES}
|
||||
/>
|
||||
</span>
|
||||
{currentVersionIndicator}
|
||||
</div>
|
||||
{open && messageContainer}
|
||||
</PostAriaLabelDiv>
|
||||
</div>
|
||||
</CompassThemeProvider>
|
||||
{restoreButton}
|
||||
</div>
|
||||
{open && messageContainer}
|
||||
</PostAriaLabelDiv>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import {bindActionCreators} from 'redux';
|
||||
import type {Dispatch} from 'redux';
|
||||
|
||||
import {getPost} from 'mattermost-redux/selectors/entities/posts';
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import {openModal} from 'actions/views/modals';
|
||||
import {editPost} from 'actions/views/posts';
|
||||
@@ -20,10 +19,8 @@ import EditedPostItem from './edited_post_item';
|
||||
|
||||
function mapStateToProps(state: GlobalState) {
|
||||
const selectedPostId = getSelectedPostId(state) || '';
|
||||
const theme = getTheme(state);
|
||||
|
||||
return {
|
||||
theme,
|
||||
postCurrentVersion: getPost(state, selectedPostId),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import {ServiceEnvironment} from '@mattermost/types/config';
|
||||
import {setSystemEmojis} from 'mattermost-redux/actions/emojis';
|
||||
import {setUrl} from 'mattermost-redux/actions/general';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import {measurePageLoadTelemetry, temporarilySetPageLoadContext, trackEvent} from 'actions/telemetry_actions.jsx';
|
||||
import BrowserStore from 'stores/browser_store';
|
||||
@@ -69,7 +68,6 @@ const CreateTeam = makeAsyncComponent('CreateTeam', lazy(() => import('component
|
||||
const Mfa = makeAsyncComponent('Mfa', lazy(() => import('components/mfa/mfa_controller')));
|
||||
const PreparingWorkspace = makeAsyncComponent('PreparingWorkspace', lazy(() => import('components/preparing_workspace')));
|
||||
const LaunchingWorkspace = makeAsyncComponent('LaunchingWorkspace', lazy(() => import('components/preparing_workspace/launching_workspace')));
|
||||
const CompassThemeProvider = makeAsyncComponent('CompassThemeProvider', lazy(() => import('components/compass_theme_provider/compass_theme_provider')));
|
||||
const TeamController = makeAsyncComponent('TeamController', lazy(() => import('components/team_controller')));
|
||||
const AnnouncementBarController = makeAsyncComponent('AnnouncementBarController', lazy(() => import('components/announcement_bar')));
|
||||
const SystemNotice = makeAsyncComponent('SystemNotice', lazy(() => import('components/system_notice')));
|
||||
@@ -454,7 +452,6 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
>
|
||||
<Switch>
|
||||
<LoggedInRoute
|
||||
theme={Preferences.THEMES.denim}
|
||||
path={'/admin_console'}
|
||||
component={AdminConsole}
|
||||
/>
|
||||
@@ -489,16 +486,17 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
from={'/_redirect/pl/:postid'}
|
||||
to={`/${this.props.permalinkRedirectTeamName}/pl/:postid`}
|
||||
/>
|
||||
<CompassThemeProvider theme={this.props.theme}>
|
||||
<>
|
||||
{(this.props.showLaunchingWorkspace && !this.props.location.pathname.includes('/preparing-workspace') &&
|
||||
<LaunchingWorkspace
|
||||
fullscreen={true}
|
||||
zIndex={LAUNCHING_WORKSPACE_FULLSCREEN_Z_INDEX}
|
||||
show={true}
|
||||
onPageView={noop}
|
||||
transitionDirection={Animations.Reasons.EnterFromBefore}
|
||||
/>
|
||||
<LaunchingWorkspace
|
||||
fullscreen={true}
|
||||
zIndex={LAUNCHING_WORKSPACE_FULLSCREEN_Z_INDEX}
|
||||
show={true}
|
||||
onPageView={noop}
|
||||
transitionDirection={Animations.Reasons.EnterFromBefore}
|
||||
/>
|
||||
)}
|
||||
|
||||
<WindowSizeObserver/>
|
||||
<ModalController/>
|
||||
<AnnouncementBarController/>
|
||||
@@ -568,7 +566,6 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
/>
|
||||
))}
|
||||
<LoggedInRoute
|
||||
theme={this.props.theme}
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})`}
|
||||
component={TeamController}
|
||||
/>
|
||||
@@ -579,7 +576,7 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
<Pluggable pluggableName='Global'/>
|
||||
<AppBar/>
|
||||
<Readout/>
|
||||
</CompassThemeProvider>
|
||||
</>
|
||||
</Switch>
|
||||
</RootProvider>
|
||||
);
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
import CompassThemeProvider from 'components/compass_theme_provider/compass_theme_provider';
|
||||
|
||||
import {mountWithIntl} from './intl-test-helper';
|
||||
|
||||
const stubValue = '#fff';
|
||||
const DEFAULT_THEME: Theme = {
|
||||
type: 'custom',
|
||||
sidebarBg: stubValue,
|
||||
sidebarText: stubValue,
|
||||
sidebarUnreadText: stubValue,
|
||||
sidebarTextHoverBg: stubValue,
|
||||
sidebarTextActiveBorder: stubValue,
|
||||
sidebarTextActiveColor: stubValue,
|
||||
sidebarHeaderBg: stubValue,
|
||||
sidebarTeamBarBg: stubValue,
|
||||
sidebarHeaderTextColor: stubValue,
|
||||
onlineIndicator: stubValue,
|
||||
awayIndicator: stubValue,
|
||||
dndIndicator: stubValue,
|
||||
mentionBg: stubValue,
|
||||
mentionBj: stubValue,
|
||||
mentionColor: stubValue,
|
||||
centerChannelBg: stubValue,
|
||||
centerChannelColor: stubValue,
|
||||
newMessageSeparator: stubValue,
|
||||
linkColor: stubValue,
|
||||
buttonBg: stubValue,
|
||||
buttonColor: stubValue,
|
||||
errorTextColor: stubValue,
|
||||
mentionHighlightBg: stubValue,
|
||||
mentionHighlightLink: stubValue,
|
||||
codeTheme: stubValue,
|
||||
};
|
||||
|
||||
export const mountWithThemedIntl = (children: React.ReactNode | React.ReactNodeArray, theme?: Theme) => {
|
||||
return mountWithIntl(
|
||||
<CompassThemeProvider
|
||||
theme={theme || DEFAULT_THEME}
|
||||
>
|
||||
{children}
|
||||
</CompassThemeProvider>,
|
||||
);
|
||||
};
|
||||
Generated
-85
@@ -65,7 +65,6 @@
|
||||
"@giphy/react-components": "8.1.0",
|
||||
"@guyplusplus/turndown-plugin-gfm": "1.0.7",
|
||||
"@mattermost/client": "10.11.0",
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/desktop-api": "5.10.0-2",
|
||||
"@mattermost/dynamic-virtualized-list": "github:mattermost/dynamic-virtualized-list#08dde0c34a12d0384740db27d55e398d139d7a51",
|
||||
"@mattermost/types": "10.11.0",
|
||||
@@ -304,40 +303,6 @@
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@mattermost/compass-components": {
|
||||
"version": "0.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/compass-components/-/compass-components-0.2.12.tgz",
|
||||
"integrity": "sha512-45ObrULlchyH8cNwGbb18ifsBSMtKHFo/VxBIxl1tNvrhqgD+tNafvlz9pO+Xy+1yFkm/pZtYr2aqZpXGXeQ8Q==",
|
||||
"dependencies": {
|
||||
"@mattermost/compass-icons": "^0.1.10",
|
||||
"@popperjs/core": "^2.9.2",
|
||||
"axios": "^0.21.1",
|
||||
"clsx": "^1.1.1",
|
||||
"color-blend": "^3.0.1",
|
||||
"csstype": "^3.0.8",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"lodash.random": "^3.2.0",
|
||||
"lodash.upperfirst": "^4.3.1",
|
||||
"react-popper": "^2.2.5",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"styled-components": "^5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.13.1 || ^17.0.1",
|
||||
"react-dom": "16.13.1 || ^17.0.1"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@mattermost/compass-components/node_modules/axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@stylistic/stylelint-plugin": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.2.tgz",
|
||||
@@ -10497,14 +10462,6 @@
|
||||
"integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/color-blend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-blend/-/color-blend-3.0.1.tgz",
|
||||
"integrity": "sha512-KueDvNiKHAvVeApic0SxHZLyy4x3NELfTLzMHRpRRLi+9e2kWhpeWvtuH3Sjb92mOJYEUhRjb8z7lr4OqDv17Q==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-contrast-checker": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/color-contrast-checker/-/color-contrast-checker-2.1.0.tgz",
|
||||
@@ -20559,32 +20516,17 @@
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.kebabcase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
|
||||
"integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"node_modules/lodash.random": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.random/-/lodash.random-3.2.0.tgz",
|
||||
"integrity": "sha512-A6Vn7teN0+qSnhOsE8yx2bGowCS1G7D9e5abq8VhwOP98YHS/KrGMf43yYxA05lvcvloT+W9Z2ffkSajFTcPUA=="
|
||||
},
|
||||
"node_modules/lodash.truncate": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||
"integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.upperfirst": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
|
||||
"integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
@@ -23244,11 +23186,6 @@
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-fast-compare": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||
},
|
||||
"node_modules/react-intl": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.2.tgz",
|
||||
@@ -23353,28 +23290,6 @@
|
||||
"react-dom": ">=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
|
||||
"integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
|
||||
"dependencies": {
|
||||
"react-fast-compare": "^3.0.1",
|
||||
"warning": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.0.0",
|
||||
"react": "^16.8.0 || ^17 || ^18",
|
||||
"react-dom": "^16.8.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper/node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-prop-types": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz",
|
||||
|
||||
@@ -374,12 +374,6 @@
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": ["@mattermost/compass-components/*"],
|
||||
"message": "compass-components is now archived."
|
||||
}
|
||||
],
|
||||
"paths": [
|
||||
{
|
||||
"name": "redux",
|
||||
|
||||
Reference in New Issue
Block a user