diff --git a/CHANGELOG.md b/CHANGELOG.md
index abd4caf78..c51417068 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,7 @@
- [Backup NG logs] Disable state filters with no entries [#3438](https://github.com/vatesfr/xen-orchestra/issues/3438) (PR [#3442](https://github.com/vatesfr/xen-orchestra/pull/3442))
- [ACLs] Global performance improvement on UI for non-admin users [#3578](https://github.com/vatesfr/xen-orchestra/issues/3578) (PR [#3584](https://github.com/vatesfr/xen-orchestra/pull/3584))
- [Backup NG] Improve the Schedule's view (Replace table by list) [#3491](https://github.com/vatesfr/xen-orchestra/issues/3491) (PR [#3586](https://github.com/vatesfr/xen-orchestra/pull/3586))
+- ([Host/Storage], [Sr/hosts]) add bulk deletion [#3179](https://github.com/vatesfr/xen-orchestra/issues/3179) (PR [#3539](https://github.com/vatesfr/xen-orchestra/pull/3539))
### Bug fixes
diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js
index 20210a481..745a574ad 100644
--- a/packages/xo-web/src/common/intl/messages.js
+++ b/packages/xo-web/src/common/intl/messages.js
@@ -1545,6 +1545,18 @@ const messages = {
destroyTasksModalTitle: 'Destroy task{nTasks, plural, one {} other {s}}',
destroyTasksModalMessage:
'Are you sure you want to destroy {nTasks, number} task{nTasks, plural, one {} other {s}}?',
+ forgetHostFromSrModalTitle: 'Forget host',
+ forgetHostFromSrModalMessage:
+ 'Are you sure you want to forget this host? This will disconnect the SR from the host by removing the link between them (PBD).',
+ forgetHostsFromSrModalTitle: 'Forget host{nPbds, plural, one {} other {s}}',
+ forgetHostsFromSrModalMessage:
+ 'Are you sure you want to forget {nPbds, number} host{nPbds, plural, one {} other {s}}? This will disconnect the SR from these hosts by removing the links between the SR and the hosts (PBDs).',
+ forgetSrFromHostModalTitle: 'Forget SR',
+ forgetSrFromHostModalMessage:
+ 'Are you sure you want to forget this SR? This will disconnect the SR from the host by removing the link between them (PBD).',
+ forgetSrsFromHostModalTitle: 'Forget SR{nPbds, plural, one {} other {s}}',
+ forgetSrsFromHostModalMessage:
+ 'Are you sure you want to forget {nPbds, number} SR{nPbds, plural, one {} other {s}}? This will disconnect the SRs from the host by removing the links between the host and the SRs (PBDs).',
// ----- Servers -----
serverLabel: 'Label',
diff --git a/packages/xo-web/src/common/xo/index.js b/packages/xo-web/src/common/xo/index.js
index d420c6b40..5143f6225 100644
--- a/packages/xo-web/src/common/xo/index.js
+++ b/packages/xo-web/src/common/xo/index.js
@@ -1683,6 +1683,8 @@ export const disconnectPbd = pbd =>
export const deletePbd = pbd => _call('pbd.delete', { id: resolveId(pbd) })
+export const deletePbds = pbds => Promise.all(map(pbds, deletePbd))
+
// Messages ----------------------------------------------------------
export const deleteMessage = message =>
diff --git a/packages/xo-web/src/xo-app/host/tab-storage.js b/packages/xo-web/src/xo-app/host/tab-storage.js
index 1281772cf..54a4adfdf 100644
--- a/packages/xo-web/src/xo-app/host/tab-storage.js
+++ b/packages/xo-web/src/xo-app/host/tab-storage.js
@@ -1,19 +1,38 @@
import _ from 'intl'
-import ActionRowButton from 'action-row-button'
-import isEmpty from 'lodash/isEmpty'
import Link from 'link'
import map from 'lodash/map'
import React from 'react'
import SortedTable from 'sorted-table'
import StateButton from 'state-button'
import Tooltip from 'tooltip'
-import { connectPbd, disconnectPbd, deletePbd, editSr, isSrShared } from 'xo'
-import { connectStore, formatSize } from 'utils'
+import { confirm } from 'modal'
+import {
+ connectPbd,
+ disconnectPbd,
+ deletePbd,
+ deletePbds,
+ editSr,
+ isSrShared,
+} from 'xo'
+import { connectStore, formatSize, noop } from 'utils'
import { Container, Row, Col } from 'grid'
import { createGetObjectsOfType, createSelector } from 'selectors'
+import { isEmpty, some } from 'lodash'
import { TabButtonLink } from 'tab-button'
import { Text } from 'editable'
+const forgetSr = ({ pbdId }) =>
+ confirm({
+ title: _('forgetSrFromHostModalTitle'),
+ body: _('forgetSrFromHostModalMessage'),
+ }).then(() => deletePbd(pbdId), noop)
+
+const forgetSrs = pbds =>
+ confirm({
+ title: _('forgetSrsFromHostModalTitle', { nPbds: pbds.length }),
+ body: _('forgetSrsFromHostModalMessage', { nPbds: pbds.length }),
+ }).then(() => deletePbds(pbds), noop)
+
const SR_COLUMNS = [
{
name: _('srName'),
@@ -83,18 +102,17 @@ const SR_COLUMNS = [
/>
),
},
+]
+
+const SR_ACTIONS = [
{
- name: _('pbdAction'),
- itemRenderer: storage =>
- !storage.attached && (
-