diff --git a/res/css/_components.pcss b/res/css/_components.pcss
index 96e5a1a50f..6996d33cee 100644
--- a/res/css/_components.pcss
+++ b/res/css/_components.pcss
@@ -36,6 +36,7 @@
@import "./components/views/settings/devices/_DeviceTile.pcss";
@import "./components/views/settings/devices/_DeviceType.pcss";
@import "./components/views/settings/devices/_FilteredDeviceList.pcss";
+@import "./components/views/settings/devices/_FilteredDeviceListHeader.pcss";
@import "./components/views/settings/devices/_SecurityRecommendations.pcss";
@import "./components/views/settings/devices/_SelectableDeviceTile.pcss";
@import "./components/views/settings/shared/_SettingsSubsection.pcss";
diff --git a/res/css/components/views/settings/devices/_FilteredDeviceList.pcss b/res/css/components/views/settings/devices/_FilteredDeviceList.pcss
index 01c8df787e..4b23271225 100644
--- a/res/css/components/views/settings/devices/_FilteredDeviceList.pcss
+++ b/res/css/components/views/settings/devices/_FilteredDeviceList.pcss
@@ -20,26 +20,6 @@ limitations under the License.
}
}
-.mx_FilteredDeviceList_header {
- display: flex;
- flex-direction: row;
- align-items: center;
- box-sizing: border-box;
-
- width: 100%;
- height: 48px;
- padding: 0 $spacing-16;
- margin-bottom: $spacing-32;
-
- background-color: $system;
- border-radius: 8px;
- color: $secondary-content;
-}
-
-.mx_FilteredDeviceList_headerLabel {
- flex: 1 1 100%;
-}
-
.mx_FilteredDeviceList_list {
list-style-type: none;
display: grid;
diff --git a/res/css/components/views/settings/devices/_FilteredDeviceListHeader.pcss b/res/css/components/views/settings/devices/_FilteredDeviceListHeader.pcss
new file mode 100644
index 0000000000..2cdbcf356f
--- /dev/null
+++ b/res/css/components/views/settings/devices/_FilteredDeviceListHeader.pcss
@@ -0,0 +1,36 @@
+/*
+Copyright 2022 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_FilteredDeviceListHeader {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ box-sizing: border-box;
+ gap: $spacing-8;
+
+ width: 100%;
+ height: 48px;
+ padding: 0 $spacing-16;
+ margin-bottom: $spacing-32;
+
+ background-color: $system;
+ border-radius: 8px;
+ color: $secondary-content;
+}
+
+.mx_FilteredDeviceListHeader_label {
+ flex: 1 1 100%;
+}
diff --git a/src/components/views/settings/devices/FilteredDeviceList.tsx b/src/components/views/settings/devices/FilteredDeviceList.tsx
index 7affee684c..5ec0a428d0 100644
--- a/src/components/views/settings/devices/FilteredDeviceList.tsx
+++ b/src/components/views/settings/devices/FilteredDeviceList.tsx
@@ -36,6 +36,7 @@ import {
DeviceWithVerification,
} from './types';
import { DevicesState } from './useOwnDevices';
+import FilteredDeviceListHeader from './FilteredDeviceListHeader';
interface Props {
devices: DevicesDictionary;
@@ -242,10 +243,7 @@ export const FilteredDeviceList =
};
return
-
-
- { _t('Sessions') }
-
+
id='device-list-filter'
label={_t('Filter devices')}
@@ -254,7 +252,7 @@ export const FilteredDeviceList =
options={options}
selectedLabel={_t('Show')}
/>
-
+
{ !!sortedDevices.length
?
:
onFilterChange(undefined)} />
diff --git a/src/components/views/settings/devices/FilteredDeviceListHeader.tsx b/src/components/views/settings/devices/FilteredDeviceListHeader.tsx
new file mode 100644
index 0000000000..6ecee4c8d2
--- /dev/null
+++ b/src/components/views/settings/devices/FilteredDeviceListHeader.tsx
@@ -0,0 +1,42 @@
+/*
+Copyright 2022 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React, { HTMLProps } from 'react';
+
+import { _t } from '../../../../languageHandler';
+
+interface Props extends Omit, 'className'> {
+ selectedDeviceCount: number;
+ children?: React.ReactNode;
+}
+
+const FilteredDeviceListHeader: React.FC = ({
+ selectedDeviceCount,
+ children,
+ ...rest
+}) => {
+ return
+
+ { selectedDeviceCount > 0
+ ? _t('%(selectedDeviceCount)s sessions selected', { selectedDeviceCount })
+ : _t('Sessions')
+ }
+
+ { children }
+
;
+};
+
+export default FilteredDeviceListHeader;
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index b8a7361175..c1b25cb2ab 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1753,6 +1753,7 @@
"Inactive for %(inactiveAgeDays)s days or longer": "Inactive for %(inactiveAgeDays)s days or longer",
"Filter devices": "Filter devices",
"Show": "Show",
+ "%(selectedDeviceCount)s sessions selected": "%(selectedDeviceCount)s sessions selected",
"Security recommendations": "Security recommendations",
"Improve your account security by following these recommendations": "Improve your account security by following these recommendations",
"View all": "View all",
diff --git a/test/components/views/settings/devices/FilteredDeviceListHeader-test.tsx b/test/components/views/settings/devices/FilteredDeviceListHeader-test.tsx
new file mode 100644
index 0000000000..8f7ecdc924
--- /dev/null
+++ b/test/components/views/settings/devices/FilteredDeviceListHeader-test.tsx
@@ -0,0 +1,39 @@
+/*
+Copyright 2022 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import { render } from '@testing-library/react';
+import React from 'react';
+
+import FilteredDeviceListHeader from '../../../../../src/components/views/settings/devices/FilteredDeviceListHeader';
+
+describe('', () => {
+ const defaultProps = {
+ selectedDeviceCount: 0,
+ children: test
,
+ ['data-testid']: 'test123',
+ };
+ const getComponent = (props = {}) => ();
+
+ it('renders correctly when no devices are selected', () => {
+ const { container } = render(getComponent());
+ expect(container).toMatchSnapshot();
+ });
+
+ it('renders correctly when some devices are selected', () => {
+ const { getByText } = render(getComponent({ selectedDeviceCount: 2 }));
+ expect(getByText('2 sessions selected')).toBeTruthy();
+ });
+});
diff --git a/test/components/views/settings/devices/__snapshots__/FilteredDeviceListHeader-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/FilteredDeviceListHeader-test.tsx.snap
new file mode 100644
index 0000000000..f474cca811
--- /dev/null
+++ b/test/components/views/settings/devices/__snapshots__/FilteredDeviceListHeader-test.tsx.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` renders correctly when no devices are selected 1`] = `
+
+
+
+`;
diff --git a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx
index 5c1d5586aa..70bb171b12 100644
--- a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx
+++ b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx
@@ -279,7 +279,7 @@ describe('', () => {
await flushPromisesWithFakeTimers();
// unverified filter is set
- expect(container.querySelector('.mx_FilteredDeviceList_header')).toMatchSnapshot();
+ expect(container.querySelector('.mx_FilteredDeviceListHeader')).toMatchSnapshot();
});
describe('device detail expansion', () => {
diff --git a/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap
index f4f120d0a5..32af1a3fa6 100644
--- a/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap
+++ b/test/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap
@@ -17,10 +17,10 @@ exports[` Sign out Signs out of current device 1`] = `
exports[` goes to filtered list from security recommendations 1`] = `