diff --git a/src/controllers/dashboard/devices/devices.html b/src/controllers/dashboard/devices/devices.html
index 63c348c900..e2504cd3e7 100644
--- a/src/controllers/dashboard/devices/devices.html
+++ b/src/controllers/dashboard/devices/devices.html
@@ -5,6 +5,7 @@
${HeaderDevices}
+
diff --git a/src/controllers/dashboard/devices/devices.js b/src/controllers/dashboard/devices/devices.js
index 1178a0f1bd..c6e7281645 100644
--- a/src/controllers/dashboard/devices/devices.js
+++ b/src/controllers/dashboard/devices/devices.js
@@ -10,10 +10,32 @@ import 'cardStyle';
/* eslint-disable indent */
+ // Local cache of loaded
+ let deviceIds = [];
+
function canDelete(deviceId) {
return deviceId !== ApiClient.deviceId();
}
+ function deleteAllDevices(page) {
+ const msg = globalize.translate('DeleteDevicesConfirmation');
+
+ require(['confirm'], async function (confirm) {
+ await confirm({
+ text: msg,
+ title: globalize.translate('HeaderDeleteDevices'),
+ confirmText: globalize.translate('ButtonDelete'),
+ primary: 'delete'
+ });
+
+ loading.show();
+ await Promise.all(
+ deviceIds.filter(canDelete).map((id) => ApiClient.deleteDevice(id))
+ );
+ loadData(page);
+ });
+ }
+
function deleteDevice(page, id) {
const msg = globalize.translate('DeleteDeviceConfirmation');
@@ -23,16 +45,10 @@ import 'cardStyle';
title: globalize.translate('HeaderDeleteDevice'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
- }).then(function () {
+ }).then(async () => {
loading.show();
- ApiClient.ajax({
- type: 'DELETE',
- url: ApiClient.getUrl('Devices', {
- Id: id
- })
- }).then(function () {
- loadData(page);
- });
+ await ApiClient.deleteDevice(id);
+ loadData(page);
});
});
}
@@ -129,6 +145,7 @@ import 'cardStyle';
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Devices')).then(function (result) {
load(page, result.Items);
+ deviceIds = result.Items.map((device) => device.Id);
loading.hide();
});
}
@@ -145,6 +162,9 @@ import 'cardStyle';
view.addEventListener('viewshow', function () {
loadData(this);
});
- }
+ view.querySelector('#deviceDeleteAll').addEventListener('click', function() {
+ deleteAllDevices(view);
+ });
+ }
/* eslint-enable indent */
diff --git a/src/strings/en-us.json b/src/strings/en-us.json
index ab547f3854..c2ad064922 100644
--- a/src/strings/en-us.json
+++ b/src/strings/en-us.json
@@ -150,6 +150,8 @@
"DefaultSubtitlesHelp": "Subtitles are loaded based on the default and forced flags in the embedded metadata. Language preferences are considered when multiple options are available.",
"DeinterlaceMethodHelp": "Select the deinterlacing method to use when software transcoding interlaced content. When hardware acceleration supporting hardware deinterlacing is enabled the hardware deinterlacer will be used instead of this setting.",
"Delete": "Delete",
+ "DeleteAll": "Delete All",
+ "DeleteDevicesConfirmation": "Are you sure you wish to delete all devices? All other sessions will be logged out. Devices will reappear the next time a user signs in.",
"DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
"DeleteImage": "Delete Image",
"DeleteImageConfirmation": "Are you sure you wish to delete this image?",
@@ -298,6 +300,7 @@
"HeaderDateIssued": "Date Issued",
"HeaderDefaultRecordingSettings": "Default Recording Settings",
"HeaderDeleteDevice": "Delete Device",
+ "HeaderDeleteDevices": "Delete All Devices",
"HeaderDeleteItem": "Delete Item",
"HeaderDeleteItems": "Delete Items",
"HeaderDeleteProvider": "Delete Provider",