From 3835e280c22c0e49760e3f1ce7d1e86f92254dc6 Mon Sep 17 00:00:00 2001 From: Justin Boileau Date: Thu, 8 Dec 2022 17:26:31 +0100 Subject: [PATCH] feat(@blindnet/bridge): view both pending and completed demands in the bridge --- .../src/bldn-bridge-demand-list-item.ts | 14 +- .../bridge/src/bldn-bridge-demand-list.ts | 24 +++- packages/bridge/src/bldn-bridge-requests.ts | 130 +++++++++++++++++- packages/bridge/src/bldn-bridge.ts | 4 +- .../core/src/computation/computation-api.ts | 4 +- .../core/src/models/generated-models/index.ts | 2 +- 6 files changed, 159 insertions(+), 19 deletions(-) diff --git a/packages/bridge/src/bldn-bridge-demand-list-item.ts b/packages/bridge/src/bldn-bridge-demand-list-item.ts index 981870b8..1eb6e935 100644 --- a/packages/bridge/src/bldn-bridge-demand-list-item.ts +++ b/packages/bridge/src/bldn-bridge-demand-list-item.ts @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ import { msg } from '@lit/localize'; import { css, html, LitElement, PropertyValueMap } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; @@ -8,6 +9,8 @@ import { ComputationAPI, PendingDemandDetailsPayload, PendingDemandPayload, + DataSubjectPayload, + CompletedDemandPayload, Recommendation, } from '@blindnet/core'; import { bldnStyles } from '@blindnet/core-ui'; @@ -19,9 +22,16 @@ enum DropdownUIState { Responded, } +interface DisplayedDemand { + id: string; + date: string; + action: PendingDemandPayload.action | CompletedDemandPayload.action; + data_subject?: DataSubjectPayload; +} + @customElement('bldn-bridge-demand-list-item') export class BldnBridgeDemandListItem extends LitElement { - @property({ type: Object }) demand: PendingDemandPayload | undefined; + @property({ type: Object }) demand: DisplayedDemand | undefined; @state() _demandDetails: PendingDemandDetailsPayload | undefined; @@ -144,7 +154,7 @@ export class BldnBridgeDemandListItem extends LitElement { protected willUpdate( _changedProperties: PropertyValueMap | Map ): void { - if (_changedProperties.has('demand') && this.demand) { + if (_changedProperties.has('_open') && this._open && this.demand) { ComputationAPI.getInstance() .getPendingDemandDetails(this.demand.id) .then(details => { diff --git a/packages/bridge/src/bldn-bridge-demand-list.ts b/packages/bridge/src/bldn-bridge-demand-list.ts index 36f9f411..4309ee9f 100644 --- a/packages/bridge/src/bldn-bridge-demand-list.ts +++ b/packages/bridge/src/bldn-bridge-demand-list.ts @@ -1,22 +1,32 @@ +/* eslint-disable camelcase */ import { msg } from '@lit/localize'; import { css, html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { map } from 'lit/directives/map.js'; import { when } from 'lit/directives/when.js'; -import { CompletedDemandPayload, PendingDemandPayload } from '@blindnet/core'; +import { + CompletedDemandPayload, + PendingDemandPayload, + DataSubjectPayload, +} from '@blindnet/core'; import { bldnStyles } from '@blindnet/core-ui'; import './bldn-bridge-demand-list-item.js'; +interface DisplayedDemand { + id: string; + date: string; + action: PendingDemandPayload.action | CompletedDemandPayload.action; + data_subject?: DataSubjectPayload; +} + @customElement('bldn-bridge-demand-list') export class BldnBridgeDemandList extends LitElement { - @property({ type: Array }) pendingDemands: PendingDemandPayload[] = []; - - @property({ type: Array }) completedDemands: CompletedDemandPayload[] = []; + @property({ type: Array }) demands: DisplayedDemand[] = []; render() { return html` ${when( - this.pendingDemands.length > 0, + this.demands.length > 0, () => html`
${msg('Created')} @@ -25,10 +35,10 @@ export class BldnBridgeDemandList extends LitElement {
${map( - this.pendingDemands, + this.demands, d => html` ` )} diff --git a/packages/bridge/src/bldn-bridge-requests.ts b/packages/bridge/src/bldn-bridge-requests.ts index c6327029..5e624abd 100644 --- a/packages/bridge/src/bldn-bridge-requests.ts +++ b/packages/bridge/src/bldn-bridge-requests.ts @@ -1,12 +1,26 @@ +/* eslint-disable camelcase */ import { localized, msg } from '@lit/localize'; -import { css, html, LitElement } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; -import { CompletedDemandPayload, PendingDemandPayload } from '@blindnet/core'; +import { css, html, LitElement, PropertyValueMap } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { + CompletedDemandPayload, + DataSubjectPayload, + PendingDemandPayload, +} from '@blindnet/core'; import { setLocale } from './localization.js'; import '@blindnet/core-ui'; import './bldn-bridge-demand-list.js'; +interface DisplayedDemand { + id: string; + date: string; + action: PendingDemandPayload.action | CompletedDemandPayload.action; + data_subject?: DataSubjectPayload; +} + +type DemandsFilter = 'all' | 'pending' | 'answered' | 'canceled'; + @localized() @customElement('bldn-bridge-requests') export class BldnBridgeRequests extends LitElement { @@ -14,6 +28,18 @@ export class BldnBridgeRequests extends LitElement { @property({ type: Array }) completedDemands: CompletedDemandPayload[] = []; + @state() _allDemands: DisplayedDemand[] = []; + + @state() _pendingDemands: DisplayedDemand[] = []; + + @state() _answeredDemands: DisplayedDemand[] = []; + + @state() _canceledDemands: DisplayedDemand[] = []; + + @state() _displayedDemands: DisplayedDemand[] = []; + + @state() _demandFilter: DemandsFilter = 'pending'; + constructor() { super(); @@ -26,6 +52,100 @@ export class BldnBridgeRequests extends LitElement { } } + /** + * Decide which demands to display + * @param e Event with selected demand filter + */ + handleDemandFilterClick(e: Event) { + e.stopPropagation(); + const { value } = (e as CustomEvent).detail; + this._demandFilter = value; + } + + updateDisplayedDemands() { + switch (this._demandFilter) { + case 'all': + this._displayedDemands = this._allDemands; + break; + case 'pending': + this._displayedDemands = this._pendingDemands; + break; + case 'answered': + this._displayedDemands = this._answeredDemands; + break; + case 'canceled': + this._displayedDemands = this._canceledDemands; + break; + default: + break; + } + } + + handleDemandsChange() { + // All demands includes pending and completed + this._allDemands = this.pendingDemands + .map(({ id, date, action, data_subject }) => ({ + id, + date, + action, + data_subject, + })) + .concat( + this.completedDemands.map( + ({ id, request_date, action, data_subject }) => ({ + id, + date: request_date, + action, + data_subject, + }) + ) + ); + + this._pendingDemands = this.pendingDemands.map( + ({ id, date, action, data_subject }) => ({ + id, + date, + action, + data_subject, + }) + ); + + this._answeredDemands = this.completedDemands.map( + ({ id, request_date, action, data_subject }) => ({ + id, + date: request_date, + action, + data_subject, + }) + ); + + this._canceledDemands = this.completedDemands + .filter(d => d.status === CompletedDemandPayload.status.CANCELED) + .map(({ id, request_date, action, data_subject }) => ({ + id, + date: request_date, + action, + data_subject, + })); + + this.updateDisplayedDemands(); + } + + /** + * Pre-filter each demand list so we don't do it on every switch + */ + protected willUpdate( + _changedProperties: PropertyValueMap | Map + ): void { + if ( + (_changedProperties.has('pendingDemands') && this.pendingDemands) || + (_changedProperties.has('completedDemands') && this.completedDemands) + ) + this.handleDemandsChange(); + if (_changedProperties.has('_demandFilter') && this._demandFilter) + this.updateDisplayedDemands(); + } + render() { return html` `; } diff --git a/packages/bridge/src/bldn-bridge.ts b/packages/bridge/src/bldn-bridge.ts index 9d3ca4b3..68bd7e89 100644 --- a/packages/bridge/src/bldn-bridge.ts +++ b/packages/bridge/src/bldn-bridge.ts @@ -59,12 +59,12 @@ export class BldnBridge extends CoreConfigurationMixin(LitElement) { ComputationAPI.getInstance() .getPendingDemands(this.adminToken) .then(pendingDemands => { - this._pendingDemands.push(...pendingDemands); + this._pendingDemands = pendingDemands; }); ComputationAPI.getInstance() .getCompletedDemands(this.adminToken) .then(completedDemands => { - this._completedDemands.push(...completedDemands); + this._completedDemands = completedDemands; }); } } diff --git a/packages/core/src/computation/computation-api.ts b/packages/core/src/computation/computation-api.ts index df96a7ce..0dff542d 100644 --- a/packages/core/src/computation/computation-api.ts +++ b/packages/core/src/computation/computation-api.ts @@ -369,7 +369,7 @@ export class ComputationAPI { } return fetch( - `https://devkit-pce-staging.azurewebsites.net/v0/consumer-interface/completed-requests`, + `https://devkit-pce-staging.azurewebsites.net/v0/bridge/completed-requests`, { method: 'GET', headers: { @@ -399,7 +399,7 @@ export class ComputationAPI { } return fetch( - `https://devkit-pce-staging.azurewebsites.net/v0/consumer-interface/completed-requests/${id}`, + `https://devkit-pce-staging.azurewebsites.net/v0/bridge/completed-requests/${id}`, { method: 'GET', headers: { diff --git a/packages/core/src/models/generated-models/index.ts b/packages/core/src/models/generated-models/index.ts index 3c6c1a19..9882c6f9 100644 --- a/packages/core/src/models/generated-models/index.ts +++ b/packages/core/src/models/generated-models/index.ts @@ -10,7 +10,7 @@ export type { AddRegulationsPayload } from './models/AddRegulationsPayload.js'; export type { ApproveDemandPayload } from './models/ApproveDemandPayload.js'; export type { CancelDemandPayload } from './models/CancelDemandPayload.js'; export type { ConsentRestriction } from './models/ConsentRestriction.js'; -export type { CompletedDemandPayload } from './models/CompletedDemandPayload.js'; +export { CompletedDemandPayload } from './models/CompletedDemandPayload.js'; export type { CompletedDemandInfoPayload } from './models/CompletedDemandInfoPayload.js'; export { CreateLegalBasePayload } from './models/CreateLegalBasePayload.js'; export { CreatePrivacyRequestPayload } from './models/CreatePrivacyRequestPayload.js';