diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md
index 2513af583..997443b46 100644
--- a/CHANGELOG.unreleased.md
+++ b/CHANGELOG.unreleased.md
@@ -8,6 +8,7 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [VM] Move boot order setting from Disk tab to Advanced tab [#1523](https://github.com/vatesfr/xen-orchestra/issues/1523#issuecomment-563141573) (PR [#4975](https://github.com/vatesfr/xen-orchestra/pull/4975))
+- [XOA/licenses] Display proxy licenses (PR [#4944](https://github.com/vatesfr/xen-orchestra/pull/4944))
### Bug fixes
@@ -34,4 +35,4 @@
- @xen-orchestra/fs patch
- xo-server patch
-- xo-web patch
+- xo-web minor
diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js
index c013bf63f..8690656fb 100644
--- a/packages/xo-web/src/common/intl/messages.js
+++ b/packages/xo-web/src/common/intl/messages.js
@@ -2287,7 +2287,9 @@ const messages = {
licensePurchaserYou: 'You',
productSupport: 'Support',
licenseNotBoundXosan: 'No XOSAN attached',
+ licenseNotBoundProxy: 'No proxy attached',
licenseBoundUnknownXosan: 'License attached to an unknown XOSAN',
+ licenseBoundUnknownProxy: 'License attached to an unknown proxy',
licensesManage: 'Manage the licenses',
newLicense: 'New license',
refreshLicenses: 'Refresh',
diff --git a/packages/xo-web/src/common/render-xo-item.js b/packages/xo-web/src/common/render-xo-item.js
index e499301ab..df33bc149 100644
--- a/packages/xo-web/src/common/render-xo-item.js
+++ b/packages/xo-web/src/common/render-xo-item.js
@@ -382,11 +382,20 @@ export const Proxy = decorate([
proxy: cb =>
subscribeProxies(proxies => cb(proxies.find(proxy => proxy.id === id))),
})),
- ({ id, proxy }) =>
+ ({ id, proxy, link, newTab }) =>
proxy !== undefined ? (
-
+
{proxy.name || proxy.address}
-
+
) : (
unknowItem(id, 'proxy')
),
@@ -394,6 +403,13 @@ export const Proxy = decorate([
Proxy.propTypes = {
id: PropTypes.string.isRequired,
+ link: PropTypes.bool,
+ newTab: PropTypes.bool,
+}
+
+Proxy.defaultProps = {
+ link: false,
+ newTab: false,
}
// ===================================================================
diff --git a/packages/xo-web/src/xo-app/xoa/licenses/index.js b/packages/xo-web/src/xo-app/xoa/licenses/index.js
index 3154eaeb1..68b087312 100644
--- a/packages/xo-web/src/xo-app/xoa/licenses/index.js
+++ b/packages/xo-web/src/xo-app/xoa/licenses/index.js
@@ -1,10 +1,11 @@
import _ from 'intl'
import ActionButton from 'action-button'
import Component from 'base-component'
+import decorate from 'apply-decorators'
import Icon from 'icon'
import Link from 'link'
import React from 'react'
-import renderXoItem from 'render-xo-item'
+import renderXoItem, { Proxy } from 'render-xo-item'
import SortedTable from 'sorted-table'
import { addSubscriptions, adminOnly, connectStore, ShortDate } from 'utils'
import { CURRENT, productId2Plan, getXoaPlan } from 'xoa-plans'
@@ -16,6 +17,7 @@ import {
getLicenses,
selfBindLicense,
subscribePlugins,
+ subscribeProxies,
subscribeSelfLicenses,
} from 'xo'
@@ -23,6 +25,25 @@ import Xosan from './xosan'
// -----------------------------------------------------------------------------
+const ProxyLicense = decorate([
+ addSubscriptions(({ license }) => ({
+ proxy: cb =>
+ subscribeProxies(proxies =>
+ cb(
+ license.vmId && proxies.find(({ vmUuid }) => vmUuid === license.vmId)
+ )
+ ),
+ })),
+ ({ license, proxy }) =>
+ license.vmId === undefined ? (
+ _('licenseNotBoundProxy')
+ ) : proxy !== undefined ? (
+
+ ) : (
+ _('licenseBoundUnknownProxy')
+ ),
+])
+
const LicenseManager = ({ item, userData }) => {
const { type } = item
@@ -75,6 +96,10 @@ const LicenseManager = ({ item, userData }) => {
return {_('licenseBoundToOtherXoa')}
}
+ if (type === 'proxy') {
+ return
+ }
+
console.warn('encountered unsupported license type')
return null
}
@@ -144,15 +169,23 @@ export default class Licenses extends Component {
return getLicenses()
.then(licenses => {
- const { xoa, xosan } = groupBy(licenses, license =>
- license.productTypes.includes('xo')
- ? 'xoa'
- : license.productTypes.includes('xosan')
- ? 'xosan'
- : 'other'
- )
+ const { proxy, xoa, xosan } = groupBy(licenses, license => {
+ for (const productType of license.productTypes) {
+ if (productType === 'xo') {
+ return 'xoa'
+ }
+ if (productType === 'xosan') {
+ return 'xosan'
+ }
+ if (productType === 'xoproxy') {
+ return 'proxy'
+ }
+ }
+ return 'other'
+ })
this.setState({
licenses: {
+ proxy,
xoa,
xosan,
},
@@ -207,6 +240,21 @@ export default class Licenses extends Component {
}
})
+ // --- proxy ---
+ forEach(licenses.proxy, license => {
+ // When `expires` is undefined, the license isn't expired
+ if (!(license.expires < now)) {
+ products.push({
+ buyer: license.buyer,
+ expires: license.expires,
+ id: license.id,
+ product: _('proxy'),
+ type: 'proxy',
+ vmId: license.boundObjectId,
+ })
+ }
+ })
+
return products
}
)