From e65db170d9deaa09899cc1bd07cf9ce2120611f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 12 May 2022 20:48:50 +0300 Subject: [PATCH] RED-3765: Google charts --- .../combo-chart/combo-chart.component.html | 111 ----- .../combo-chart/combo-chart.component.scss | 89 ---- .../combo-chart/combo-chart.component.ts | 405 ------------------ .../combo-series-vertical.component.ts | 199 --------- .../screens/license/combo-chart/index.ts | 2 - .../screens/license/combo-chart/models.ts | 11 - .../google-chart/google-chart.component.html | 8 + .../google-chart/google-chart.component.scss | 0 .../google-chart/google-chart.component.ts | 36 ++ .../screens/license/google-chart/models.ts | 1 + .../license-chart.component.html | 19 +- .../license-chart/license-chart.component.ts | 82 +--- .../license-screen.component.scss | 2 +- .../license-screen.component.ts | 2 +- .../admin/screens/license/license.module.ts | 21 +- .../admin/screens/license/utils/constants.ts | 16 - .../admin/screens/license/utils/license.ts | 4 +- apps/red-ui/src/assets/config/config.json | 4 +- package.json | 2 +- yarn.lock | 170 +------- 20 files changed, 101 insertions(+), 1083 deletions(-) delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.html delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.scss delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.ts delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-series-vertical.component.ts delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/index.ts delete mode 100644 apps/red-ui/src/app/modules/admin/screens/license/combo-chart/models.ts create mode 100644 apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.html create mode 100644 apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.scss create mode 100644 apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.ts create mode 100644 apps/red-ui/src/app/modules/admin/screens/license/google-chart/models.ts diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.html b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.html deleted file mode 100644 index 667d9a3b8..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.scss b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.scss deleted file mode 100644 index 7ee754487..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.scss +++ /dev/null @@ -1,89 +0,0 @@ -.ngx-charts { - float: left; - overflow: visible; - - .circle, - .bar, - .arc { - cursor: pointer; - } - - .bar, - .cell, - .arc, - .card { - &.active, - &:hover { - opacity: 0.8; - transition: opacity 100ms ease-in-out; - } - - &:focus { - outline: none; - } - - &.hidden { - display: none; - } - } - - g { - &:focus { - outline: none; - } - } - - .line-series, - .line-series-range, - .area-series { - &.inactive { - transition: opacity 100ms ease-in-out; - opacity: 0.2; - } - } - - .line-highlight { - display: none; - - &.active { - display: block; - } - } - - .area { - opacity: 0.6; - } - - .circle { - &:hover { - cursor: pointer; - } - } - - .label { - font-size: 12px; - font-weight: normal; - } - - .tooltip-anchor { - fill: rgb(0, 0, 0); - } - - .gridline-path { - stroke: #ddd; - stroke-width: 1; - fill: none; - } - - .grid-panel { - rect { - fill: none; - } - - &.odd { - rect { - fill: rgba(0, 0, 0, 0.05); - } - } - } -} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.ts deleted file mode 100644 index 0f949194c..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-chart.component.ts +++ /dev/null @@ -1,405 +0,0 @@ -import { - Component, - ContentChild, - EventEmitter, - HostListener, - Input, - Output, - TemplateRef, - ViewChild, - ViewEncapsulation, -} from '@angular/core'; - -import { curveLinear } from 'd3-shape'; -import { scaleBand, scaleLinear, scalePoint, scaleTime } from 'd3-scale'; -import { - BaseChartComponent, - calculateViewDimensions, - Color, - ColorHelper, - LegendPosition, - LineSeriesComponent, - Orientation, - ScaleType, - ViewDimensions, -} from '@swimlane/ngx-charts'; -import { ILineChartSeries } from './models'; - -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'combo-chart-component', - templateUrl: './combo-chart.component.html', - styleUrls: ['./combo-chart.component.scss'], - encapsulation: ViewEncapsulation.None, -}) -export class ComboChartComponent extends BaseChartComponent { - @Input() curve: any = curveLinear; - @Input() legend = false; - @Input() legendTitle = 'Legend'; - @Input() legendPosition: LegendPosition = LegendPosition.Right; - @Input() xAxis; - @Input() yAxis; - @Input() showXAxisLabel; - @Input() showYAxisLabel; - @Input() showRightYAxisLabel; - @Input() xAxisLabel; - @Input() yAxisLabel; - @Input() yAxisLabelRight; - @Input() tooltipDisabled = false; - @Input() gradient: boolean; - @Input() showGridLines = true; - @Input() activeEntries: any[] = []; - @Input() schemeType: ScaleType; - @Input() xAxisTickFormatting: any; - @Input() yAxisTickFormatting: any; - @Input() yRightAxisTickFormatting: any; - @Input() roundDomains = false; - @Input() colorSchemeLine: Color; - @Input() autoScale; - @Input() lineChart: ILineChartSeries[]; - @Input() yLeftAxisScaleFactor: any; - @Input() yRightAxisScaleFactor: any; - @Input() rangeFillOpacity: number; - @Input() animations = true; - @Input() noBarWhenZero = true; - - @Output() activate = new EventEmitter<{ value; entries: unknown[] }>(); - @Output() deactivate = new EventEmitter<{ value; entries: unknown[] }>(); - - @ContentChild('tooltipTemplate') tooltipTemplate: TemplateRef; - @ContentChild('seriesTooltipTemplate') seriesTooltipTemplate: TemplateRef; - - @ViewChild(LineSeriesComponent) lineSeriesComponent: LineSeriesComponent; - - dims: ViewDimensions; - xScale: any; - yScale: any; - xDomain: string[] | number[]; - yDomain: string[] | number[]; - transform: string; - colors: ColorHelper; - colorsLine: ColorHelper; - margin: any[] = [10, 20, 10, 20]; - xAxisHeight = 0; - yAxisWidth = 0; - legendOptions: any; - scaleType: ScaleType = ScaleType.Linear; - xScaleLine; - yScaleLine; - xDomainLine; - yDomainLine; - seriesDomain; - scaledAxis; - combinedSeries: ILineChartSeries[]; - xSet; - filteredDomain; - hoveredVertical; - yOrientLeft: Orientation = Orientation.Left; - yOrientRight: Orientation = Orientation.Right; - legendSpacing = 0; - bandwidth: number; - barPadding = 8; - - trackBy(index, item): string { - return item.name; - } - - update(): void { - super.update(); - this.dims = calculateViewDimensions({ - width: this.width, - height: this.height, - margins: this.margin, - showXAxis: this.xAxis, - showYAxis: this.yAxis, - xAxisHeight: this.xAxisHeight, - yAxisWidth: this.yAxisWidth, - showXLabel: this.showXAxisLabel, - showYLabel: this.showYAxisLabel, - showLegend: this.legend, - legendType: this.schemeType, - legendPosition: this.legendPosition, - }); - - if (!this.yAxis) { - this.legendSpacing = 0; - } else if (this.showYAxisLabel && this.yAxis) { - this.legendSpacing = 100; - } else { - this.legendSpacing = 40; - } - this.xScale = this.getXScale(); - this.yScale = this.getYScale(); - - // line chart - this.xDomainLine = this.getXDomainLine(); - if (this.filteredDomain) { - this.xDomainLine = this.filteredDomain; - } - - this.yDomainLine = this.getYDomainLine(); - this.seriesDomain = this.getSeriesDomain(); - - this.scaleLines(); - - this.setColors(); - this.legendOptions = this.getLegendOptions(); - - this.transform = `translate(${this.dims.xOffset} , ${this.margin[0]})`; - } - - deactivateAll() { - this.activeEntries = [...this.activeEntries]; - for (const entry of this.activeEntries) { - this.deactivate.emit({ value: entry, entries: [] }); - } - this.activeEntries = []; - } - - @HostListener('mouseleave') - hideCircles(): void { - this.hoveredVertical = null; - this.deactivateAll(); - } - - updateHoveredVertical(item): void { - this.hoveredVertical = item.value; - this.deactivateAll(); - } - - updateDomain(domain): void { - this.filteredDomain = domain; - this.xDomainLine = this.filteredDomain; - this.xScaleLine = this.getXScaleLine(this.xDomainLine, this.dims.width); - } - - scaleLines() { - this.xScaleLine = this.getXScaleLine(this.xDomainLine, this.dims.width); - this.yScaleLine = this.getYScaleLine(this.yDomainLine, this.dims.height); - } - - getSeriesDomain(): any[] { - this.combinedSeries = this.lineChart.slice(0); - this.combinedSeries.push({ - name: this.yAxisLabel, - series: this.results, - }); - return this.combinedSeries.map(d => d.name); - } - - isDate(value): value is Date { - return value instanceof Date; - } - - getScaleType(values): ScaleType { - let date = true; - let num = true; - - for (const value of values) { - if (!this.isDate(value)) { - date = false; - } - - if (typeof value !== 'number') { - num = false; - } - } - - if (date) { - return ScaleType.Time; - } - if (num) { - return ScaleType.Linear; - } - return ScaleType.Ordinal; - } - - getXDomainLine(): any[] { - let values: number[] = []; - - for (const results of this.lineChart) { - for (const d of results.series) { - if (!values.includes(d.name)) { - values.push(d.name); - } - } - } - - this.scaleType = this.getScaleType(values); - let domain = []; - - if (this.scaleType === 'time') { - const min = Math.min(...values); - const max = Math.max(...values); - domain = [min, max]; - } else if (this.scaleType === 'linear') { - values = values.map(v => Number(v)); - const min = Math.min(...values); - const max = Math.max(...values); - domain = [min, max]; - } else { - domain = values; - } - - this.xSet = values; - return domain; - } - - getYDomainLine(): any[] { - const domain: number[] = []; - - for (const results of this.lineChart) { - for (const d of results.series) { - if (domain.indexOf(d.value) < 0) { - domain.push(d.value); - } - if (d.min !== undefined) { - if (domain.indexOf(d.min) < 0) { - domain.push(d.min); - } - } - if (d.max !== undefined) { - if (domain.indexOf(d.max) < 0) { - domain.push(d.max); - } - } - } - } - - let min = Math.min(...domain); - const max = Math.max(...domain); - if (this.yRightAxisScaleFactor) { - const minMax = this.yRightAxisScaleFactor(min, max); - return [Math.min(0, minMax.min as number), minMax.max]; - } else { - min = Math.min(0, min); - return [min, max]; - } - } - - getXScaleLine(domain, width: number): any { - let scale; - if (this.bandwidth === undefined) { - this.bandwidth = width - this.barPadding; - } - const offset = Math.floor((width + this.barPadding - (this.bandwidth + this.barPadding) * domain.length) / 2); - - if (this.scaleType === 'time') { - scale = scaleTime().range([0, width]).domain(domain); - } else if (this.scaleType === 'linear') { - scale = scaleLinear().range([0, width]).domain(domain); - - if (this.roundDomains) { - scale = scale.nice(); - } - } else if (this.scaleType === 'ordinal') { - scale = scalePoint() - .range([offset + this.bandwidth / 2, width - offset - this.bandwidth / 2]) - .domain(domain); - } - - return scale; - } - - getYScaleLine(domain, height): any { - const scale = scaleLinear().range([height, 0]).domain(domain); - - return this.roundDomains ? scale.nice() : scale; - } - - getXScale(): any { - this.xDomain = this.getXDomain(); - const spacing = this.xDomain.length / (this.dims.width / this.barPadding + 1); - return scaleBand().range([0, this.dims.width]).paddingInner(spacing).domain(this.xDomain); - } - - getYScale(): any { - this.yDomain = this.getYDomain(); - const scale = scaleLinear().range([this.dims.height, 0]).domain(this.yDomain); - return this.roundDomains ? scale.nice() : scale; - } - - getXDomain(): any[] { - return this.results.map(d => d.name); - } - - getYDomain() { - const values: number[] = this.results.map(d => d.value); - const min = Math.min(0, ...values); - const max = Math.max(...values); - if (this.yLeftAxisScaleFactor) { - const minMax = this.yLeftAxisScaleFactor(min, max); - return [Math.min(0, minMax.min as number), minMax.max]; - } else { - return [min, max]; - } - } - - onClick(data) { - this.select.emit(data); - } - - setColors(): void { - let domain: number[] | string[]; - if (this.schemeType === 'ordinal') { - domain = this.xDomain; - } else { - domain = this.yDomain; - } - this.colors = new ColorHelper(this.scheme, this.schemeType, domain, this.customColors); - this.colorsLine = new ColorHelper(this.colorSchemeLine, this.schemeType, domain, this.customColors); - } - - getLegendOptions() { - const opts = { - scaleType: this.schemeType, - colors: undefined, - domain: [], - title: undefined, - position: this.legendPosition, - }; - if (opts.scaleType === 'ordinal') { - opts.domain = this.seriesDomain; - opts.colors = this.colorsLine; - opts.title = this.legendTitle; - } else { - opts.domain = this.seriesDomain; - opts.colors = this.colors.scale; - } - return opts; - } - - updateLineWidth(width): void { - this.bandwidth = width; - this.scaleLines(); - } - - updateYAxisWidth({ width }: { width: number }): void { - this.yAxisWidth = width + 20; - this.update(); - } - - updateXAxisHeight({ height }): void { - this.xAxisHeight = height; - this.update(); - } - - onActivate(item) { - const idx = this.activeEntries.findIndex(d => d.name === item.name && d.value === item.value && d.series === item.series); - if (idx > -1) { - return; - } - - this.activeEntries = [item, ...this.activeEntries]; - this.activate.emit({ value: item, entries: this.activeEntries }); - } - - onDeactivate(item) { - const idx = this.activeEntries.findIndex(d => d.name === item.name && d.value === item.value && d.series === item.series); - - this.activeEntries.splice(idx, 1); - this.activeEntries = [...this.activeEntries]; - - this.deactivate.emit({ value: item, entries: this.activeEntries }); - } -} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-series-vertical.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-series-vertical.component.ts deleted file mode 100644 index 483125c2a..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/combo-series-vertical.component.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; -import { animate, style, transition, trigger } from '@angular/animations'; -import { Bar, BarOrientation, formatLabel, PlacementTypes, StyleTypes } from '@swimlane/ngx-charts'; - -@Component({ - // eslint-disable-next-line @angular-eslint/component-selector - selector: 'g[ngx-combo-charts-series-vertical]', - template: ` - - `, - changeDetection: ChangeDetectionStrategy.OnPush, - animations: [ - trigger('animationState', [ - transition('* => void', [ - style({ - opacity: 1, - transform: '*', - }), - animate(500, style({ opacity: 0, transform: 'scale(0)' })), - ]), - ]), - ], -}) -export class ComboSeriesVerticalComponent implements OnChanges { - @Input() dims; - @Input() type = 'standard'; - @Input() series; - @Input() seriesLine; - @Input() xScale; - @Input() yScale; - @Input() colors; - @Input() tooltipDisabled = false; - @Input() gradient: boolean; - @Input() activeEntries: any[]; - @Input() seriesName: string; - @Input() animations = true; - @Input() noBarWhenZero = true; - - @Output() activate = new EventEmitter(); - @Output() deactivate = new EventEmitter(); - @Output() bandwidth = new EventEmitter(); - - bars: any; - x: any; - y: any; - readonly tooltipTypes = StyleTypes; - readonly tooltipPlacements = PlacementTypes; - readonly orientations = BarOrientation; - - ngOnChanges(): void { - this.update(); - } - - update(): void { - let width; - if (this.series.length) { - width = this.xScale.bandwidth(); - this.bandwidth.emit(width); - } - - let d0 = 0; - let total; - if (this.type === 'normalized') { - total = this.series.map(d => d.value).reduce((sum: number, d: number) => sum + d, 0); - } - - this.bars = this.series.map((d, index) => { - let value: number = d.value; - const label = d.name; - const formattedLabel = formatLabel(label); - const roundEdges = this.type === 'standard'; - - const bar: Bar = { - value, - label, - roundEdges, - data: d, - width, - formattedLabel, - height: 0, - x: 0, - y: 0, - ariaLabel: label, - tooltipText: label, - color: undefined, - gradientStops: undefined, - }; - - let offset0 = d0; - let offset1 = offset0 + value; - - if (this.type === 'standard') { - bar.height = Math.abs(this.yScale(value) - this.yScale(0)); - bar.x = this.xScale(label); - - if (value < 0) { - bar.y = this.yScale(0); - } else { - bar.y = this.yScale(value); - } - } else if (this.type === 'stacked') { - d0 += value; - - bar.height = this.yScale(offset0) - this.yScale(offset1); - bar.x = 0; - bar.y = this.yScale(offset1); - // bar.offset0 = offset0; - // bar.offset1 = offset1; - } else if (this.type === 'normalized') { - d0 += value; - - if (total > 0) { - offset0 = (offset0 * 100) / total; - offset1 = (offset1 * 100) / total; - } else { - offset0 = 0; - offset1 = 0; - } - - bar.height = this.yScale(offset0) - this.yScale(offset1); - bar.x = 0; - bar.y = this.yScale(offset1); - // bar.offset0 = offset0; - // bar.offset1 = offset1; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - value = (offset1 - offset0).toFixed(2) + '%'; - } - - if (this.colors.scaleType === 'ordinal') { - bar.color = this.colors.getColor(label); - } else { - if (this.type === 'standard') { - bar.color = this.colors.getColor(value); - bar.gradientStops = this.colors.getLinearGradientStops(value); - } else { - bar.color = this.colors.getColor(offset1); - bar.gradientStops = this.colors.getLinearGradientStops(offset1, offset0); - } - } - - let tooltipLabel = formattedLabel; - if (this.seriesName) { - tooltipLabel = `${this.seriesName} • ${formattedLabel}`; - } - - this.getSeriesTooltips(this.seriesLine, index); - const lineValue = this.seriesLine[0].series[index].value; - bar.tooltipText = ` - ${tooltipLabel} - - Y1 - ${value.toLocaleString()} • Y2 - ${lineValue.toLocaleString()}% - - `; - - return bar; - }); - } - - getSeriesTooltips(seriesLine, index) { - return seriesLine.map(d => d.series[index]); - } - - isActive(entry): boolean { - if (!this.activeEntries) { - return false; - } - const item = this.activeEntries.find(d => entry.name === d.name && entry.series === d.series); - return item !== undefined; - } - - trackBy(index, bar): string { - return bar.label; - } -} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/index.ts b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/index.ts deleted file mode 100644 index 2a0ab4f22..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './combo-chart.component'; -export * from './combo-series-vertical.component'; diff --git a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/models.ts b/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/models.ts deleted file mode 100644 index 7358f8e55..000000000 --- a/apps/red-ui/src/app/modules/admin/screens/license/combo-chart/models.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface ISeries { - name: number; - value: number; - min: number; - max: number; -} - -export interface ILineChartSeries { - name: string; - series: ISeries[]; -} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.html b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.html new file mode 100644 index 000000000..b21969ad9 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.html @@ -0,0 +1,8 @@ + diff --git a/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.scss b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.ts new file mode 100644 index 000000000..43aaad22d --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/google-chart.component.ts @@ -0,0 +1,36 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ChartType } from 'angular-google-charts'; +import { TranslateService } from '@ngx-translate/core'; +import { GoogleChartData } from './models'; + +@Component({ + selector: 'redaction-google-chart', + templateUrl: './google-chart.component.html', + styleUrls: ['./google-chart.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class GoogleChartComponent { + @Input() data: GoogleChartData; + + readonly options = { + fontName: 'Inter', + fontSize: 13, + vAxis: { + title: this._translateService.instant('license-info-screen.chart.pages-per-month'), + }, + seriesType: 'bars', + vAxes: { + 1: { + title: this._translateService.instant('license-info-screen.chart.total-pages'), + }, + }, + series: { 1: { type: 'line', targetAxisIndex: 1 }, 2: { type: 'line', targetAxisIndex: 1 } }, + colors: ['#0389ec', '#dd4d50', '#5ce594'], + legend: { position: 'top' }, + }; + readonly type = ChartType.ComboChart; + readonly width = 1000; + readonly height = 300; + + constructor(private readonly _translateService: TranslateService) {} +} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/google-chart/models.ts b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/models.ts new file mode 100644 index 000000000..f0bd08dfb --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/screens/license/google-chart/models.ts @@ -0,0 +1 @@ +export type GoogleChartData = [string, number, number, number][]; diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.html b/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.html index 8da1b9488..495e9e2c0 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.html @@ -1,18 +1 @@ - + diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.ts index 107353d82..4729044e3 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/license-chart/license-chart.component.ts @@ -1,15 +1,14 @@ -import { Component } from '@angular/core'; -import { ComboBarScheme, LICENSE_STORAGE_KEY, LineChartScheme } from '../utils/constants'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { LICENSE_STORAGE_KEY } from '../utils/constants'; import dayjs from 'dayjs'; -import { TranslateService } from '@ngx-translate/core'; import { ILicenseReport } from '@red/domain'; import { LicenseService } from '../services/license.service'; import { IDateRange } from '../utils/date-range'; import { ILicense } from '../utils/license'; import { switchMap, tap } from 'rxjs/operators'; -import { ILineChartSeries } from '../combo-chart/models'; import { LoadingService } from '@iqser/common-ui'; import { generateDateRanges, isCurrentMonth, toDate } from '../utils/functions'; +import { GoogleChartData } from '../google-chart/models'; const monthNames = dayjs.monthsShort(); @@ -17,76 +16,38 @@ const monthNames = dayjs.monthsShort(); selector: 'redaction-license-chart', templateUrl: './license-chart.component.html', styleUrls: ['./license-chart.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class LicenseChartComponent { - readonly lineChartScheme = LineChartScheme; - readonly comboBarScheme = ComboBarScheme; + readonly chartData$ = this.#chartData$; - lineChartSeries$ = this.#licenseChartSeries$; - barChart: any[]; + constructor(private readonly _licenseService: LicenseService, private readonly _loadingService: LoadingService) {} - constructor( - private readonly _translateService: TranslateService, - private readonly _licenseService: LicenseService, - private readonly _loadingService: LoadingService, - ) {} - - get #licenseChartSeries$() { + get #chartData$() { return this._licenseService.selectedLicense$.pipe( tap(() => this._loadingService.start()), - switchMap(license => this.#setMonthlyStats(license)), + switchMap(license => this.#chartData(license)), tap(() => this._loadingService.stop()), ); } - async #setMonthlyStats(licence: ILicense): Promise { - const startDate = dayjs(licence.validFrom); - const endDate = dayjs(licence.validUntil); + async #chartData(license: ILicense): Promise { + const startDate = dayjs(license.validFrom); + const endDate = dayjs(license.validUntil); const startMonth: number = startDate.month(); const startYear: number = startDate.year(); - const dateRanges = generateDateRanges(startMonth, startYear, endDate.month(), endDate.year()); + const dateRanges = generateDateRanges(startMonth, startYear, endDate.month() as number, endDate.year() as number); const reports = await this.#getReports(dateRanges); - return [ - { - name: this._translateService.instant('license-info-screen.chart.licensed-total'), - series: this.#totalLicensedPagesSeries(dateRanges), - }, - { - name: this._translateService.instant('license-info-screen.chart.cumulative'), - series: this.#setBarChartAndGetCumulativePageSeries(startMonth, startYear, reports), - }, - ]; - } - - #setBarChartAndGetCumulativePageSeries(month: number, year: number, reports: ILicenseReport[]) { let cumulativePages = 0; - const cumulativePagesSeries = []; - this.barChart = []; - for (const report of reports) { - cumulativePages += report.numberOfAnalyzedPages; - - const name = `${monthNames[month]} ${year}`; - this.barChart.push({ - name, - value: report.numberOfAnalyzedPages, - }); - - cumulativePagesSeries.push({ - name, - value: cumulativePages, - }); - - month++; - if (month === 12) { - month = 0; - year++; - } - } - - return cumulativePagesSeries; + return dateRanges.map((range, index) => [ + `${monthNames[range.startMonth]} ${range.startYear}`, + reports[index].numberOfAnalyzedPages, + this._licenseService.totalLicensedNumberOfPages, + (cumulativePages += reports[index].numberOfAnalyzedPages), + ]); } #getReports(dateRanges: IDateRange[]) { @@ -117,11 +78,4 @@ export class LicenseChartComponent { return report; } - - #totalLicensedPagesSeries(dateRanges: IDateRange[]) { - return dateRanges.map(dateRange => ({ - name: `${monthNames[dateRange.startMonth]} ${dateRange.startYear}`, - value: this._licenseService.totalLicensedNumberOfPages, - })); - } } diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.scss b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.scss index 04fde6620..5302874b3 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.scss +++ b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.scss @@ -40,7 +40,7 @@ } } - combo-chart-component { + redaction-license-chart { margin-bottom: 50px; } } diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts index 9790b0406..262cd147b 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/license-screen/license-screen.component.ts @@ -9,7 +9,7 @@ import { LicenseService } from '../services/license.service'; import { ILicenseReport } from '@red/domain'; import dayjs from 'dayjs'; import { ILicense } from '../utils/license'; -import { UserPreferenceService } from '../../../../../services/user-preference.service'; +import { UserPreferenceService } from '@services/user-preference.service'; @Component({ templateUrl: './license-screen.component.html', diff --git a/apps/red-ui/src/app/modules/admin/screens/license/license.module.ts b/apps/red-ui/src/app/modules/admin/screens/license/license.module.ts index dbe83e1b0..8960051f5 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/license.module.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/license.module.ts @@ -7,9 +7,10 @@ import { RouterModule, Routes } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { MatSelectModule } from '@angular/material/select'; import { IqserListingModule } from '@iqser/common-ui'; -import { NgxChartsModule } from '@swimlane/ngx-charts'; -import { ComboChartComponent, ComboSeriesVerticalComponent } from './combo-chart'; import { FormsModule } from '@angular/forms'; +import { GoogleChartComponent } from './google-chart/google-chart.component'; +import { GoogleChartsModule } from 'angular-google-charts'; +import { CommonModule } from '@angular/common'; const routes: Routes = [ { @@ -19,14 +20,16 @@ const routes: Routes = [ ]; @NgModule({ - declarations: [ - LicenseScreenComponent, - LicenseSelectComponent, - LicenseChartComponent, - ComboChartComponent, - ComboSeriesVerticalComponent, + declarations: [LicenseScreenComponent, LicenseSelectComponent, LicenseChartComponent, GoogleChartComponent], + imports: [ + CommonModule, + RouterModule.forChild(routes), + TranslateModule, + MatSelectModule, + FormsModule, + IqserListingModule, + GoogleChartsModule, ], - imports: [RouterModule.forChild(routes), TranslateModule, MatSelectModule, FormsModule, NgxChartsModule, IqserListingModule], providers: [LicenseService], }) export class LicenseModule {} diff --git a/apps/red-ui/src/app/modules/admin/screens/license/utils/constants.ts b/apps/red-ui/src/app/modules/admin/screens/license/utils/constants.ts index a139c9732..aaffc8d71 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/utils/constants.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/utils/constants.ts @@ -1,17 +1 @@ -import { Color, ScaleType } from '@swimlane/ngx-charts'; - -export const ComboBarScheme: Color = { - name: 'Combo bar scheme', - selectable: true, - group: ScaleType.Ordinal, - domain: ['#0389ec'], -}; - -export const LineChartScheme: Color = { - name: 'Line chart scheme', - selectable: true, - group: ScaleType.Ordinal, - domain: ['#dd4d50', '#5ce594', '#0389ec'], -}; - export const LICENSE_STORAGE_KEY = 'redaction-license-reports'; diff --git a/apps/red-ui/src/app/modules/admin/screens/license/utils/license.ts b/apps/red-ui/src/app/modules/admin/screens/license/utils/license.ts index 63cf5b4bf..5d525ee42 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/utils/license.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/utils/license.ts @@ -25,7 +25,7 @@ export const LICENSE_DATA: ILicenses = { licenses: [ { id: 'guid-1', - name: '1 Year comulative (2022)', + name: '1 Year cumulative (2022)', product: 'RedactManager', licensedTo: 'Customer company name 1', licensedToEmail: 'customer@example.com', @@ -46,7 +46,7 @@ export const LICENSE_DATA: ILicenses = { }, { id: 'guid-2', - name: '2 Year comulative (2021)', + name: '2 Year cumulative (2021)', product: 'RedactManager', licensedTo: 'Customer company name 2', licensedToEmail: 'customer@example.com', diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index d8966dc0b..640de2ce2 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -11,8 +11,8 @@ "LICENSE_CUSTOMER": "Development License", "LICENSE_EMAIL": "todo-license@email.com", "LICENSE_END": "31-12-2022", - "LICENSE_PAGE_COUNT": 1000, - "LICENSE_START": "01-01-2021", + "LICENSE_PAGE_COUNT": 10000, + "LICENSE_START": "01-01-2022", "MAX_FILE_SIZE_MB": 100, "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", diff --git a/package.json b/package.json index 998a4cdc9..ab1ba1d10 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "@ngx-translate/http-loader": "^7.0.0", "@nrwl/angular": "13.9.5", "@pdftron/webviewer": "8.3.3", - "@swimlane/ngx-charts": "^20.0.1", "@tabuckner/material-dayjs-adapter": "2.0.0", + "angular-google-charts": "^2.2.2", "dayjs": "^1.11.0", "file-saver": "^2.0.5", "jwt-decode": "^3.1.2", diff --git a/yarn.lock b/yarn.lock index 25b914395..f8b12fb0f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2150,25 +2150,6 @@ "@swc/core-win32-ia32-msvc" "1.2.155" "@swc/core-win32-x64-msvc" "1.2.155" -"@swimlane/ngx-charts@^20.0.1": - version "20.1.0" - resolved "https://registry.yarnpkg.com/@swimlane/ngx-charts/-/ngx-charts-20.1.0.tgz#c1377adacc835fa35ed0c6cb32a8ec5b43ccfd69" - integrity sha512-PY/X+eW+ZEvF3N1kuUVV5H3NHoFXlIWOvNnCKAs874yye//ttgfL/Qf9haHQpki5WIHQtpwn8xM1ylVEQT98bg== - dependencies: - "@types/d3-shape" "^2.0.0" - d3-array "^2.9.1" - d3-brush "^2.1.0" - d3-color "^2.0.0" - d3-format "^2.0.0" - d3-hierarchy "^2.0.0" - d3-interpolate "^2.0.1" - d3-scale "^3.2.3" - d3-selection "^2.0.0" - d3-shape "^2.0.0" - d3-time-format "^3.0.0" - d3-transition "^2.0.0" - tslib "^2.0.0" - "@tabuckner/material-dayjs-adapter@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@tabuckner/material-dayjs-adapter/-/material-dayjs-adapter-2.0.0.tgz#e79207232363fca391820c7992f7ed97576d7199" @@ -2267,18 +2248,6 @@ dependencies: "@types/node" "*" -"@types/d3-path@^2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-2.0.2.tgz#6052f38f6186319769dfabab61b5514b0e02c75c" - integrity sha512-3YHpvDw9LzONaJzejXLOwZ3LqwwkoXb9LI2YN7Hbd6pkGo5nIlJ09ul4bQhBN4hQZJKmUpX8HkVqbzgUKY48cg== - -"@types/d3-shape@^2.0.0": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3" - integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ== - dependencies: - "@types/d3-path" "^2" - "@types/eslint-scope@^3.7.3": version "3.7.3" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" @@ -2324,6 +2293,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/google.visualization@0.0.58": + version "0.0.58" + resolved "https://registry.yarnpkg.com/@types/google.visualization/-/google.visualization-0.0.58.tgz#eb2aa3cf05d63a9b42ff5cfcab1fc0594fb45a0e" + integrity sha512-ldwrhRvqSlrCYjHELGZNNMP8m5oPLBb6iU7CfKF2C/YpgRTlHihqsrL5M293u0GL7mKfjm0AjSIgEE2LU8fuTw== + "@types/graceful-fs@^4.1.2": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" @@ -2905,6 +2879,14 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" +angular-google-charts@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/angular-google-charts/-/angular-google-charts-2.2.2.tgz#fd26a78a0c44f8bc686832116e7ced9751b46987" + integrity sha512-dbNDqhSfqxv1rMMph2xV55+nsXSREClm03bTRpq4nRjpVghC1hVwsqfeg6p/cngB7WgamQmWj5ExTwN6vBzVAg== + dependencies: + "@types/google.visualization" "0.0.58" + tslib "^2.2.0" + ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -4049,122 +4031,6 @@ cuint@^0.2.2: resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= -d3-array@2, d3-array@^2.3.0, d3-array@^2.9.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - -d3-brush@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-2.1.0.tgz#adadfbb104e8937af142e9a6e2028326f0471065" - integrity sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ== - dependencies: - d3-dispatch "1 - 2" - d3-drag "2" - d3-interpolate "1 - 2" - d3-selection "2" - d3-transition "2" - -"d3-color@1 - 2", d3-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" - integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== - -"d3-dispatch@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz#8a18e16f76dd3fcaef42163c97b926aa9b55e7cf" - integrity sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA== - -d3-drag@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-2.0.0.tgz#9eaf046ce9ed1c25c88661911c1d5a4d8eb7ea6d" - integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== - dependencies: - d3-dispatch "1 - 2" - d3-selection "2" - -"d3-ease@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-2.0.0.tgz#fd1762bfca00dae4bacea504b1d628ff290ac563" - integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ== - -"d3-format@1 - 2", d3-format@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" - integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== - -d3-hierarchy@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz#dab88a58ca3e7a1bc6cab390e89667fcc6d20218" - integrity sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw== - -"d3-interpolate@1 - 2", "d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" - integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== - dependencies: - d3-color "1 - 2" - -"d3-path@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" - integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== - -d3-scale@^3.2.3: - version "3.3.0" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" - integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== - dependencies: - d3-array "^2.3.0" - d3-format "1 - 2" - d3-interpolate "1.2.0 - 2" - d3-time "^2.1.1" - d3-time-format "2 - 3" - -d3-selection@2, d3-selection@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-2.0.0.tgz#94a11638ea2141b7565f883780dabc7ef6a61066" - integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== - -d3-shape@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" - integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== - dependencies: - d3-path "1 - 2" - -"d3-time-format@2 - 3", d3-time-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" - integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== - dependencies: - d3-time "1 - 2" - -"d3-time@1 - 2", d3-time@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" - integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== - dependencies: - d3-array "2" - -"d3-timer@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" - integrity sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA== - -d3-transition@2, d3-transition@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-2.0.0.tgz#366ef70c22ef88d1e34105f507516991a291c94c" - integrity sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog== - dependencies: - d3-color "1 - 2" - d3-dispatch "1 - 2" - d3-ease "1 - 2" - d3-interpolate "1 - 2" - d3-timer "1 - 2" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -6322,11 +6188,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -10461,6 +10322,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"