Skip to content

Commit 906b3b5

Browse files
committed
Refactor SKU mapping and update usage report service for consistency
1 parent 89f7d05 commit 906b3b5

File tree

4 files changed

+109
-66
lines changed

4 files changed

+109
-66
lines changed

src/app/components/usage/actions/table-workflow-usage/table-workflow-usage.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export class TableWorkflowUsageComponent implements OnChanges, AfterViewInit {
227227
{
228228
columnDef: 'sku',
229229
header: 'Runner',
230-
cell: (workflowItem: WorkflowUsageItem) => workflowItem.sku,
230+
cell: (workflowItem: WorkflowUsageItem) => this.usageReportService.formatSku(workflowItem.sku),
231231
sticky: true,
232232
},
233233
];

src/app/components/usage/copilot/table-workflow-usage/table-copilot-usage.component.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AfterViewInit, Component, Input, OnChanges, ViewChild } from '@angular/core';
1+
import { AfterViewInit, Component, Input, OnChanges, ViewChild, ChangeDetectorRef } from '@angular/core';
22
import { MatPaginator } from '@angular/material/paginator';
33
import { MatTableDataSource } from '@angular/material/table';
44
import { MatSort } from '@angular/material/sort';
@@ -39,6 +39,7 @@ export class TableCopilotUsageComponent implements OnChanges, AfterViewInit {
3939

4040
constructor(
4141
private usageReportService: UsageReportService,
42+
private cdr: ChangeDetectorRef
4243
) { }
4344

4445
ngOnChanges() {
@@ -66,6 +67,7 @@ export class TableCopilotUsageComponent implements OnChanges, AfterViewInit {
6667
header: month,
6768
cell: (workflowItem: any) => this.currency === 'cost' ? currencyPipe.transform(workflowItem[month]) : decimalPipe.transform(workflowItem[month]),
6869
footer: () => {
70+
if (!this.dataSource?.data) return '';
6971
const total = this.dataSource.data.reduce((acc, item) => acc + (item as any)[month], 0);
7072
return this.currency === 'cost' ? currencyPipe.transform(total) : decimalPipe.transform(total);
7173
}
@@ -95,8 +97,15 @@ export class TableCopilotUsageComponent implements OnChanges, AfterViewInit {
9597
});
9698
});
9799
usage = usageItems
98-
this.displayedColumns = this.columns.map(c => c.columnDef);
100+
101+
// Update dataSource first
99102
this.dataSource.data = usage;
103+
104+
// Then update displayedColumns in the next tick to avoid ExpressionChangedAfterItHasBeenCheckedError
105+
setTimeout(() => {
106+
this.displayedColumns = this.columns.map(c => c.columnDef);
107+
this.cdr.detectChanges();
108+
});
100109
}
101110

102111
ngAfterViewInit() {
@@ -129,20 +138,24 @@ export class TableCopilotUsageComponent implements OnChanges, AfterViewInit {
129138
columnDef: 'total',
130139
header: 'Total seats',
131140
cell: (workflowItem: CopilotUsageItem) => decimalPipe.transform(Math.floor(workflowItem.total)),
132-
footer: () => decimalPipe.transform(this.data.reduce((acc, line) => acc += line.value, 0))
141+
footer: () => {
142+
if (!this.data) return '';
143+
return decimalPipe.transform(this.data.reduce((acc, line) => acc += line.value, 0));
144+
}
133145
});
134146
} else if (this.currency === 'cost') {
135147
columns.push({
136148
columnDef: 'cost',
137149
header: 'Total cost',
138150
cell: (workflowItem: CopilotUsageItem) => currencyPipe.transform(workflowItem.cost),
139-
footer: () => currencyPipe.transform(this.data.reduce((acc, line) => acc += line.value, 0))
151+
footer: () => {
152+
if (!this.data) return '';
153+
return currencyPipe.transform(this.data.reduce((acc, line) => acc += line.value, 0));
154+
}
140155
});
141156
}
142157
}
143-
// columns[0].footer = () => 'Total';
144158
this.columns = columns;
145-
this.displayedColumns = this.columns.map(c => c.columnDef);
146159
}
147160
}
148161

