Room list: add new settings to enable/disable the sections (#34151)
* Add new settings to enable/disable the sections * Add `RoomList.showSections` settings to preference user settings * Hide sections ui in room list header - Hide the collapse/expand button and the *new section* entry in the menu. - Display the *start chat* button instead of the compose menu when the only action available is to create a DM * Hide sections ui in context menu of room item * Listen to show section settings in room list item vm * Listen to show sections setting in room list header vm * Put all the rooms inside the chat section when sections are disabled When the chat section is the only section, the room list is in "flat list mode". Putting all the rooms inside the chat section. The section filters (aka custom section, favourites etc) are not passed to the skip list. * Update preferences settings screenshot * Add e2e test for RoomList.showSections toggle * Hide "Chat moved" toast when a room is tagged when RoomList.showSections is disabled
This commit is contained in:
+14
@@ -142,3 +142,17 @@ export const DisplaySectionReleaseAnnouncement: Story = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const SectionsDisabled: Story = {
|
||||
args: {
|
||||
areSectionsEnabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const NoComposeMenu: Story = {
|
||||
args: {
|
||||
canCreateRoom: false,
|
||||
canCreateVideoRoom: false,
|
||||
areSectionsEnabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import React, { type JSX } from "react";
|
||||
import { IconButton, H1 } from "@vector-im/compound-web";
|
||||
import { CollapseAllIcon, ExpandAllIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { CollapseAllIcon, ExpandAllIcon, ChatIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { type ViewModel, useViewModel } from "../../core/viewmodel";
|
||||
import { Flex } from "../../core/utils/Flex";
|
||||
@@ -59,6 +59,10 @@ export interface RoomListHeaderViewSnapshot {
|
||||
* Whether message previews are enabled in the room list.
|
||||
*/
|
||||
isMessagePreviewEnabled: boolean;
|
||||
/**
|
||||
* Whether sections are enabled in the room list.
|
||||
*/
|
||||
areSectionsEnabled: boolean;
|
||||
/**
|
||||
* If "collapse", an icon to collapse all sections is shown.
|
||||
* If "expand", an icon to expand all sections is shown.
|
||||
@@ -145,7 +149,9 @@ interface RoomListHeaderViewProps {
|
||||
*/
|
||||
export function RoomListHeaderView({ vm }: Readonly<RoomListHeaderViewProps>): JSX.Element {
|
||||
const { translate: _t } = useI18n();
|
||||
const { title, displaySpaceMenu, collapseSections } = useViewModel(vm);
|
||||
const { title, displaySpaceMenu, collapseSections, areSectionsEnabled, canCreateRoom, canCreateVideoRoom } =
|
||||
useViewModel(vm);
|
||||
const canOnlyStartChat = !areSectionsEnabled && !canCreateRoom && !canCreateVideoRoom;
|
||||
|
||||
return (
|
||||
<Flex
|
||||
@@ -164,7 +170,7 @@ export function RoomListHeaderView({ vm }: Readonly<RoomListHeaderViewProps>): J
|
||||
</Flex>
|
||||
<Flex align="center" gap="var(--cpd-space-2x)">
|
||||
<OptionMenuView vm={vm} />
|
||||
{collapseSections && (
|
||||
{areSectionsEnabled && collapseSections && (
|
||||
<IconButton
|
||||
size="28px"
|
||||
style={{ padding: "4px" }}
|
||||
@@ -182,7 +188,18 @@ export function RoomListHeaderView({ vm }: Readonly<RoomListHeaderViewProps>): J
|
||||
)}
|
||||
</IconButton>
|
||||
)}
|
||||
<ComposeMenuView vm={vm} />
|
||||
{canOnlyStartChat ? (
|
||||
<IconButton
|
||||
size="28px"
|
||||
style={{ padding: "4px" }}
|
||||
onClick={(e) => vm.createChatRoom(e.nativeEvent)}
|
||||
tooltip={_t("action|start_chat")}
|
||||
>
|
||||
<ChatIcon color="var(--cpd-color-icon-secondary)" aria-hidden />
|
||||
</IconButton>
|
||||
) : (
|
||||
<ComposeMenuView vm={vm} />
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -17,4 +17,5 @@ export const defaultSnapshot: RoomListHeaderViewSnapshot = {
|
||||
activeSortOption: "recent",
|
||||
isMessagePreviewEnabled: true,
|
||||
displaySectionReleaseAnnouncement: false,
|
||||
areSectionsEnabled: true,
|
||||
};
|
||||
|
||||
+5
-2
@@ -36,7 +36,8 @@ interface ComposeMenuViewProps {
|
||||
export function ComposeMenuView({ vm }: ComposeMenuViewProps): JSX.Element {
|
||||
const { translate: _t } = useI18n();
|
||||
const [open, setOpen] = useState(false);
|
||||
const { canCreateRoom, canCreateVideoRoom, displaySectionReleaseAnnouncement } = useViewModel(vm);
|
||||
const { canCreateRoom, canCreateVideoRoom, displaySectionReleaseAnnouncement, areSectionsEnabled } =
|
||||
useViewModel(vm);
|
||||
|
||||
// 28px button with a 20px icon
|
||||
const button = (
|
||||
@@ -80,7 +81,9 @@ export function ComposeMenuView({ vm }: ComposeMenuViewProps): JSX.Element {
|
||||
hideChevron
|
||||
/>
|
||||
)}
|
||||
<MenuItem Icon={SectionIcon} label={_t("action|new_section")} onSelect={vm.createSection} hideChevron />
|
||||
{areSectionsEnabled && (
|
||||
<MenuItem Icon={SectionIcon} label={_t("action|new_section")} onSelect={vm.createSection} hideChevron />
|
||||
)}
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
+38
-34
@@ -131,41 +131,45 @@ export function MoreOptionContent({ vm }: MoreOptionContentProps): JSX.Element {
|
||||
hideChevron={true}
|
||||
/>
|
||||
)}
|
||||
<SubMenu
|
||||
trigger={
|
||||
<MenuItem
|
||||
Icon={ArrowRightIcon}
|
||||
label={_t("room_list|more_options|move_to_section")}
|
||||
onSelect={null}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{snapshot.sections.map((section) => (
|
||||
<MenuItem
|
||||
key={section.tag}
|
||||
label={section.name}
|
||||
labelProps={{ className: styles.sectionLabel }}
|
||||
onSelect={() => vm.onToggleSection(section.tag)}
|
||||
onClick={(evt) => evt.stopPropagation()}
|
||||
hideChevron={true}
|
||||
aria-checked={section.isSelected}
|
||||
{snapshot.areSectionsEnabled && (
|
||||
<>
|
||||
<SubMenu
|
||||
trigger={
|
||||
<MenuItem
|
||||
Icon={ArrowRightIcon}
|
||||
label={_t("room_list|more_options|move_to_section")}
|
||||
onSelect={null}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{section.isSelected && (
|
||||
<CheckIcon color="var(--cpd-color-icon-tertiary)" width="24px" height="24px" />
|
||||
)}
|
||||
</MenuItem>
|
||||
))}
|
||||
{hasSections && <Separator />}
|
||||
<MenuItem label={_t("action|new_section")} onSelect={vm.onCreateSection} hideChevron={true} />
|
||||
</SubMenu>
|
||||
{isInSection && (
|
||||
<MenuItem
|
||||
Icon={MinusIcon}
|
||||
label={_t("room_list|more_options|remove_from_section")}
|
||||
onSelect={vm.onRemoveFromSection}
|
||||
onClick={(evt) => evt.stopPropagation()}
|
||||
hideChevron={true}
|
||||
/>
|
||||
{snapshot.sections.map((section) => (
|
||||
<MenuItem
|
||||
key={section.tag}
|
||||
label={section.name}
|
||||
labelProps={{ className: styles.sectionLabel }}
|
||||
onSelect={() => vm.onToggleSection(section.tag)}
|
||||
onClick={(evt) => evt.stopPropagation()}
|
||||
hideChevron={true}
|
||||
aria-checked={section.isSelected}
|
||||
>
|
||||
{section.isSelected && (
|
||||
<CheckIcon color="var(--cpd-color-icon-tertiary)" width="24px" height="24px" />
|
||||
)}
|
||||
</MenuItem>
|
||||
))}
|
||||
{hasSections && <Separator />}
|
||||
<MenuItem label={_t("action|new_section")} onSelect={vm.onCreateSection} hideChevron={true} />
|
||||
</SubMenu>
|
||||
{isInSection && (
|
||||
<MenuItem
|
||||
Icon={MinusIcon}
|
||||
label={_t("room_list|more_options|remove_from_section")}
|
||||
onSelect={vm.onRemoveFromSection}
|
||||
onClick={(evt) => evt.stopPropagation()}
|
||||
hideChevron={true}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Separator />
|
||||
<MenuItem
|
||||
|
||||
+6
@@ -308,3 +308,9 @@ export const LastItem: Story = {
|
||||
isSelected: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const SectionDisabled: Story = {
|
||||
args: {
|
||||
areSectionsEnabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
+2
@@ -94,6 +94,8 @@ export interface RoomListItemViewSnapshot {
|
||||
roomNotifState: RoomNotifState;
|
||||
/** Available sections the room can be assigned to */
|
||||
sections: Section[];
|
||||
/** Whether sections are enabled in the room list */
|
||||
areSectionsEnabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
@@ -53,4 +53,5 @@ export const defaultSnapshot: RoomListItemViewSnapshot = {
|
||||
isSelected: false,
|
||||
},
|
||||
],
|
||||
areSectionsEnabled: true,
|
||||
};
|
||||
|
||||
@@ -106,6 +106,7 @@ export const createMockRoomSnapshot = (id: string, name: string, index: number):
|
||||
canMarkAsUnread: true,
|
||||
roomNotifState: RoomNotifState.AllMessages,
|
||||
sections: [],
|
||||
areSectionsEnabled: true,
|
||||
});
|
||||
|
||||
export function createMockRoomItemViewModel(roomId: string, name: string, index: number): RoomListItemViewModel {
|
||||
|
||||
Reference in New Issue
Block a user