@ministryofjustice/hmpps-digital-prison-reporting-frontend 4.15.4 → 4.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dpr/components/_async/async-filters-form/view.njk +2 -2
- package/dpr/components/_catalogue/catalogue-list/utils.test.ts +1 -1
- package/dpr/components/_charts/chart/Buckets.js +2 -0
- package/dpr/components/_charts/chart/Buckets.js.map +7 -0
- package/dpr/components/_charts/chart/Buckets.ts +198 -0
- package/dpr/components/_charts/chart/DashboardVisualisation.js +2 -0
- package/dpr/components/_charts/chart/DashboardVisualisation.js.map +7 -0
- package/dpr/components/_charts/chart/DashboardVisualisation.ts +43 -0
- package/dpr/components/_charts/chart/heatmap/HeatmapChart.js +2 -0
- package/dpr/components/_charts/chart/heatmap/HeatmapChart.js.map +7 -0
- package/dpr/components/_charts/chart/heatmap/HeatmapChart.ts +144 -0
- package/dpr/components/_charts/utils.js +1 -1
- package/dpr/components/_charts/utils.js.map +3 -3
- package/dpr/components/_charts/utils.ts +1 -1
- package/dpr/components/_dashboards/dashboard/types.js.map +1 -1
- package/dpr/components/_dashboards/dashboard/types.ts +4 -4
- package/dpr/components/_dashboards/scorecard/Scorecard.js +2 -0
- package/dpr/components/_dashboards/scorecard/Scorecard.js.map +7 -0
- package/dpr/components/_dashboards/scorecard/Scorecard.ts +315 -0
- package/dpr/components/_dashboards/scorecard/types.js +1 -1
- package/dpr/components/_dashboards/scorecard/types.js.map +1 -1
- package/dpr/components/_dashboards/scorecard/types.ts +20 -1
- package/dpr/components/_dashboards/scorecard/utils.js +1 -1
- package/dpr/components/_dashboards/scorecard/utils.js.map +3 -3
- package/dpr/components/_dashboards/scorecard/utils.test.ts +8 -437
- package/dpr/components/_dashboards/scorecard/utils.ts +2 -265
- package/dpr/components/_dashboards/scorecard/view.njk +2 -2
- package/dpr/components/_filters/types.d.js.map +1 -1
- package/dpr/components/_filters/types.d.ts +1 -0
- package/dpr/components/_filters/utils.js +1 -1
- package/dpr/components/_filters/utils.js.map +3 -3
- package/dpr/components/_filters/utils.ts +17 -12
- package/dpr/routes/journeys/request-report/filters/tests.cy.js +1 -1
- package/dpr/routes/journeys/request-report/filters/tests.cy.js.map +3 -3
- package/dpr/routes/journeys/request-report/filters/tests.cy.ts +40 -0
- package/dpr/routes/journeys/view-report/async/dashboard/utils.js +1 -1
- package/dpr/routes/journeys/view-report/async/dashboard/utils.js.map +3 -3
- package/dpr/routes/journeys/view-report/async/dashboard/utils.ts +3 -2
- package/dpr/types/api.d.js.map +1 -1
- package/dpr/types/api.d.ts +2 -0
- package/dpr/utils/datasetHelper.js +1 -1
- package/dpr/utils/datasetHelper.js.map +2 -2
- package/dpr/utils/datasetHelper.ts +1 -1
- package/package.json +1 -1
- package/dpr/components/_charts/chart/heatmap/Heatmap.js +0 -2
- package/dpr/components/_charts/chart/heatmap/Heatmap.js.map +0 -7
- package/dpr/components/_charts/chart/heatmap/Heatmap.ts +0 -278
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/dpr/components/_dashboards/dashboard/types.ts"],
|
|
4
|
-
"sourcesContent": ["import { components } from '../../../types/api'\nimport { ChartCardData, MoJTable, UnitType } from '../../../types/Charts'\nimport { Scorecard, ScorecardGroup } from '../scorecard/types'\n\nexport interface DashboardDefinition {\n id: string\n name: string\n description?: string\n sections: DashboardSection[]\n isMissing?: boolean\n filterFields: components['schemas']['FieldDefinition'][]\n}\n\nexport interface DashboardSection {\n id: string\n display?: string\n description?: string\n visualisations: DashboardVisualisation[]\n}\n\nexport interface DashboardUISection {\n id: string\n title?: string\n description?: string\n visualisations?: DashboardUIVisualisation[]\n}\n\nexport interface DashboardUIVisualisation {\n id: string\n type: DashboardVisualisationType\n title?: string\n description?: string\n data: Scorecard | Scorecard[] | ScorecardGroup[] | ChartCardData | { table: MoJTable; ts: string }\n}\n\nexport interface DashboardVisualisation {\n id: string\n type: DashboardVisualisationType\n display?: string\n description?: string\n columns: DashboardVisualisationColumns\n options: DashboardVisualisationOptions\n}\n\nexport type DashboardVisualisationOptions = ListDashboardVisualisationOptions |
|
|
4
|
+
"sourcesContent": ["import { components } from '../../../types/api'\nimport { ChartCardData, MoJTable, UnitType } from '../../../types/Charts'\nimport { Scorecard, ScorecardGroup } from '../scorecard/types'\n\nexport interface DashboardDefinition {\n id: string\n name: string\n description?: string\n sections: DashboardSection[]\n isMissing?: boolean\n filterFields: components['schemas']['FieldDefinition'][]\n}\n\nexport interface DashboardSection {\n id: string\n display?: string\n description?: string\n visualisations: DashboardVisualisation[]\n}\n\nexport interface DashboardUISection {\n id: string\n title?: string\n description?: string\n visualisations?: DashboardUIVisualisation[]\n}\n\nexport interface DashboardUIVisualisation {\n id: string\n type: DashboardVisualisationType\n title?: string\n description?: string\n data: Scorecard | Scorecard[] | ScorecardGroup[] | ChartCardData | { table: MoJTable; ts: string }\n}\n\nexport interface DashboardVisualisation {\n id: string\n type: DashboardVisualisationType\n display?: string\n description?: string\n columns: DashboardVisualisationColumns\n options: DashboardVisualisationOptions\n}\n\nexport type DashboardVisualisationOptions = ListDashboardVisualisationOptions | BucketDashboardVisualisationOptions\n\nexport interface ListDashboardVisualisationOptions {\n showLatest?: boolean\n columnsAsList?: boolean\n}\n\nexport interface BucketDashboardVisualisationOptions {\n useRagColours?: boolean\n buckets?: DashboardVisualisationBucket[]\n baseColour?: string\n}\n\nexport interface DashboardVisualisationBucket {\n min?: number\n max?: number\n hexColour?: string\n}\n\nexport interface ListVisualisation extends DashboardVisualisation {\n type: DashboardVisualisationType.LIST\n}\n\nexport enum DashboardVisualisationType {\n LIST = 'list',\n DONUT = 'doughnut',\n BAR = 'bar',\n LINE = 'line',\n MATRIX = 'matrix',\n MATRIX_TIMESERIES = 'matrix-timeseries',\n BAR_TIMESERIES = 'bar-timeseries',\n LINE_TIMESERIES = 'line-timeseries',\n SCORECARD = 'scorecard',\n SCORECARD_GROUP = 'scorecard-group',\n}\n\nexport interface DashboardVisualisationColumns {\n keys?: DashboardVisualisationColumnKey[]\n measures: DashboardVisualisationColumnMeasure[]\n filters?: DashboardVisualisationColumnFilter[]\n expectNulls: boolean\n}\n\nexport interface DashboardVisualisationColumn {\n id: string\n display?: string\n}\n\nexport interface DashboardVisualisationColumnKey extends DashboardVisualisationColumn {\n optional?: boolean\n}\n\nexport interface DashboardVisualisationColumnMeasure extends DashboardVisualisationColumn {\n aggregate?: AggregateType\n displayValue?: boolean\n unit?: UnitType\n axis?: 'x' | 'y'\n}\n\nexport interface DashboardVisualisationColumnFilter {\n id: string\n equals: string | number\n}\n\nexport interface BarChartVisualisationColumn extends DashboardVisualisationColumnMeasure {\n axis?: 'x' | 'y'\n}\n\nexport interface ScorecardVisualisationColumn extends DashboardVisualisationColumn {\n displayValue: boolean\n}\n\nexport enum AggregateType {\n SUM = 'sum',\n AVG = 'average',\n}\n"],
|
|
5
5
|
"mappings": "4ZAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,EAAA,+BAAAC,IAAA,eAAAC,EAAAJ,GAmEO,IAAKG,OACVA,EAAA,KAAO,OACPA,EAAA,MAAQ,WACRA,EAAA,IAAM,MACNA,EAAA,KAAO,OACPA,EAAA,OAAS,SACTA,EAAA,kBAAoB,oBACpBA,EAAA,eAAiB,iBACjBA,EAAA,gBAAkB,kBAClBA,EAAA,UAAY,YACZA,EAAA,gBAAkB,kBAVRA,OAAA,IAiDAD,OACVA,EAAA,IAAM,MACNA,EAAA,IAAM,UAFIA,OAAA",
|
|
6
6
|
"names": ["types_exports", "__export", "AggregateType", "DashboardVisualisationType", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -42,20 +42,20 @@ export interface DashboardVisualisation {
|
|
|
42
42
|
options: DashboardVisualisationOptions
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export type DashboardVisualisationOptions = ListDashboardVisualisationOptions |
|
|
45
|
+
export type DashboardVisualisationOptions = ListDashboardVisualisationOptions | BucketDashboardVisualisationOptions
|
|
46
46
|
|
|
47
47
|
export interface ListDashboardVisualisationOptions {
|
|
48
48
|
showLatest?: boolean
|
|
49
49
|
columnsAsList?: boolean
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export interface
|
|
52
|
+
export interface BucketDashboardVisualisationOptions {
|
|
53
53
|
useRagColours?: boolean
|
|
54
|
-
buckets?:
|
|
54
|
+
buckets?: DashboardVisualisationBucket[]
|
|
55
55
|
baseColour?: string
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export interface
|
|
58
|
+
export interface DashboardVisualisationBucket {
|
|
59
59
|
min?: number
|
|
60
60
|
max?: number
|
|
61
61
|
hexColour?: string
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var R=Object.create;var g=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var F=(u,l)=>{for(var e in l)g(u,e,{get:l[e],enumerable:!0})},b=(u,l,e,t)=>{if(l&&typeof l=="object"||typeof l=="function")for(let s of B(l))!T.call(u,s)&&s!==e&&g(u,s,{get:()=>l[s],enumerable:!(t=k(l,s))||t.enumerable});return u};var v=(u,l,e)=>(e=u!=null?R($(u)):{},b(l||!u||!u.__esModule?g(e,"default",{value:u,enumerable:!0}):e,u)),N=u=>b(g({},"__esModule",{value:!0}),u);var I={};F(I,{ScorecardVisualisation:()=>f,default:()=>M});module.exports=N(I);var K=v(require("../../_charts/chart/DashboardVisualisation")),n=v(require("../../../utils/datasetHelper")),D=v(require("../../_charts/chart/Buckets"));class f extends K.default{constructor(e,t,s=!1){super(e,t);this.buckets=[];this.ragColours=["#cce2d8","#fff7bf","#f4cdc6"];this.initBuckets=(e,t)=>{this.bucketsHelper=new D.default(e,this.definition,t,!1,this.ragColours),this.buckets=new D.default(e,this.definition,t,!1,this.ragColours).getBuckets()};this.initGroupVars=()=>{this.groupKey=n.default.getGroupKey(this.keys,this.dataset.latest),this.groupKeyId=this.groupKey?.id,this.groupKeyDisplay=this.groupKey?.display,this.valueColumn=this.measures.find(e=>e.displayValue),this.valueColumn&&(this.valueKey=this.valueColumn?.id,this.titleColumn=this.measures.find(e=>e.display||e.display===""),this.titleKey=this.titleColumn?.id)};this.getDataset=(e,t)=>{const s=n.default.getLastestDataset(t),r=n.default.getDatasetRows(e,s),i=r[0]?.ts?.raw,o=n.default.filterRowsByDisplayColumns(e,r,!0),a=n.default.getEarliestDataset(t),c=n.default.getDatasetRows(e,a),d=c[0]?.ts?.raw;return{earliest:n.default.filterRowsByDisplayColumns(e,c,!0),earliestTs:d,latest:o,latestTs:i}};this.setRagScore=(e,t)=>this.bucketsHelper.getBucketForValue(e,t);this.createScorecardData=({title:e,value:t,rag:s,valueFor:r,valueFrom:i,prevVal:o,groupTitle:a})=>({title:e,value:t,...!Number.isNaN(t)&&this.buckets.length&&{rag:this.setRagScore(t,s)},valueFor:r,trend:this.createTrend(r,i,t,o),...a&&{group:a}});this.createTrend=(e,t,s,r)=>{let i;if(t!==e){const o=+s-+r;i={direction:Math.sign(o),value:Math.abs(o),from:t}}return i};this.validateDefinition=()=>{const{id:e,type:t}=this.definition,s=[];if(this.group||(this.measures.length!==1?s.push(`Measures should only have 1 column defined. Found ${this.measures.length}`):this.titleColumn?this.valueKey||s.push('Missing ID in title measure. Expected measure to include "id: string" field'):s.push('No title column defined. Expected measure to include "display: string" field')),s.length){const r=`Validation: Visualisaton definition: ID: ${e}, type: ${t}, errors: ${s.join(",")}`;throw new Error(r)}};this.createScorecardGroupFromColumns=()=>{const{latest:e,earliest:t,latestTs:s,earliestTs:r}=this.dataset;return e.map((i,o)=>({title:this.createGroupTitle(i),scorecards:Object.keys(i).filter(a=>a!==this.groupKeyId).map(a=>{const d=this.measures.find(w=>w.id===a)?.display||a,p=i[a],{raw:h,rag:m}=p,y=Number(h),S=m!==void 0?Number(m):void 0;this.initBuckets([i],a);const C=`${s}`,V=`${r}`,G=t[o][a]?.raw;return this.createScorecardData({title:d,value:y,rag:S,prevVal:G,valueFor:C,valueFrom:V})})}))};this.createScorecardGroupFromList=()=>{const{latest:e,earliest:t}=this.dataset;return[{title:"",scorecards:e.map((s,r)=>{const i=this.getScorecardValues(s),o=t[r][this.valueKey].raw;return this.createScorecardData({...i,prevVal:o})})}]};this.createScorecardGroupFromListWithGroups=()=>{const{latest:e,earliest:t}=this.dataset;let s=n.default.groupRowsByKey(t,this.groupKeyId),r=n.default.groupRowsByKey(e,this.groupKeyId);return this.groupKeyId===this.titleKey&&(r=[r.flat()],s=[s.flat()]),r.map((o,a)=>({title:this.createGroupTitle(o[0]),scorecards:o.map((c,d)=>{const p=this.getScorecardValues(c),m=s[a][d][this.valueKey]?.raw;return this.createScorecardData({...p,prevVal:m})})}))};this.getScorecardValues=e=>{const{latestTs:t,earliestTs:s}=this.dataset,r=`${this.titleColumn.display} ${e[this.titleKey].raw}`,i=e[this.valueKey],{raw:o,rag:a}=i,c=Number(o),d=a!==void 0?Number(a):void 0;this.initBuckets([e],this.valueKey);const p=`${t}`,h=`${s}`;return{title:r,value:c,rag:d,valueFor:p,valueFrom:h}};this.buildScorecard=()=>{const{latest:e,earliest:t,latestTs:s,earliestTs:r}=this.dataset;return e.map((o,a)=>{const{raw:c,rag:d}=o[this.valueKey],p=t[a][this.valueKey].raw,h=`${s}`,m=`${r}`,y=this.titleColumn.display;return this.createScorecardData({title:y,value:c,rag:d,prevVal:p,valueFor:h,valueFrom:m})})[0]};this.createGroupTitle=e=>{const t=this.groupKeyId?`${e[this.groupKeyId]?.raw}`:"";return this.groupKeyDisplay&&this.groupKeyDisplay.length?`${this.groupKeyDisplay}: ${t}`:t};this.buildGroup=()=>{let e;return this.valueColumn?this.groupKey?e=this.createScorecardGroupFromListWithGroups():e=this.createScorecardGroupFromList():e=this.createScorecardGroupFromColumns(),e};this.build=()=>(this.validateDefinition(),this.group?this.buildGroup():this.buildScorecard());this.group=s,this.dataset=this.getDataset(t,e),s?this.initGroupVars():(this.valueKey=this.measures[0].id,this.titleColumn={display:t.display,id:this.valueKey},this.initBuckets(e,this.valueKey))}}var M=f;0&&(module.exports={ScorecardVisualisation});
|
|
2
|
+
//# sourceMappingURL=Scorecard.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/dpr/components/_dashboards/scorecard/Scorecard.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable prefer-destructuring */\nimport { DashboardDataResponse } from '../../../types/Metrics'\nimport DashboardVisualisationClass from '../../_charts/chart/DashboardVisualisation'\nimport {\n DashboardVisualisation,\n DashboardVisualisationBucket,\n DashboardVisualisationColumnKey,\n DashboardVisualisationColumnMeasure,\n} from '../dashboard/types'\nimport DatasetHelper from '../../../utils/datasetHelper'\nimport { CreateScorecardDataArgs, Scorecard, ScorecardDataset, ScorecardGroup, ScorecardTrend } from './types'\nimport Buckets from '../../_charts/chart/Buckets'\n\nclass ScorecardVisualisation extends DashboardVisualisationClass {\n private dataset: ScorecardDataset\n\n private groupKey: DashboardVisualisationColumnKey\n\n private groupKeyId: string\n\n private groupKeyDisplay: string\n\n private bucketsHelper: Buckets\n\n private buckets: DashboardVisualisationBucket[] = []\n\n private valueColumn: DashboardVisualisationColumnMeasure\n\n private valueKey: string\n\n private titleColumn: DashboardVisualisationColumnMeasure\n\n private titleKey: string\n\n private group: boolean\n\n private ragColours: string[] = ['#cce2d8', '#fff7bf', '#f4cdc6']\n\n constructor(responseData: DashboardDataResponse[], definition: DashboardVisualisation, group = false) {\n super(responseData, definition)\n this.group = group\n this.dataset = this.getDataset(definition, responseData)\n\n if (group) {\n this.initGroupVars()\n } else {\n this.valueKey = this.measures[0].id\n this.titleColumn = { display: definition.display, id: this.valueKey }\n this.initBuckets(responseData, this.valueKey)\n }\n }\n\n private initBuckets = (responseData: DashboardDataResponse[], valueKey: string) => {\n this.bucketsHelper = new Buckets(responseData, this.definition, valueKey, false, this.ragColours)\n this.buckets = new Buckets(responseData, this.definition, valueKey, false, this.ragColours).getBuckets()\n }\n\n private initGroupVars = () => {\n this.groupKey = DatasetHelper.getGroupKey(this.keys, this.dataset.latest)\n this.groupKeyId = this.groupKey?.id\n this.groupKeyDisplay = this.groupKey?.display\n\n this.valueColumn = this.measures.find((col) => col.displayValue)\n if (this.valueColumn) {\n this.valueKey = this.valueColumn?.id\n this.titleColumn = this.measures.find((col) => {\n return col.display || col.display === ''\n })\n this.titleKey = this.titleColumn?.id\n }\n }\n\n private getDataset = (scorecardDefinition: DashboardVisualisation, rawData: DashboardDataResponse[]) => {\n const latestData = DatasetHelper.getLastestDataset(rawData)\n const latestDataSetRows = DatasetHelper.getDatasetRows(scorecardDefinition, latestData)\n const latestTs = latestDataSetRows[0]?.ts?.raw\n const latestFiltered = DatasetHelper.filterRowsByDisplayColumns(scorecardDefinition, latestDataSetRows, true)\n\n const earliestData = DatasetHelper.getEarliestDataset(rawData)\n const earliestDataSetRows = DatasetHelper.getDatasetRows(scorecardDefinition, earliestData)\n const earliestTs = earliestDataSetRows[0]?.ts?.raw\n const earliestfiltered = DatasetHelper.filterRowsByDisplayColumns(scorecardDefinition, earliestDataSetRows, true)\n\n return {\n earliest: earliestfiltered,\n earliestTs,\n latest: latestFiltered,\n latestTs,\n }\n }\n\n private setRagScore = (value: number, rag?: number) => {\n return this.bucketsHelper.getBucketForValue(value, rag)\n }\n\n private createScorecardData = ({\n title,\n value,\n rag,\n valueFor,\n valueFrom,\n prevVal,\n groupTitle,\n }: CreateScorecardDataArgs) => {\n return {\n title,\n value,\n ...(!Number.isNaN(value) && this.buckets.length && { rag: this.setRagScore(<number>value, rag) }),\n valueFor,\n trend: this.createTrend(valueFor, valueFrom, value, prevVal),\n ...(groupTitle && {\n group: groupTitle,\n }),\n }\n }\n\n private createTrend = (\n valueFor: string,\n valueFrom: string,\n latestValue: string | number,\n earliestValue: string | number,\n ): ScorecardTrend | undefined => {\n let trendData\n\n if (valueFrom !== valueFor) {\n const value = +latestValue - +earliestValue\n const direction = Math.sign(value)\n trendData = {\n direction,\n value: Math.abs(value),\n from: valueFrom,\n }\n }\n\n return trendData\n }\n\n private validateDefinition = () => {\n const { id, type } = this.definition\n const errors = []\n if (!this.group) {\n if (this.measures.length !== 1) {\n errors.push(`Measures should only have 1 column defined. Found ${this.measures.length}`)\n } else if (!this.titleColumn) {\n errors.push(`No title column defined. Expected measure to include \"display: string\" field`)\n } else if (!this.valueKey) {\n errors.push(`Missing ID in title measure. Expected measure to include \"id: string\" field`)\n }\n }\n\n if (errors.length) {\n // Throw the error\n const message = `Validation: Visualisaton definition: ID: ${id}, type: ${type}, errors: ${errors.join(',')}`\n throw new Error(message)\n }\n }\n\n private createScorecardGroupFromColumns = () => {\n const { latest, earliest, latestTs, earliestTs } = this.dataset\n\n return latest.map((row, rowIndex) => {\n return {\n title: this.createGroupTitle(row),\n scorecards: Object.keys(row)\n .filter((colId) => colId !== this.groupKeyId)\n .map((colId) => {\n const measure = this.measures.find((m) => m.id === colId)\n const title = measure?.display || colId\n const rowCol = row[colId]\n const { raw, rag: ragScore } = rowCol\n const value = Number(raw)\n\n const rag = ragScore !== undefined ? Number(ragScore) : undefined\n this.initBuckets([row], colId)\n\n const valueFor = `${latestTs}`\n const valueFrom = `${earliestTs}`\n\n const comparisonRow = earliest[rowIndex]\n const prevVal = comparisonRow[colId]?.raw\n\n return this.createScorecardData({\n title,\n value,\n rag,\n prevVal,\n valueFor,\n valueFrom,\n })\n }),\n }\n })\n }\n\n private createScorecardGroupFromList = (): ScorecardGroup[] => {\n const { latest, earliest } = this.dataset\n return [\n {\n title: '',\n scorecards: latest.map((row: DashboardDataResponse, index: number) => {\n const values = this.getScorecardValues(row)\n const prevVal = earliest[index][this.valueKey].raw\n return this.createScorecardData({\n ...values,\n prevVal,\n })\n }),\n },\n ]\n }\n\n private createScorecardGroupFromListWithGroups = () => {\n const { latest, earliest } = this.dataset\n\n let earliestGroupedByKey = DatasetHelper.groupRowsByKey(earliest, this.groupKeyId)\n let latestGroupedByKey = DatasetHelper.groupRowsByKey(latest, this.groupKeyId)\n if (this.groupKeyId === this.titleKey) {\n latestGroupedByKey = [latestGroupedByKey.flat()]\n earliestGroupedByKey = [earliestGroupedByKey.flat()]\n }\n\n const scorecardGroup = latestGroupedByKey.map((group, groupIndex) => {\n return {\n title: this.createGroupTitle(group[0]),\n scorecards: group.map((row, rowIndex) => {\n const values = this.getScorecardValues(row)\n const comparisonRow = earliestGroupedByKey[groupIndex][rowIndex]\n const prevVal = comparisonRow[this.valueKey]?.raw\n\n return this.createScorecardData({\n ...values,\n prevVal,\n })\n }),\n }\n })\n\n return scorecardGroup\n }\n\n private getScorecardValues = (row: DashboardDataResponse) => {\n const { latestTs, earliestTs } = this.dataset\n const title = `${this.titleColumn.display} ${row[this.titleKey].raw}`\n const rowCol = row[this.valueKey]\n const { raw, rag: ragScore } = rowCol\n const value = Number(raw)\n const rag = ragScore !== undefined ? Number(ragScore) : undefined\n this.initBuckets([row], this.valueKey)\n const valueFor = `${latestTs}`\n const valueFrom = `${earliestTs}`\n\n return {\n title,\n value,\n rag,\n valueFor,\n valueFrom,\n }\n }\n\n /**\n * Builds a single scorecard\n *\n * @return {Scorecard}\n */\n private buildScorecard = () => {\n const { latest, earliest, latestTs, earliestTs } = this.dataset\n const scorecordArr: Scorecard[] = latest.map((datasetRow: DashboardDataResponse, index: number) => {\n const { raw: value, rag } = datasetRow[this.valueKey]\n const prevVal = earliest[index][this.valueKey].raw\n const valueFor = `${latestTs}`\n const valueFrom = `${earliestTs}`\n const title = this.titleColumn.display\n\n return this.createScorecardData({\n title,\n value,\n rag,\n prevVal,\n valueFor,\n valueFrom,\n })\n })\n\n return scorecordArr[0]\n }\n\n private createGroupTitle = (row: DashboardDataResponse) => {\n const title = this.groupKeyId ? `${row[this.groupKeyId]?.raw}` : ''\n return this.groupKeyDisplay && this.groupKeyDisplay.length ? `${this.groupKeyDisplay}: ${title}` : title\n }\n\n private buildGroup = () => {\n let scorecardGroup: ScorecardGroup[]\n if (!this.valueColumn) {\n scorecardGroup = this.createScorecardGroupFromColumns()\n } else if (this.groupKey) {\n scorecardGroup = this.createScorecardGroupFromListWithGroups()\n } else {\n scorecardGroup = this.createScorecardGroupFromList()\n }\n return scorecardGroup\n }\n\n build = () => {\n this.validateDefinition()\n if (this.group) {\n return this.buildGroup()\n }\n return this.buildScorecard()\n }\n}\n\nexport { ScorecardVisualisation }\nexport default ScorecardVisualisation\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Scorecard_exports", "__export", "ScorecardVisualisation", "Scorecard_default", "__toCommonJS", "import_DashboardVisualisation", "import_datasetHelper", "import_Buckets", "DashboardVisualisationClass", "responseData", "definition", "group", "valueKey", "Buckets", "DatasetHelper", "col", "scorecardDefinition", "rawData", "latestData", "latestDataSetRows", "latestTs", "latestFiltered", "earliestData", "earliestDataSetRows", "earliestTs", "value", "rag", "title", "valueFor", "valueFrom", "prevVal", "groupTitle", "latestValue", "earliestValue", "trendData", "id", "type", "errors", "message", "latest", "earliest", "row", "rowIndex", "colId", "m", "rowCol", "raw", "ragScore", "index", "values", "earliestGroupedByKey", "latestGroupedByKey", "groupIndex", "datasetRow", "scorecardGroup"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/* eslint-disable prefer-destructuring */
|
|
2
|
+
import { DashboardDataResponse } from '../../../types/Metrics'
|
|
3
|
+
import DashboardVisualisationClass from '../../_charts/chart/DashboardVisualisation'
|
|
4
|
+
import {
|
|
5
|
+
DashboardVisualisation,
|
|
6
|
+
DashboardVisualisationBucket,
|
|
7
|
+
DashboardVisualisationColumnKey,
|
|
8
|
+
DashboardVisualisationColumnMeasure,
|
|
9
|
+
} from '../dashboard/types'
|
|
10
|
+
import DatasetHelper from '../../../utils/datasetHelper'
|
|
11
|
+
import { CreateScorecardDataArgs, Scorecard, ScorecardDataset, ScorecardGroup, ScorecardTrend } from './types'
|
|
12
|
+
import Buckets from '../../_charts/chart/Buckets'
|
|
13
|
+
|
|
14
|
+
class ScorecardVisualisation extends DashboardVisualisationClass {
|
|
15
|
+
private dataset: ScorecardDataset
|
|
16
|
+
|
|
17
|
+
private groupKey: DashboardVisualisationColumnKey
|
|
18
|
+
|
|
19
|
+
private groupKeyId: string
|
|
20
|
+
|
|
21
|
+
private groupKeyDisplay: string
|
|
22
|
+
|
|
23
|
+
private bucketsHelper: Buckets
|
|
24
|
+
|
|
25
|
+
private buckets: DashboardVisualisationBucket[] = []
|
|
26
|
+
|
|
27
|
+
private valueColumn: DashboardVisualisationColumnMeasure
|
|
28
|
+
|
|
29
|
+
private valueKey: string
|
|
30
|
+
|
|
31
|
+
private titleColumn: DashboardVisualisationColumnMeasure
|
|
32
|
+
|
|
33
|
+
private titleKey: string
|
|
34
|
+
|
|
35
|
+
private group: boolean
|
|
36
|
+
|
|
37
|
+
private ragColours: string[] = ['#cce2d8', '#fff7bf', '#f4cdc6']
|
|
38
|
+
|
|
39
|
+
constructor(responseData: DashboardDataResponse[], definition: DashboardVisualisation, group = false) {
|
|
40
|
+
super(responseData, definition)
|
|
41
|
+
this.group = group
|
|
42
|
+
this.dataset = this.getDataset(definition, responseData)
|
|
43
|
+
|
|
44
|
+
if (group) {
|
|
45
|
+
this.initGroupVars()
|
|
46
|
+
} else {
|
|
47
|
+
this.valueKey = this.measures[0].id
|
|
48
|
+
this.titleColumn = { display: definition.display, id: this.valueKey }
|
|
49
|
+
this.initBuckets(responseData, this.valueKey)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private initBuckets = (responseData: DashboardDataResponse[], valueKey: string) => {
|
|
54
|
+
this.bucketsHelper = new Buckets(responseData, this.definition, valueKey, false, this.ragColours)
|
|
55
|
+
this.buckets = new Buckets(responseData, this.definition, valueKey, false, this.ragColours).getBuckets()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private initGroupVars = () => {
|
|
59
|
+
this.groupKey = DatasetHelper.getGroupKey(this.keys, this.dataset.latest)
|
|
60
|
+
this.groupKeyId = this.groupKey?.id
|
|
61
|
+
this.groupKeyDisplay = this.groupKey?.display
|
|
62
|
+
|
|
63
|
+
this.valueColumn = this.measures.find((col) => col.displayValue)
|
|
64
|
+
if (this.valueColumn) {
|
|
65
|
+
this.valueKey = this.valueColumn?.id
|
|
66
|
+
this.titleColumn = this.measures.find((col) => {
|
|
67
|
+
return col.display || col.display === ''
|
|
68
|
+
})
|
|
69
|
+
this.titleKey = this.titleColumn?.id
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private getDataset = (scorecardDefinition: DashboardVisualisation, rawData: DashboardDataResponse[]) => {
|
|
74
|
+
const latestData = DatasetHelper.getLastestDataset(rawData)
|
|
75
|
+
const latestDataSetRows = DatasetHelper.getDatasetRows(scorecardDefinition, latestData)
|
|
76
|
+
const latestTs = latestDataSetRows[0]?.ts?.raw
|
|
77
|
+
const latestFiltered = DatasetHelper.filterRowsByDisplayColumns(scorecardDefinition, latestDataSetRows, true)
|
|
78
|
+
|
|
79
|
+
const earliestData = DatasetHelper.getEarliestDataset(rawData)
|
|
80
|
+
const earliestDataSetRows = DatasetHelper.getDatasetRows(scorecardDefinition, earliestData)
|
|
81
|
+
const earliestTs = earliestDataSetRows[0]?.ts?.raw
|
|
82
|
+
const earliestfiltered = DatasetHelper.filterRowsByDisplayColumns(scorecardDefinition, earliestDataSetRows, true)
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
earliest: earliestfiltered,
|
|
86
|
+
earliestTs,
|
|
87
|
+
latest: latestFiltered,
|
|
88
|
+
latestTs,
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private setRagScore = (value: number, rag?: number) => {
|
|
93
|
+
return this.bucketsHelper.getBucketForValue(value, rag)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private createScorecardData = ({
|
|
97
|
+
title,
|
|
98
|
+
value,
|
|
99
|
+
rag,
|
|
100
|
+
valueFor,
|
|
101
|
+
valueFrom,
|
|
102
|
+
prevVal,
|
|
103
|
+
groupTitle,
|
|
104
|
+
}: CreateScorecardDataArgs) => {
|
|
105
|
+
return {
|
|
106
|
+
title,
|
|
107
|
+
value,
|
|
108
|
+
...(!Number.isNaN(value) && this.buckets.length && { rag: this.setRagScore(<number>value, rag) }),
|
|
109
|
+
valueFor,
|
|
110
|
+
trend: this.createTrend(valueFor, valueFrom, value, prevVal),
|
|
111
|
+
...(groupTitle && {
|
|
112
|
+
group: groupTitle,
|
|
113
|
+
}),
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private createTrend = (
|
|
118
|
+
valueFor: string,
|
|
119
|
+
valueFrom: string,
|
|
120
|
+
latestValue: string | number,
|
|
121
|
+
earliestValue: string | number,
|
|
122
|
+
): ScorecardTrend | undefined => {
|
|
123
|
+
let trendData
|
|
124
|
+
|
|
125
|
+
if (valueFrom !== valueFor) {
|
|
126
|
+
const value = +latestValue - +earliestValue
|
|
127
|
+
const direction = Math.sign(value)
|
|
128
|
+
trendData = {
|
|
129
|
+
direction,
|
|
130
|
+
value: Math.abs(value),
|
|
131
|
+
from: valueFrom,
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return trendData
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private validateDefinition = () => {
|
|
139
|
+
const { id, type } = this.definition
|
|
140
|
+
const errors = []
|
|
141
|
+
if (!this.group) {
|
|
142
|
+
if (this.measures.length !== 1) {
|
|
143
|
+
errors.push(`Measures should only have 1 column defined. Found ${this.measures.length}`)
|
|
144
|
+
} else if (!this.titleColumn) {
|
|
145
|
+
errors.push(`No title column defined. Expected measure to include "display: string" field`)
|
|
146
|
+
} else if (!this.valueKey) {
|
|
147
|
+
errors.push(`Missing ID in title measure. Expected measure to include "id: string" field`)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (errors.length) {
|
|
152
|
+
// Throw the error
|
|
153
|
+
const message = `Validation: Visualisaton definition: ID: ${id}, type: ${type}, errors: ${errors.join(',')}`
|
|
154
|
+
throw new Error(message)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private createScorecardGroupFromColumns = () => {
|
|
159
|
+
const { latest, earliest, latestTs, earliestTs } = this.dataset
|
|
160
|
+
|
|
161
|
+
return latest.map((row, rowIndex) => {
|
|
162
|
+
return {
|
|
163
|
+
title: this.createGroupTitle(row),
|
|
164
|
+
scorecards: Object.keys(row)
|
|
165
|
+
.filter((colId) => colId !== this.groupKeyId)
|
|
166
|
+
.map((colId) => {
|
|
167
|
+
const measure = this.measures.find((m) => m.id === colId)
|
|
168
|
+
const title = measure?.display || colId
|
|
169
|
+
const rowCol = row[colId]
|
|
170
|
+
const { raw, rag: ragScore } = rowCol
|
|
171
|
+
const value = Number(raw)
|
|
172
|
+
|
|
173
|
+
const rag = ragScore !== undefined ? Number(ragScore) : undefined
|
|
174
|
+
this.initBuckets([row], colId)
|
|
175
|
+
|
|
176
|
+
const valueFor = `${latestTs}`
|
|
177
|
+
const valueFrom = `${earliestTs}`
|
|
178
|
+
|
|
179
|
+
const comparisonRow = earliest[rowIndex]
|
|
180
|
+
const prevVal = comparisonRow[colId]?.raw
|
|
181
|
+
|
|
182
|
+
return this.createScorecardData({
|
|
183
|
+
title,
|
|
184
|
+
value,
|
|
185
|
+
rag,
|
|
186
|
+
prevVal,
|
|
187
|
+
valueFor,
|
|
188
|
+
valueFrom,
|
|
189
|
+
})
|
|
190
|
+
}),
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private createScorecardGroupFromList = (): ScorecardGroup[] => {
|
|
196
|
+
const { latest, earliest } = this.dataset
|
|
197
|
+
return [
|
|
198
|
+
{
|
|
199
|
+
title: '',
|
|
200
|
+
scorecards: latest.map((row: DashboardDataResponse, index: number) => {
|
|
201
|
+
const values = this.getScorecardValues(row)
|
|
202
|
+
const prevVal = earliest[index][this.valueKey].raw
|
|
203
|
+
return this.createScorecardData({
|
|
204
|
+
...values,
|
|
205
|
+
prevVal,
|
|
206
|
+
})
|
|
207
|
+
}),
|
|
208
|
+
},
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private createScorecardGroupFromListWithGroups = () => {
|
|
213
|
+
const { latest, earliest } = this.dataset
|
|
214
|
+
|
|
215
|
+
let earliestGroupedByKey = DatasetHelper.groupRowsByKey(earliest, this.groupKeyId)
|
|
216
|
+
let latestGroupedByKey = DatasetHelper.groupRowsByKey(latest, this.groupKeyId)
|
|
217
|
+
if (this.groupKeyId === this.titleKey) {
|
|
218
|
+
latestGroupedByKey = [latestGroupedByKey.flat()]
|
|
219
|
+
earliestGroupedByKey = [earliestGroupedByKey.flat()]
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const scorecardGroup = latestGroupedByKey.map((group, groupIndex) => {
|
|
223
|
+
return {
|
|
224
|
+
title: this.createGroupTitle(group[0]),
|
|
225
|
+
scorecards: group.map((row, rowIndex) => {
|
|
226
|
+
const values = this.getScorecardValues(row)
|
|
227
|
+
const comparisonRow = earliestGroupedByKey[groupIndex][rowIndex]
|
|
228
|
+
const prevVal = comparisonRow[this.valueKey]?.raw
|
|
229
|
+
|
|
230
|
+
return this.createScorecardData({
|
|
231
|
+
...values,
|
|
232
|
+
prevVal,
|
|
233
|
+
})
|
|
234
|
+
}),
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
return scorecardGroup
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private getScorecardValues = (row: DashboardDataResponse) => {
|
|
242
|
+
const { latestTs, earliestTs } = this.dataset
|
|
243
|
+
const title = `${this.titleColumn.display} ${row[this.titleKey].raw}`
|
|
244
|
+
const rowCol = row[this.valueKey]
|
|
245
|
+
const { raw, rag: ragScore } = rowCol
|
|
246
|
+
const value = Number(raw)
|
|
247
|
+
const rag = ragScore !== undefined ? Number(ragScore) : undefined
|
|
248
|
+
this.initBuckets([row], this.valueKey)
|
|
249
|
+
const valueFor = `${latestTs}`
|
|
250
|
+
const valueFrom = `${earliestTs}`
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
title,
|
|
254
|
+
value,
|
|
255
|
+
rag,
|
|
256
|
+
valueFor,
|
|
257
|
+
valueFrom,
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Builds a single scorecard
|
|
263
|
+
*
|
|
264
|
+
* @return {Scorecard}
|
|
265
|
+
*/
|
|
266
|
+
private buildScorecard = () => {
|
|
267
|
+
const { latest, earliest, latestTs, earliestTs } = this.dataset
|
|
268
|
+
const scorecordArr: Scorecard[] = latest.map((datasetRow: DashboardDataResponse, index: number) => {
|
|
269
|
+
const { raw: value, rag } = datasetRow[this.valueKey]
|
|
270
|
+
const prevVal = earliest[index][this.valueKey].raw
|
|
271
|
+
const valueFor = `${latestTs}`
|
|
272
|
+
const valueFrom = `${earliestTs}`
|
|
273
|
+
const title = this.titleColumn.display
|
|
274
|
+
|
|
275
|
+
return this.createScorecardData({
|
|
276
|
+
title,
|
|
277
|
+
value,
|
|
278
|
+
rag,
|
|
279
|
+
prevVal,
|
|
280
|
+
valueFor,
|
|
281
|
+
valueFrom,
|
|
282
|
+
})
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
return scorecordArr[0]
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private createGroupTitle = (row: DashboardDataResponse) => {
|
|
289
|
+
const title = this.groupKeyId ? `${row[this.groupKeyId]?.raw}` : ''
|
|
290
|
+
return this.groupKeyDisplay && this.groupKeyDisplay.length ? `${this.groupKeyDisplay}: ${title}` : title
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private buildGroup = () => {
|
|
294
|
+
let scorecardGroup: ScorecardGroup[]
|
|
295
|
+
if (!this.valueColumn) {
|
|
296
|
+
scorecardGroup = this.createScorecardGroupFromColumns()
|
|
297
|
+
} else if (this.groupKey) {
|
|
298
|
+
scorecardGroup = this.createScorecardGroupFromListWithGroups()
|
|
299
|
+
} else {
|
|
300
|
+
scorecardGroup = this.createScorecardGroupFromList()
|
|
301
|
+
}
|
|
302
|
+
return scorecardGroup
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
build = () => {
|
|
306
|
+
this.validateDefinition()
|
|
307
|
+
if (this.group) {
|
|
308
|
+
return this.buildGroup()
|
|
309
|
+
}
|
|
310
|
+
return this.buildScorecard()
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export { ScorecardVisualisation }
|
|
315
|
+
export default ScorecardVisualisation
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var g=(e,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of i(r))!c.call(e,a)&&a!==o&&n(e,a,{get:()=>r[a],enumerable:!(t=s(r,a))||t.enumerable});return e};var d=e=>g(n({},"__esModule",{value:!0}),e);var u={};module.exports=d(u);
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/dpr/components/_dashboards/scorecard/types.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
4
|
+
"sourcesContent": ["import { DashboardDataResponse } from '../../../types/Metrics'\n\nexport interface Scorecard {\n title: string\n group?: string\n value: number | string\n trend?: ScorecardTrend\n link?: {\n href: '#'\n displayName: 'View breakdown'\n }\n valueFor?: string\n rag?: ScorecardRag\n}\n\nexport interface ScorecardSubGroup {\n name: string\n scorecards: Scorecard[]\n}\n\nexport interface ScorecardGroup {\n title?: string\n description?: string\n scorecards: Scorecard[]\n}\n\nexport interface ScorecardTrend {\n direction: number\n value: number\n from: string\n}\n\nexport interface ScorecardRag {\n score: number\n colour: string\n}\n\nexport interface ScorecardDataset {\n earliest: DashboardDataResponse[]\n earliestTs: string | number\n latest: DashboardDataResponse[]\n latestTs: string | number\n}\n\nexport interface CreateScorecardDataArgs {\n title: string\n value: string | number\n rag?: number\n valueFor: string\n valueFrom: string\n prevVal: string | number\n groupTitle?: string\n}\n"],
|
|
5
5
|
"mappings": "kWAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
6
|
"names": ["types_exports", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DashboardDataResponse } from '../../../types/Metrics'
|
|
2
|
+
|
|
1
3
|
export interface Scorecard {
|
|
2
4
|
title: string
|
|
3
5
|
group?: string
|
|
@@ -30,5 +32,22 @@ export interface ScorecardTrend {
|
|
|
30
32
|
|
|
31
33
|
export interface ScorecardRag {
|
|
32
34
|
score: number
|
|
33
|
-
|
|
35
|
+
colour: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ScorecardDataset {
|
|
39
|
+
earliest: DashboardDataResponse[]
|
|
40
|
+
earliestTs: string | number
|
|
41
|
+
latest: DashboardDataResponse[]
|
|
42
|
+
latestTs: string | number
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CreateScorecardDataArgs {
|
|
46
|
+
title: string
|
|
47
|
+
value: string | number
|
|
48
|
+
rag?: number
|
|
49
|
+
valueFor: string
|
|
50
|
+
valueFrom: string
|
|
51
|
+
prevVal: string | number
|
|
52
|
+
groupTitle?: string
|
|
34
53
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var l=(o,c)=>{for(var e in c)d(o,e,{get:c[e],enumerable:!0})},i=(o,c,e,t)=>{if(c&&typeof c=="object"||typeof c=="function")for(let r of u(c))!h.call(o,r)&&r!==e&&d(o,r,{get:()=>c[r],enumerable:!(t=p(c,r))||t.enumerable});return o};var m=o=>i(d({},"__esModule",{value:!0}),o);var S={};l(S,{default:()=>b,mergeScorecardsIntoGroup:()=>s});module.exports=m(S);var n=require("../dashboard/types");const s=o=>(o.reduce((e,t,r)=>(t.type===n.DashboardVisualisationType.SCORECARD&&e.push(r),e),[]).reduce((e,t)=>{const r=e[e.length-1];return(!r||r[r.length-1]!==t-1)&&e.push([]),e[e.length-1].push(t),e},[]).reverse().forEach(e=>{const t=e[0],r=e.map(a=>o[a].data).filter(a=>!!a);for(;e.length;)o.splice(e.pop(),1);r.length&&o.splice(t,0,{id:`${t}`,type:n.DashboardVisualisationType.SCORECARD_GROUP,data:[{scorecards:r}]})}),o);var b={mergeScorecardsIntoGroup:s};0&&(module.exports={mergeScorecardsIntoGroup});
|
|
2
2
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/dpr/components/_dashboards/scorecard/utils.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["utils_exports", "__export", "
|
|
4
|
+
"sourcesContent": ["import { DashboardUIVisualisation, DashboardVisualisationType } from '../dashboard/types'\nimport { Scorecard } from './types'\n\nexport const mergeScorecardsIntoGroup = (visualisations: DashboardUIVisualisation[]) => {\n const groupedScorecardIndexes: number[][] = visualisations\n // get scorecard indexes\n .reduce((acc: number[], vis: DashboardUIVisualisation, i: number) => {\n if (vis.type === DashboardVisualisationType.SCORECARD) acc.push(i)\n return acc\n }, [])\n // group adjacent indexes\n .reduce((r, n) => {\n const lastSubArray = r[r.length - 1]\n if (!lastSubArray || lastSubArray[lastSubArray.length - 1] !== n - 1) r.push([])\n r[r.length - 1].push(n)\n return r\n }, [])\n\n groupedScorecardIndexes.reverse().forEach((group: number[]) => {\n const spliceAtIndex = group[0]\n const scorecardGroup: Scorecard[] = group\n .map((scIndex: number) => {\n return visualisations[scIndex].data as Scorecard\n })\n .filter((scorecard: Scorecard) => !!scorecard)\n\n while (group.length) {\n visualisations.splice(group.pop(), 1)\n }\n\n if (scorecardGroup.length) {\n visualisations.splice(spliceAtIndex, 0, {\n id: `${spliceAtIndex}`,\n type: DashboardVisualisationType.SCORECARD_GROUP,\n data: [{ scorecards: scorecardGroup }],\n })\n }\n })\n\n return visualisations\n}\n\nexport default {\n mergeScorecardsIntoGroup,\n}\n"],
|
|
5
|
+
"mappings": "4ZAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,6BAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAAqE,8BAG9D,MAAMF,EAA4BG,IACKA,EAEzC,OAAO,CAACC,EAAeC,EAA+BC,KACjDD,EAAI,OAAS,6BAA2B,WAAWD,EAAI,KAAKE,CAAC,EAC1DF,GACN,CAAC,CAAC,EAEJ,OAAO,CAACG,EAAGC,IAAM,CAChB,MAAMC,EAAeF,EAAEA,EAAE,OAAS,CAAC,EACnC,OAAI,CAACE,GAAgBA,EAAaA,EAAa,OAAS,CAAC,IAAMD,EAAI,IAAGD,EAAE,KAAK,CAAC,CAAC,EAC/EA,EAAEA,EAAE,OAAS,CAAC,EAAE,KAAKC,CAAC,EACfD,CACT,EAAG,CAAC,CAAC,EAEiB,QAAQ,EAAE,QAASG,GAAoB,CAC7D,MAAMC,EAAgBD,EAAM,CAAC,EACvBE,EAA8BF,EACjC,IAAKG,GACGV,EAAeU,CAAO,EAAE,IAChC,EACA,OAAQC,GAAyB,CAAC,CAACA,CAAS,EAE/C,KAAOJ,EAAM,QACXP,EAAe,OAAOO,EAAM,IAAI,EAAG,CAAC,EAGlCE,EAAe,QACjBT,EAAe,OAAOQ,EAAe,EAAG,CACtC,GAAI,GAAGA,CAAa,GACpB,KAAM,6BAA2B,gBACjC,KAAM,CAAC,CAAE,WAAYC,CAAe,CAAC,CACvC,CAAC,CAEL,CAAC,EAEMT,GAGT,IAAOJ,EAAQ,CACb,yBAAAC,CACF",
|
|
6
|
+
"names": ["utils_exports", "__export", "utils_default", "mergeScorecardsIntoGroup", "__toCommonJS", "import_types", "visualisations", "acc", "vis", "i", "r", "n", "lastSubArray", "group", "spliceAtIndex", "scorecardGroup", "scIndex", "scorecard"]
|
|
7
7
|
}
|