src/app/components/usage/shared-storage/table-shared-storage/table-shared-storage.component.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Input, Pipe, PipeTransform, ViewChild, OnChanges, AfterViewInit } from '@angular/core';
1+
import { Component, Input, Pipe, PipeTransform, ViewChild, OnChanges, AfterViewInit, ChangeDetectorRef } from '@angular/core';
22
import { MatPaginator } from '@angular/material/paginator';
33
import { MatTableDataSource } from '@angular/material/table';
44
import { MatSort } from '@angular/material/sort';
@@ -37,6 +37,8 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
3737
@ViewChild(MatPaginator) paginator!: MatPaginator;
3838
@ViewChild(MatSort) sort!: MatSort;
3939

40+
constructor(private cdr: ChangeDetectorRef) {}
41+
4042
ngOnChanges() {
4143
this.initializeColumns();
4244
const workflowUsage = this.data.reduce((acc, line) => {
@@ -56,6 +58,7 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
5658
header: month,
5759
cell: (sharedStorageItem: any) => this.currency === 'cost' ? currencyPipe.transform(sharedStorageItem[month]) : fileSizePipe.transform(sharedStorageItem[month]),
5860
footer: () => {
61+
if (!this.dataSource?.data) return '';
5962
const total = this.dataSource.data.reduce((acc, item) => acc + (item as any)[month], 0);
6063
return this.currency === 'cost' ? currencyPipe.transform(total) : fileSizePipe.transform(total);
6164
}
@@ -91,8 +94,14 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
9194
});
9295
});
9396

94-
this.displayedColumns = this.columns.map(c => c.columnDef);
95-
this.dataSource ? this.dataSource.data = workflowUsage : this.dataSource = new MatTableDataSource();
97+
// Update dataSource first
98+
this.dataSource.data = workflowUsage;
99+
100+
// Then update displayedColumns in the next tick to avoid ExpressionChangedAfterItHasBeenCheckedError
101+
setTimeout(() => {
102+
this.displayedColumns = this.columns.map(c => c.columnDef);
103+
this.cdr.detectChanges();
104+
});
96105
}
97106

98107
ngAfterViewInit() {
@@ -119,7 +128,10 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
119128
columnDef: 'count',
120129
header: 'Count',
121130
cell: (sharedStorageItem: any) => sharedStorageItem.count,
122-
footer: () => this.dataSource.data.reduce((acc, line) => acc + line.count, 0),
131+
footer: () => {
132+
if (!this.dataSource?.data) return '';
133+
return this.dataSource.data.reduce((acc, line) => acc + line.count, 0);
134+
},
123135
}
124136
];
125137
if (this.currency == 'cost') {
@@ -128,13 +140,19 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
128140
columnDef: 'total',
129141
header: 'Total Cost',
130142
cell: (sharedStorageItem: any) => currencyPipe.transform(sharedStorageItem.totalCost),
131-
footer: () => currencyPipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.totalCost, 0))
143+
footer: () => {
144+
if (!this.dataSource?.data) return '';
145+
return currencyPipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.totalCost, 0));
146+
}
132147
},
133148
{
134149
columnDef: 'costPerDay',
135150
header: 'Cost Per Day',
136151
cell: (sharedStorageItem: SharedStorageUsageItem) => currencyPipe.transform(sharedStorageItem.costPerDay),
137-
footer: () => currencyPipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.costPerDay, 0)),
152+
footer: () => {
153+
if (!this.dataSource?.data) return '';
154+
return currencyPipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.costPerDay, 0));
155+
},
138156
}
139157
);
140158
} else if (this.currency == 'minutes') {
@@ -143,18 +161,23 @@ export class TableSharedStorageComponent implements OnChanges, AfterViewInit {
143161
columnDef: 'avgSize',
144162
header: 'Average Size',
145163
cell: (sharedStorageItem: any) => fileSizePipe.transform(sharedStorageItem.avgSize),
146-
footer: () => fileSizePipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.avgSize, 0) / this.dataSource.data.length),
164+
footer: () => {
165+
if (!this.dataSource?.data || this.dataSource.data.length === 0) return '';
166+
return fileSizePipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.avgSize, 0) / this.dataSource.data.length);
167+
},
147168
},
148169
{
149170
columnDef: 'total',
150171
header: 'Total',
151172
cell: (sharedStorageItem: any) => fileSizePipe.transform(sharedStorageItem.total),
152-
footer: () => fileSizePipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.total, 0)),
173+
footer: () => {
174+
if (!this.dataSource?.data) return '';
175+
return fileSizePipe.transform(this.dataSource.data.reduce((acc, line) => acc + line.total, 0));
176+
},
153177
}
154178
);
155179
}
156180
this.columns = columns;
157-
this.displayedColumns = this.columns.map(c => c.columnDef);
158181
}
159182

