Skip to content

Commit

Permalink
feat(dh): file upload for RSM-012 (#3872)
Browse files Browse the repository at this point in the history
Co-authored-by: Morten Hansen <mimo@mimo-design.com>
  • Loading branch information
dzhavat and mimse authored Jan 14, 2025
1 parent 3d4328c commit 899d1d1
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ type CalculationsConnection {
edges: [CalculationsEdge!]
"A flattened list of the nodes."
nodes: [Calculation!]
capacitySettlementsUploadUrl: String
}

"An edge in a connection."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2020 Energinet DataHub A/S
//
// Licensed under the Apache License, Version 2.0 (the "License2");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Energinet.DataHub.WebApi.GraphQL.Types.Calculation;

[ExtendObjectType("CalculationsConnection")]
public class CalculationsExtension
{
public string? GetCapacitySettlementsUploadUrl(
[Service] IHttpContextAccessor httpContextAccessor,
[Service] LinkGenerator linkGenerator) =>
linkGenerator.GetUriByAction(
httpContextAccessor.HttpContext!,
"ImportCapacitySettlements",
"Dh2Bridge");
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Energinet.DataHub.WebApi.Clients.MarketParticipant.v1;
using Energinet.DataHub.WebApi.GraphQL.Resolvers;

namespace Energinet.DataHub.WebApi.GraphQL.Types.Permission;

[ExtendObjectType("FilteredPermissionsConnection")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,12 @@
"search": "Søg på ID",
"new": "Ny beregning",
"scheduledCalculationTooltip": "Det faktiske tidspunkt kan afvige fra det planlagte tidspunkt",
"capacitySettlements": {
"uploadButton": "Upload fil til effektbetaling",
"uploadInProgress": "Upload i gang",
"uploadSuccess": "Fil uploadet",
"uploadError": "Noget gik galt. Filen blev ikke uploadet. Prøv igen"
},
"create": {
"title": "Ny beregning",
"periodWarning": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,12 @@
"search": "Search by ID",
"new": "New calculation",
"scheduledCalculationTooltip": "The actual time may differ from the scheduled time",
"capacitySettlements": {
"uploadButton": "Upload file for capacity settlements",
"uploadInProgress": "Upload in progress",
"uploadSuccess": "File uploaded",
"uploadError": "An error occurred while uploading the file. Please try again"
},
"create": {
"title": "New calculation",
"periodWarning": {
Expand Down
7 changes: 4 additions & 3 deletions libs/dh/shared/data-access-mocks/src/lib/wholesale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function wholesaleMocks(apiBase: string) {
return [
createCalculation(),
getCalculation(),
getCalculations(),
getCalculations(apiBase),
downloadSettlementReportData(apiBase),
downloadSettlementReportDataV2(apiBase),
getLatestCalculation(),
Expand Down Expand Up @@ -609,9 +609,9 @@ function downloadSettlementReportDataV2(apiBase: string) {
});
});
}
function getCalculations() {
function getCalculations(apiBase: string) {
return mockGetCalculationsQuery(async ({ variables }) => {
if (!variables.input.executionTime) {
if (!variables.input.executionType) {
return HttpResponse.json({ data: null }, { status: 500 });
} else {
await delay(mswConfig.delay);
Expand All @@ -625,6 +625,7 @@ function getCalculations() {
startCursor: 'startCursor',
endCursor: 'endCursor',
},
capacitySettlementsUploadUrl: `${apiBase}/v1/Dh2Bridge/ImportCapacitySettlements`,
totalCount: mockedCalculations.length,
nodes: mockedCalculations,
},
Expand Down
2 changes: 2 additions & 0 deletions libs/dh/shared/domain/src/lib/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const permissions = [
'request-wholesale-settlement:view',
'calculations:view',
'imbalance-prices:view',
'dh2-bridge:import',
'metering-point:search',
'fas',
] as const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ query GetCalculations(
startCursor
endCursor
}
capacitySettlementsUploadUrl
nodes {
id
state
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//#region License
/**
* @license
* Copyright 2020 Energinet DataHub A/S
*
* Licensed under the Apache License, Version 2.0 (the "License2");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#endregion
import { Component, ElementRef, inject, input, viewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { translate } from '@ngneat/transloco';
import { tapResponse } from '@ngrx/operators';

import { WattToastService } from '@energinet-datahub/watt/toast';

const jsonExt = '.json';
const jsonMimeType = 'application/json';

@Component({
selector: 'dh-capacity-settlements-uploader',
styles: [
`
.upload-input {
display: none;
}
`,
],
template: `<input
type="file"
class="upload-input"
[accept]="jsonExt"
(change)="onFileSelected(uploadInput.files)"
#uploadInput
/>`,
})
export class DhCapacitySettlementsUploaderComponent {
private readonly httpClient = inject(HttpClient);
private readonly toastService = inject(WattToastService);

private uploadInput = viewChild.required<ElementRef<HTMLInputElement>>('uploadInput');

uploadUrl = input.required<string>();

jsonExt = jsonExt;

selectFile(): void {
this.uploadInput().nativeElement.click();
}

onFileSelected(files: FileList | null): void {
if (files == null) {
return;
}

const file = files[0];

if (file.type === jsonMimeType) {
return this.startUpload(file);
}
}

private startUpload(file: File): void {
this.toastService.open({
type: 'loading',
message: translate('wholesale.calculations.capacitySettlements.uploadInProgress'),
});

const formData = new FormData();
formData.append('jsonFile', file);

this.httpClient
.post(this.uploadUrl(), formData)
.pipe(
tapResponse(
() => this.onUploadSuccessFn(),
() => this.onUploadErrorFn()
)
)
.subscribe();
}

private onUploadSuccessFn = () => {
const message = translate('wholesale.calculations.capacitySettlements.uploadSuccess');

this.toastService.open({ type: 'success', message });

this.resetUploadInput();
};

private onUploadErrorFn = () => {
const message = translate('wholesale.calculations.capacitySettlements.uploadError');

this.toastService.open({ type: 'danger', message });

this.resetUploadInput();
};

private resetUploadInput(): void {
this.uploadInput().nativeElement.value = '';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,33 @@
[error]="dataSource.error"
>
<h3>{{ t("headline") }}</h3>

<watt-button variant="secondary" icon="plus" (click)="create.emit()">
{{ t("new") }}
</watt-button>

<watt-button
*dhPermissionRequired="['dh2-bridge:import']"
variant="icon"
icon="menu"
[matMenuTriggerFor]="menu"
/>

<dh-capacity-settlements-uploader
[uploadUrl]="dataSource.query.data()?.calculations?.capacitySettlementsUploadUrl ?? ''"
#uploader
/>

<mat-menu #menu="matMenu">
<button type="button" mat-menu-item (click)="uploader.selectFile()">
{{ t("capacitySettlements.uploadButton") }}
</button>
</mat-menu>

<watt-data-filters>
<dh-calculations-filters [initial]="filter()" (filter)="filter.set($event)" />
</watt-data-filters>

<watt-table
*transloco="let translateHeader; read: 'wholesale.calculations.columns'"
[dataSource]="dataSource"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
effect,
} from '@angular/core';
import { TranslocoDirective } from '@ngneat/transloco';
import { MatMenuModule } from '@angular/material/menu';

import { WATT_TABLE, WattTableColumnDef } from '@energinet-datahub/watt/table';
import { WattBadgeComponent } from '@energinet-datahub/watt/badge';
Expand All @@ -35,7 +36,6 @@ import { WattDatePipe } from '@energinet-datahub/watt/date';
import { Calculation } from '@energinet-datahub/dh/wholesale/domain';
import { WattButtonComponent } from '@energinet-datahub/watt/button';
import { VaterStackComponent, VaterUtilityDirective } from '@energinet-datahub/watt/vater';
import { DhCalculationsFiltersComponent } from '../filters/filters.component';
import {
CalculationQueryInput,
CalculationOrchestrationState,
Expand All @@ -46,10 +46,16 @@ import { GetCalculationsDataSource } from '@energinet-datahub/dh/shared/domain/g

import { WattIconComponent } from '@energinet-datahub/watt/icon';
import { WattTooltipDirective } from '@energinet-datahub/watt/tooltip';
import { DhPermissionRequiredDirective } from '@energinet-datahub/dh/shared/feature-authorization';

import { DhCalculationsFiltersComponent } from '../filters/filters.component';
import { DhCapacitySettlementsUploaderComponent } from '../file-uploader/dh-capacity-settlements-uploader.component';

@Component({
imports: [
MatMenuModule,
TranslocoDirective,

VaterStackComponent,
VaterUtilityDirective,
WATT_TABLE,
Expand All @@ -60,7 +66,9 @@ import { WattTooltipDirective } from '@energinet-datahub/watt/tooltip';
WattDataFiltersComponent,
WattIconComponent,
WattTooltipDirective,
DhPermissionRequiredDirective,
DhCalculationsFiltersComponent,
DhCapacitySettlementsUploaderComponent,
],
selector: 'dh-calculations-table',
templateUrl: './table.component.html',
Expand Down

0 comments on commit 899d1d1

Please sign in to comment.