MM-49869 - add channels button lhs sidebar (#22701)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
29cff3269c
Коммит
bb939e28c9
@@ -9,3 +9,10 @@ export function setAddChannelDropdown(open: boolean) {
|
||||
open,
|
||||
};
|
||||
}
|
||||
|
||||
export function setAddChannelCtaDropdown(open: boolean) {
|
||||
return {
|
||||
type: ActionTypes.ADD_CHANNEL_CTA_DROPDOWN_TOGGLE,
|
||||
open,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/new_channel_modal should match snapshot 1`] = `
|
||||
<MenuWrapper
|
||||
animationComponent={[Function]}
|
||||
className="AddChannelsCtaDropdown"
|
||||
onToggle={[Function]}
|
||||
open={false}
|
||||
>
|
||||
<button
|
||||
aria-label="Add Channels Dropdown"
|
||||
className="SidebarChannelNavigator__addChannelsCtaLhsButton SidebarChannelNavigator__addChannelsCtaLhsButton--untouched"
|
||||
id="addChannelsCta"
|
||||
>
|
||||
<li
|
||||
aria-label="Add channels"
|
||||
>
|
||||
<i
|
||||
className="icon-plus-box"
|
||||
/>
|
||||
<span>
|
||||
Add Channels
|
||||
</span>
|
||||
</li>
|
||||
</button>
|
||||
<Menu
|
||||
ariaLabel="Add Channels Dropdown"
|
||||
id="AddChannelCtaDropdown"
|
||||
>
|
||||
<MenuGroup>
|
||||
<MenuItemAction
|
||||
id="showNewChannel"
|
||||
onClick={[Function]}
|
||||
show={true}
|
||||
text="Create New Channel"
|
||||
/>
|
||||
<MenuItemAction
|
||||
id="showMoreChannels"
|
||||
onClick={[Function]}
|
||||
show={true}
|
||||
text="Browse Channels"
|
||||
/>
|
||||
</MenuGroup>
|
||||
</Menu>
|
||||
</MenuWrapper>
|
||||
`;
|
||||
@@ -82,7 +82,7 @@ exports[`components/sidebar/invite_members_button should match snapshot 1`] = `
|
||||
>
|
||||
<li
|
||||
aria-label="Invite Members"
|
||||
className="SidebarChannelNavigator_inviteMembersLhsButton SidebarChannelNavigator_inviteMembersLhsButton--untouched"
|
||||
className="SidebarChannelNavigator__inviteMembersLhsButton SidebarChannelNavigator__inviteMembersLhsButton--untouched"
|
||||
>
|
||||
<i
|
||||
className="icon-plus-box"
|
||||
|
||||
@@ -189,14 +189,12 @@ const AddChannelDropdown = ({
|
||||
placement='top'
|
||||
overlay={tooltip}
|
||||
>
|
||||
<>
|
||||
<button
|
||||
className={'AddChannelDropdown_dropdownButton'}
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.add_channel_dropdown.dropdownAriaLabel', defaultMessage: 'Add Channel Dropdown'})}
|
||||
>
|
||||
<i className='icon-plus'/>
|
||||
</button>
|
||||
</>
|
||||
<button
|
||||
className={'AddChannelDropdown_dropdownButton'}
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.add_channel_dropdown.dropdownAriaLabel', defaultMessage: 'Add Channel Dropdown'})}
|
||||
>
|
||||
<i className='icon-plus'/>
|
||||
</button>
|
||||
</OverlayTrigger>
|
||||
<Menu
|
||||
id='AddChannelDropdown'
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
|
||||
import {GlobalState} from 'types/store';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {UsersState} from '@mattermost/types/users';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions.jsx';
|
||||
|
||||
import AddChannelsCtaButton from './add_channels_cta_button';
|
||||
|
||||
jest.mock('actions/telemetry_actions.jsx', () => {
|
||||
const original = jest.requireActual('actions/telemetry_actions.jsx');
|
||||
return {
|
||||
...original,
|
||||
trackEvent: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
let mockState: GlobalState;
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
...jest.requireActual('react-redux') as typeof import('react-redux'),
|
||||
useSelector: (selector: (state: typeof mockState) => unknown) => selector(mockState),
|
||||
useDispatch: () => mockDispatch,
|
||||
}));
|
||||
|
||||
describe('components/new_channel_modal', () => {
|
||||
beforeEach(() => {
|
||||
mockState = {
|
||||
entities: {
|
||||
general: {
|
||||
config: {},
|
||||
},
|
||||
channels: {
|
||||
currentChannelId: 'current_channel_id',
|
||||
channels: {},
|
||||
roles: {
|
||||
current_channel_id: [
|
||||
'channel_user',
|
||||
'channel_admin',
|
||||
],
|
||||
},
|
||||
},
|
||||
teams: {
|
||||
currentTeamId: 'current_team_id',
|
||||
myMembers: {
|
||||
current_team_id: {
|
||||
roles: 'team_user team_admin',
|
||||
},
|
||||
},
|
||||
teams: {
|
||||
current_team_id: {
|
||||
id: 'current_team_id',
|
||||
description: 'Curent team description',
|
||||
name: 'current-team',
|
||||
},
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
myPreferences: {},
|
||||
},
|
||||
users: {
|
||||
currentUserId: 'current_user_id',
|
||||
profiles: {
|
||||
current_user_id: {roles: 'system_user'},
|
||||
},
|
||||
},
|
||||
roles: {
|
||||
roles: {
|
||||
guest_user: {
|
||||
permissions: [],
|
||||
},
|
||||
system_user: {
|
||||
permissions: [Permissions.JOIN_PUBLIC_CHANNELS, Permissions.CREATE_PRIVATE_CHANNEL, Permissions.CREATE_PUBLIC_CHANNEL],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
views: {
|
||||
addChannelCtaDropdown: {
|
||||
isOpen: false,
|
||||
},
|
||||
},
|
||||
} as unknown as GlobalState;
|
||||
});
|
||||
|
||||
test('should match snapshot', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<AddChannelsCtaButton/>,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should find the add channels button when user has permissions', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<AddChannelsCtaButton/>,
|
||||
);
|
||||
expect(wrapper.find('.AddChannelsCtaDropdown').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should return nothing when user does not have permissions', () => {
|
||||
const guestUser = {
|
||||
currentUserId: 'guest_user_id',
|
||||
profiles: {
|
||||
user_id: {
|
||||
id: 'guest_user_id',
|
||||
roles: 'team_role',
|
||||
},
|
||||
},
|
||||
} as unknown as UsersState;
|
||||
mockState = {...mockState, entities: {...mockState.entities, users: guestUser}};
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
<AddChannelsCtaButton/>,
|
||||
);
|
||||
expect(wrapper.find('.AddChannelsCtaDropdown').exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should fire dispatch to save preferences when button is clicked', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<AddChannelsCtaButton/>,
|
||||
);
|
||||
const button = wrapper.find('.AddChannelsCtaDropdown button');
|
||||
expect(mockDispatch).not.toHaveBeenCalled();
|
||||
button.simulate('click');
|
||||
expect(mockDispatch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should fire trackEvent to send telemetry when button is clicked', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<AddChannelsCtaButton/>,
|
||||
);
|
||||
|
||||
const button = wrapper.find('.AddChannelsCtaDropdown button');
|
||||
expect(mockDispatch).not.toHaveBeenCalled();
|
||||
button.simulate('click');
|
||||
|
||||
expect(trackEvent).toHaveBeenCalledWith('ui', 'add_channels_cta_button_clicked');
|
||||
});
|
||||
});
|
||||
155
webapp/channels/src/components/sidebar/add_channels_cta_button.tsx
Обычный файл
155
webapp/channels/src/components/sidebar/add_channels_cta_button.tsx
Обычный файл
@@ -0,0 +1,155 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback} from 'react';
|
||||
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import {useSelector, useDispatch} from 'react-redux';
|
||||
|
||||
import MenuWrapper from 'components/widgets/menu/menu_wrapper';
|
||||
import Menu from 'components/widgets/menu/menu';
|
||||
import MoreChannels from 'components/more_channels';
|
||||
import NewChannelModal from 'components/new_channel_modal/new_channel_modal';
|
||||
|
||||
import {isAddChannelCtaDropdownOpen} from 'selectors/views/add_channel_dropdown';
|
||||
|
||||
import {GlobalState} from 'types/store';
|
||||
|
||||
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {haveICurrentChannelPermission} from 'mattermost-redux/selectors/entities/roles';
|
||||
import {DispatchFunc} from 'mattermost-redux/types/actions';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common';
|
||||
|
||||
import {setAddChannelCtaDropdown} from 'actions/views/add_channel_dropdown';
|
||||
import {openModal} from 'actions/views/modals';
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import {ModalIdentifiers, Preferences, Touched} from 'utils/constants';
|
||||
|
||||
const AddChannelsCtaButton = (): JSX.Element | null => {
|
||||
const dispatch = useDispatch<DispatchFunc>();
|
||||
const currentTeamId = useSelector(getCurrentTeamId);
|
||||
const intl = useIntl();
|
||||
const touchedAddChannelsCtaButton = useSelector((state: GlobalState) => getBool(state, Preferences.TOUCHED, Touched.ADD_CHANNELS_CTA));
|
||||
|
||||
const canCreatePublicChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.CREATE_PUBLIC_CHANNEL));
|
||||
const canCreatePrivateChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.CREATE_PRIVATE_CHANNEL));
|
||||
const canCreateChannel = canCreatePrivateChannel || canCreatePublicChannel;
|
||||
const canJoinPublicChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.JOIN_PUBLIC_CHANNELS));
|
||||
const isAddChannelCtaOpen = useSelector(isAddChannelCtaDropdownOpen);
|
||||
const currentUserId = useSelector(getCurrentUserId);
|
||||
const openAddChannelsCtaOpen = useCallback((open: boolean) => {
|
||||
dispatch(setAddChannelCtaDropdown(open));
|
||||
}, []);
|
||||
|
||||
let buttonClass = 'SidebarChannelNavigator__addChannelsCtaLhsButton';
|
||||
|
||||
if (!touchedAddChannelsCtaButton) {
|
||||
buttonClass += ' SidebarChannelNavigator__addChannelsCtaLhsButton--untouched';
|
||||
}
|
||||
|
||||
if ((!canCreateChannel && !canJoinPublicChannel) || !currentTeamId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const showMoreChannelsModal = () => {
|
||||
dispatch(openModal({
|
||||
modalId: ModalIdentifiers.MORE_CHANNELS,
|
||||
dialogType: MoreChannels,
|
||||
dialogProps: {morePublicChannelsModalType: 'public'},
|
||||
}));
|
||||
trackEvent('ui', 'browse_channels_button_is_clicked');
|
||||
};
|
||||
|
||||
const showNewChannelModal = () => {
|
||||
dispatch(openModal({
|
||||
modalId: ModalIdentifiers.NEW_CHANNEL_MODAL,
|
||||
dialogType: NewChannelModal,
|
||||
}));
|
||||
trackEvent('ui', 'create_new_channel_button_is_clicked');
|
||||
};
|
||||
|
||||
const renderDropdownItems = () => {
|
||||
let joinPublicChannel;
|
||||
if (canJoinPublicChannel) {
|
||||
joinPublicChannel = (
|
||||
<Menu.ItemAction
|
||||
id='showMoreChannels'
|
||||
onClick={showMoreChannelsModal}
|
||||
text={intl.formatMessage({id: 'sidebar_left.add_channel_dropdown.browseChannels', defaultMessage: 'Browse Channels'})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let createChannel;
|
||||
if (canCreateChannel) {
|
||||
createChannel = (
|
||||
<Menu.ItemAction
|
||||
id='showNewChannel'
|
||||
onClick={showNewChannelModal}
|
||||
text={intl.formatMessage({id: 'sidebar_left.add_channel_dropdown.createNewChannel', defaultMessage: 'Create New Channel'})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Menu.Group>
|
||||
{createChannel}
|
||||
{joinPublicChannel}
|
||||
</Menu.Group>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const trackOpen = (opened: boolean) => {
|
||||
openAddChannelsCtaOpen(opened);
|
||||
trackEvent('ui', 'add_channels_cta_button_clicked');
|
||||
if (!touchedAddChannelsCtaButton) {
|
||||
dispatch(savePreferences(
|
||||
currentUserId,
|
||||
[{
|
||||
category: Preferences.TOUCHED,
|
||||
user_id: currentUserId,
|
||||
name: Touched.ADD_CHANNELS_CTA,
|
||||
value: 'true',
|
||||
}],
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<MenuWrapper
|
||||
className='AddChannelsCtaDropdown'
|
||||
onToggle={trackOpen}
|
||||
open={isAddChannelCtaOpen}
|
||||
>
|
||||
<button
|
||||
className={buttonClass}
|
||||
id={'addChannelsCta'}
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.add_channel_dropdown.dropdownAriaLabel', defaultMessage: 'Add Channels Dropdown'})}
|
||||
>
|
||||
<li
|
||||
aria-label={intl.formatMessage({id: 'sidebar_left.sidebar_channel_navigator.addChannelsCta', defaultMessage: 'Add channels'})}
|
||||
>
|
||||
<i className='icon-plus-box'/>
|
||||
<span>
|
||||
{intl.formatMessage({id: 'sidebar_left.addChannelsCta', defaultMessage: 'Add Channels'})}
|
||||
</span>
|
||||
</li>
|
||||
</button>
|
||||
<Menu
|
||||
id='AddChannelCtaDropdown'
|
||||
ariaLabel={intl.formatMessage({id: 'sidebar_left.add_channel_cta_dropdown.dropdownAriaLabel', defaultMessage: 'Add Channels Dropdown'})}
|
||||
>
|
||||
{renderDropdownItems()}
|
||||
</Menu>
|
||||
</MenuWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddChannelsCtaButton;
|
||||
@@ -32,7 +32,7 @@ type Props = {
|
||||
isAdmin: boolean;
|
||||
}
|
||||
|
||||
const InviteMembersButton: React.FC<Props> = (props: Props): JSX.Element | null => {
|
||||
const InviteMembersButton = (props: Props): JSX.Element | null => {
|
||||
const dispatch = useDispatch<DispatchFunc>();
|
||||
|
||||
const intl = useIntl();
|
||||
@@ -50,10 +50,10 @@ const InviteMembersButton: React.FC<Props> = (props: Props): JSX.Element | null
|
||||
props.onClick();
|
||||
};
|
||||
|
||||
let buttonClass = 'SidebarChannelNavigator_inviteMembersLhsButton';
|
||||
let buttonClass = 'SidebarChannelNavigator__inviteMembersLhsButton';
|
||||
|
||||
if (!props.touchedInviteMembersButton && Number(totalUserCount) <= Constants.USER_LIMIT) {
|
||||
buttonClass += ' SidebarChannelNavigator_inviteMembersLhsButton--untouched';
|
||||
buttonClass += ' SidebarChannelNavigator__inviteMembersLhsButton--untouched';
|
||||
}
|
||||
|
||||
if (!currentTeamId || !totalUserCount) {
|
||||
|
||||
@@ -24,6 +24,8 @@ import KeyboardShortcutSequence, {
|
||||
KEYBOARD_SHORTCUTS,
|
||||
} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
|
||||
|
||||
import AddChannelsCtaButton from '../add_channels_cta_button';
|
||||
|
||||
import SidebarCategorySortingMenu from './sidebar_category_sorting_menu';
|
||||
import SidebarCategoryMenu from './sidebar_category_menu';
|
||||
|
||||
@@ -342,6 +344,13 @@ export default class SidebarCategory extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
let addChannelsCtaButton = null;
|
||||
if (category.type === 'channels' && !category.collapsed) {
|
||||
addChannelsCtaButton = (
|
||||
<AddChannelsCtaButton/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('SidebarChannelGroup a11y__section', {
|
||||
@@ -399,6 +408,7 @@ export default class SidebarCategory extends React.PureComponent<Props, State> {
|
||||
}}
|
||||
</Droppable>
|
||||
{inviteMembersButton}
|
||||
{addChannelsCtaButton}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -4854,6 +4854,7 @@
|
||||
"shortcuts.team_nav.prev.mac": "Previous team:\t⌘|⌥|Up",
|
||||
"shortcuts.team_nav.switcher": "Navigate to a specific team:\tCtrl|Alt|[1-9]",
|
||||
"shortcuts.team_nav.switcher.mac": "Navigate to a specific team:\t⌘|⌥|[1-9]",
|
||||
"sidebar_left.add_channel_cta_dropdown.dropdownAriaLabel": "Add Channel Dropdown",
|
||||
"sidebar_left.add_channel_dropdown.browseChannels": "Browse Channels",
|
||||
"sidebar_left.add_channel_dropdown.browseOrCreateChannels": "Browse or create channels",
|
||||
"sidebar_left.add_channel_dropdown.createCategory": "Create New Category",
|
||||
@@ -4863,6 +4864,7 @@
|
||||
"sidebar_left.add_channel_dropdown.invitePeopleExtraText": "Add people to the team",
|
||||
"sidebar_left.add_channel_dropdown.work_template": "Create from a template",
|
||||
"sidebar_left.add_channel_dropdown.work_template_extra": "Set up a channel with linked boards, and playbooks",
|
||||
"sidebar_left.addChannelsCta": "Add channels",
|
||||
"sidebar_left.channel_filter.filterByUnread": "Filter by unread",
|
||||
"sidebar_left.channel_filter.filterUnreadAria": "unreads filter",
|
||||
"sidebar_left.channel_filter.showAllChannels": "Show all channels",
|
||||
@@ -4901,6 +4903,7 @@
|
||||
"sidebar_left.sidebar_channel_menu.unfavoriteChannel": "Unfavorite",
|
||||
"sidebar_left.sidebar_channel_menu.unmuteChannel": "Unmute Channel",
|
||||
"sidebar_left.sidebar_channel_menu.unmuteConversation": "Unmute Conversation",
|
||||
"sidebar_left.sidebar_channel_navigator.addChannelsCta": "Add channels",
|
||||
"sidebar_left.sidebar_channel_navigator.inviteUsers": "Invite Users",
|
||||
"sidebar_left.sidebar_channel.selectedCount": "{count} selected",
|
||||
"sidebar_right_menu.console": "System Console",
|
||||
|
||||
21
webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts
Обычный файл
21
webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts
Обычный файл
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
import {GenericAction} from 'mattermost-redux/types/actions';
|
||||
|
||||
import {ActionTypes} from 'utils/constants';
|
||||
|
||||
export function isOpen(state = false, action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case ActionTypes.ADD_CHANNEL_CTA_DROPDOWN_TOGGLE:
|
||||
return action.open;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
isOpen,
|
||||
});
|
||||
@@ -25,6 +25,7 @@ import productMenu from './product_menu';
|
||||
import textbox from './textbox';
|
||||
import statusDropdown from './status_dropdown';
|
||||
import addChannelDropdown from './add_channel_dropdown';
|
||||
import addChannelCtaDropdown from './add_channel_cta_dropdown';
|
||||
import threads from './threads';
|
||||
import onboardingTasks from './onboarding_tasks';
|
||||
|
||||
@@ -50,6 +51,7 @@ export default combineReducers({
|
||||
channelSidebar,
|
||||
statusDropdown,
|
||||
addChannelDropdown,
|
||||
addChannelCtaDropdown,
|
||||
onboardingTasks,
|
||||
threads,
|
||||
productMenu,
|
||||
|
||||
@@ -178,6 +178,46 @@ $sidebarOpacityAnimationDuration: 0.15s;
|
||||
}
|
||||
}
|
||||
|
||||
&__inviteMembersLhsButton,
|
||||
&__addChannelsCtaLhsButton {
|
||||
display: flex;
|
||||
padding: 6px 0;
|
||||
margin-left: 15px;
|
||||
color: rgba(var(--sidebar-text-rgb), 0.72);
|
||||
line-height: 20px;
|
||||
list-style: none;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
align-self: flex-end;
|
||||
margin-top: -2px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&--untouched {
|
||||
color: var(--sidebar-unread-text);
|
||||
font-weight: $font-weight--semibold;
|
||||
|
||||
i::before {
|
||||
font-weight: $font-weight--semibold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__addChannelsCtaLhsButton {
|
||||
border: none;
|
||||
margin-left: 0;
|
||||
background: none;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.AddChannelDropdown_dropdownButton,
|
||||
.SidebarChannelNavigator_inviteUsers,
|
||||
.SidebarChannelNavigator_jumpToButton,
|
||||
@@ -700,35 +740,12 @@ $sidebarOpacityAnimationDuration: 0.15s;
|
||||
}
|
||||
}
|
||||
|
||||
.SidebarChannelNavigator_inviteMembersLhsButton {
|
||||
display: flex;
|
||||
padding: 6px 0;
|
||||
margin-left: 15px;
|
||||
color: rgba(var(--sidebar-text-rgb), 0.72);
|
||||
line-height: 20px;
|
||||
list-style: none;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
align-self: flex-end;
|
||||
margin-top: -2px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&--untouched {
|
||||
color: var(--sidebar-unread-text);
|
||||
font-weight: $font-weight--semibold;
|
||||
|
||||
i::before {
|
||||
font-weight: $font-weight--semibold;
|
||||
}
|
||||
}
|
||||
.AddChannelsCtaDropdown .dropdown-menu {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#introTextInvite {
|
||||
#introTextInvite,
|
||||
#addChannelsCta {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
@@ -737,6 +754,14 @@ $sidebarOpacityAnimationDuration: 0.15s;
|
||||
}
|
||||
}
|
||||
|
||||
#AddChannelCtaDropdown {
|
||||
position: fixed;
|
||||
|
||||
ul {
|
||||
min-width: 232px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.SidebarChannelNavigator_inviteUsersSticky {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
|
||||
@@ -6,3 +6,7 @@ import {GlobalState} from 'types/store';
|
||||
export function isAddChannelDropdownOpen(state: GlobalState) {
|
||||
return state.views.addChannelDropdown.isOpen;
|
||||
}
|
||||
|
||||
export function isAddChannelCtaDropdownOpen(state: GlobalState) {
|
||||
return state.views.addChannelCtaDropdown.isOpen;
|
||||
}
|
||||
|
||||
@@ -180,6 +180,10 @@ export type ViewsState = {
|
||||
isOpen: boolean;
|
||||
};
|
||||
|
||||
addChannelCtaDropdown: {
|
||||
isOpen: boolean;
|
||||
};
|
||||
|
||||
onboardingTasks: {
|
||||
isShowOnboardingTaskCompletion: boolean;
|
||||
isShowOnboardingCompleteProfileTour: boolean;
|
||||
|
||||
@@ -163,6 +163,7 @@ export const Preferences = {
|
||||
// For one off things that have a special, attention-grabbing UI until you interact with them
|
||||
export const Touched = {
|
||||
INVITE_MEMBERS: 'invite_members',
|
||||
ADD_CHANNELS_CTA: 'add_channels_cta',
|
||||
};
|
||||
|
||||
// Category for actions/interactions that will happen just once
|
||||
@@ -264,6 +265,7 @@ export const ActionTypes = keyMirror({
|
||||
|
||||
STATUS_DROPDOWN_TOGGLE: null,
|
||||
ADD_CHANNEL_DROPDOWN_TOGGLE: null,
|
||||
ADD_CHANNEL_CTA_DROPDOWN_TOGGLE: null,
|
||||
|
||||
SHOW_ONBOARDING_TASK_COMPLETION: null,
|
||||
SHOW_ONBOARDING_COMPLETE_PROFILE_TOUR: null,
|
||||
|
||||
Ссылка в новой задаче
Block a user