160183
applyFilter(event: Event) {

src/app/usage-report.service.ts

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -43,58 +43,65 @@ export class UsageReportService {
4343
usernames: string[] = [];
4444
valueType: BehaviorSubject<'minutes' | 'cost'> = new BehaviorSubject<'minutes' | 'cost'>('cost')
4545
skuMapping: { [key: string]: string } = {
46-
"Compute - UBUNTU": 'Ubuntu 2',
47-
"Compute - UBUNTU_16_CORE": 'Ubuntu 16',
48-
"Compute - UBUNTU_16_CORE_ARM": 'Ubuntu 16 (ARM)',
49-
"Compute - UBUNTU_2_CORE_ARM": 'Ubuntu 2 (ARM)',
50-
"Compute - UBUNTU_32_CORE": 'Ubuntu 32',
51-
"Compute - UBUNTU_32_CORE_ARM": 'Ubuntu 32 (ARM)',
52-
"Compute - UBUNTU_4_CORE": 'Ubuntu 4',
53-
"Compute - UBUNTU_4_CORE_ARM": 'Ubuntu 4 (ARM)',
54-
"Compute - UBUNTU_4_CORE_GPU": 'Ubuntu 4 (GPU)',
55-
"Compute - UBUNTU_64_CORE": 'Ubuntu 64',
56-
"Compute - UBUNTU_64_CORE_ARM": 'Ubuntu 64 (ARM)',
57-
"Compute - UBUNTU_8_CORE": 'Ubuntu 8',
58-
"Compute - UBUNTU_8_CORE_ARM": 'Ubuntu 8 (ARM)',
59-
"Compute - MACOS": 'MacOS 3',
60-
"Compute - MACOS_12_CORE": 'MacOS 12',
61-
"Compute - MACOS_8_CORE": 'MacOS 8',
62-
"Compute - MACOS_LARGE": 'MacOS 12 (x86)',
63-
"Compute - MACOS_XLARGE": 'MacOS 6 (M1)',
64-
"Compute - WINDOWS": 'Windows 2',
65-
"Compute - WINDOWS_16_CORE": 'Windows 16',
66-
"Compute - WINDOWS_16_CORE_ARM": 'Windows 16 (ARM)',
67-
"Compute - WINDOWS_2_CORE_ARM": 'Windows 2 (ARM)',
68-
"Compute - WINDOWS_32_CORE": 'Windows 32',
69-
"Compute - WINDOWS_32_CORE_ARM": 'Windows 32 (ARM)',
70-
"Compute - WINDOWS_4_CORE": 'Windows 4',
71-
"Compute - WINDOWS_4_CORE_ARM": 'Windows 4 (ARM)',
72-
"Compute - WINDOWS_4_CORE_GPU": 'Windows 4 (GPU)',
73-
"Compute - WINDOWS_64_CORE": 'Windows 64',
74-
"Compute - WINDOWS_64_CORE_ARM": 'Windows 64 (ARM)',
75-
"Compute - WINDOWS_8_CORE": 'Windows 8',
76-
"Compute - WINDOWS_8_CORE_ARM": 'Windows 8 (ARM)',
46+
"actions_linux": 'Ubuntu 2',
47+
"actions_linux_16_core": 'Ubuntu 16',
48+
"actions_linux_16_core_arm": 'Ubuntu 16 (ARM)',
49+
"actions_linux_2_core_arm": 'Ubuntu 2 (ARM)',
50+
"actions_linux_32_core": 'Ubuntu 32',
51+
"actions_linux_32_core_arm": 'Ubuntu 32 (ARM)',
52+
"actions_linux_4_core": 'Ubuntu 4',
53+
"actions_linux_4_core_arm": 'Ubuntu 4 (ARM)',
54+
"actions_linux_4_core_gpu": 'Ubuntu 4 (GPU)',
55+
"actions_linux_64_core": 'Ubuntu 64',
56+
"actions_linux_64_core_arm": 'Ubuntu 64 (ARM)',
57+
"actions_linux_8_core": 'Ubuntu 8',
58+
"actions_linux_8_core_arm": 'Ubuntu 8 (ARM)',
59+
"actions_linux_2_core_advanced": 'Ubuntu 2 (Advanced)',
60+
"actions_macos": 'MacOS 3',
61+
"actions_macos_12_core": 'MacOS 12',
62+
"actions_macos_8_core": 'MacOS 8',
63+
"actions_macos_large": 'MacOS 12 (x86)',
64+
"actions_macos_xlarge": 'MacOS 6 (M1)',
65+
"actions_self_hosted_macos": 'MacOS (Self-Hosted)',
66+
"actions_windows": 'Windows 2',
67+
"actions_windows_16_core": 'Windows 16',
68+
"actions_windows_16_core_arm": 'Windows 16 (ARM)',
69+
"actions_windows_2_core_arm": 'Windows 2 (ARM)',
70+
"actions_windows_32_core": 'Windows 32',
71+
"actions_windows_32_core_arm": 'Windows 32 (ARM)',
72+
"actions_windows_4_core": 'Windows 4',
73+
"actions_windows_4_core_arm": 'Windows 4 (ARM)',
74+
"actions_windows_4_core_gpu": 'Windows 4 (GPU)',
75+
"actions_windows_64_core": 'Windows 64',
76+
"actions_windows_64_core_arm": 'Windows 64 (ARM)',
77+
"actions_windows_8_core": 'Windows 8',
78+
"actions_windows_8_core_arm": 'Windows 8 (ARM)',
79+
"actions_storage": 'Actions Storage',
80+
"actions_unknown": 'Actions Unknown',
81+
"copilot_enterprise": 'Copilot Enterprise',
82+
"copilot_for_business": 'Copilot Business',
83+
"git_lfs_storage": 'Git LFS Storage',
84+
"packages_storage": 'Packages Storage',
7785
};
7886
skuOrder = [
79-
'Compute - UBUNTU',
80-
'Compute - UBUNTU_4_CORE',
81-
'Compute - UBUNTU_8_CORE',
82-
'Compute - UBUNTU_16_CORE',
83-
'Compute - UBUNTU_32_CORE',
84-
'Compute - UBUNTU_64_CORE',
85-
'Compute - WINDOWS',
86-
// 'Compute - WINDOWS_4_CORE', DOESN'T EXIST
87-
'Compute - WINDOWS_8_CORE',
88-
'Compute - WINDOWS_16_CORE',
89-
'Compute - WINDOWS_32_CORE',
90-
'Compute - WINDOWS_64_CORE',
91-
'Compute - MACOS',
92-
'Compute - MACOS_12_CORE',
93-
'Compute - MACOS_LARGE',
94-
'Compute - MACOS_XLARGE',
95-
'Data Transfer',
96-
'Shared Storage',
97-
'Copilot Business',
87+
'actions_linux',
88+
'actions_linux_4_core',
89+
'actions_linux_8_core',
90+
'actions_linux_16_core',
91+
'actions_linux_32_core',
92+
'actions_linux_64_core',
93+
'actions_windows',
94+
// 'actions_windows_4_core', DOESN'T EXIST
95+
'actions_windows_8_core',
96+
'actions_windows_16_core',
97+
'actions_windows_32_core',
98+
'actions_windows_64_core',
99+
'actions_macos',
100+
'actions_macos_12_core',
101+
'actions_macos_large',
102+
'actions_macos_xlarge',
103+
'actions_storage',
104+
'copilot_for_business',
98105
].map(sku => this.formatSku(sku));
99106
monthsOrder = [
100107
'January',

0 commit comments

Comments
 (0)