Skip to content

Commit

Permalink
- finish import feature
Browse files Browse the repository at this point in the history
  • Loading branch information
flange92 committed Feb 22, 2024
1 parent 3e83bde commit 50439e0
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<c8y-modal [customFooter]="true" #modal>
<ng-container c8y-modal-title>
<h1><i class="c8y-icon c8y-icon-device"></i></h1>
<h3 id="modal-title">
{{ 'Export Tenant Option' | translate }}
</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class ExportModalComponent {
link.download = 'export_tenant_options.json';
link.click();
this.isLoading = false;
this.close();
}

close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h3 id="modal-title">
title="{{ 'Import' | translate }}"
class="btn btn-primary"
type="button"
(click)="export()"
(click)="import()"
[ngClass]="{ 'btn-pending': isLoading }"
>
{{ 'Import' | translate }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import { Component } from '@angular/core';
import { ITenantOption } from '@c8y/client';
import { ITenantOption, TenantOptionsService } from '@c8y/client';
import {
AlertService,
Column,
ColumnDataType,
DisplayOptions,
ModalService,
Pagination,
Status,
_,
} from '@c8y/ngx-components';
import { BsModalRef } from 'ngx-bootstrap/modal';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { TenantOptionRow } from '../tenant-option-management.component';
import { TenantOptionRow, ImportStatus } from '../tenant-option-management.component';
import { TenantOptionManagementService } from '../tenant-option-management.service';
import { isEmpty } from 'lodash';

@Component({
templateUrl: './file-import-modal.component.html',
Expand Down Expand Up @@ -39,7 +46,14 @@ export class FileImportModalComponent {

title = 'Tenant Options Export';

constructor(private modal: BsModalRef, private alertService: AlertService) {
constructor(
private modal: BsModalRef,
private alertService: AlertService,
private optionsManagement: TenantOptionManagementService,
private tenantOptionService: TenantOptionsService,
protected confirmationModal: ModalService,
protected translateService: TranslateService
) {
this.columns = this.getDefaultColumns();
}

Expand All @@ -59,6 +73,13 @@ export class FileImportModalComponent {
filterable: true,
dataType: ColumnDataType.TextShort,
},
{
header: 'Status',
name: 'status',
path: 'status',
filterable: true,
dataType: ColumnDataType.TextShort,
},
];
}

Expand All @@ -72,6 +93,16 @@ export class FileImportModalComponent {
try {
const fileContent = e.target.result;
this.rows = JSON.parse(fileContent);
this.rows.forEach((row) => {
this.tenantOptionService
.detail({ category: row.category, key: row.key })
.then((_option) => {
row.status = ImportStatus.CONFLICT;
})
.catch((_error) => {
row.status = ImportStatus.NEW;
});
});
} catch (error) {
this.alertService.danger('Invalid file content. Please select a valid JSON file.');
console.warn(error);
Expand All @@ -81,26 +112,86 @@ export class FileImportModalComponent {
reader.readAsText(file);
} else {
this.alertService.danger('Invalid file type. Please select a JSON file.');
console.log('Invalid file type. Please select a JSON file.');
console.warn('Invalid file type. Please select a JSON file.');
}
}

async onItemsSelect(selectedItemIds: string[]) {
if (
this.rows.filter((r) => r.status === 'CONFLICT' && selectedItemIds.includes(r.id)).length > 0
) {
await this.confirmationModal
.confirm(
_('Overwrite Tenant Options') as string,
_(
'There is an existing tenant option with the same categroy and key. Do you want to continue an overwrite that one?'
) as string,
Status.DANGER,
{ ok: _('Overwritte') as string, cancel: _('Cancel') as string }
)
.then((result) => {
if (result) {
this.selectedItems = this.rows.filter((r) => selectedItemIds.includes(r.id));
this.rows
.filter((r) => r.status === ImportStatus.CONFLICT && selectedItemIds.includes(r.id))
.forEach((r) => (r.status = ImportStatus.OVERWRITE));
} else {
this.selectedItems = this.rows.filter(
(r) => r.status === ImportStatus.NEW && selectedItemIds.includes(r.id)
);
}
});
} else {
this.selectedItems = this.rows.filter((r) => selectedItemIds.includes(r.id));
}
}

onItemsSelect(selectedItemIds: string[]) {
this.selectedItems = this.rows.filter((r) => selectedItemIds.includes(r.id));
reload() { }

async import() {
if (this.selectedItems.length > 0) {
this.isLoading = true;
for (const item of this.selectedItems) {
await this.importOrUpdateItem(item);
}
this.isLoading = false;
this.alertService.success('Tenant options imported successfully.');
this.close();
} else {
this.alertService.danger('Please select at least one item to import.');
}
}

reload() {}

export() {
this.isLoading = true;
const selectedItemsJson = JSON.stringify(this.selectedItems);
const blob = new Blob([selectedItemsJson], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'export_tenant_options.json';
link.click();
this.isLoading = false;
async importOrUpdateItem(item: TenantOptionRow) {
const row = this.rows.find((r) => r.id == item.id);
if (!isEmpty(row)) {
if (row.status === ImportStatus.OVERWRITE) {
row.status = ImportStatus.LOADING;
const option = {
key: item.key,
category: item.category,
value: item.value,
encrypted: '',
};
await this.optionsManagement.updateOption(option);
try {
await this.optionsManagement.addOptionToConfiguration(option);
} catch (error) {
// Ignore the rejection
}
row.status = ImportStatus.UPDATED;
} else {
row.status = ImportStatus.LOADING;
const option = {
key: item.key,
category: item.category,
value: item.value,
encrypted: '',
};
await this.optionsManagement.addOption(option);
row.status = ImportStatus.ADDED;
}
}
}

close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@

<c8y-action-bar-item [placement]="'right'" [priority]="500">
<button
title="{{ 'New tenant option' | translate }}"
title="{{ 'Create new' | translate }}"
type="button"
class="btn btn-link"
(click)="openAddModal()"
>
<i c8yIcon="plus"></i> {{ 'New tenant option' | translate }}
<i c8yIcon="plus"></i> {{ 'Create new' | translate }}
</button>
</c8y-action-bar-item>

Expand Down
16 changes: 11 additions & 5 deletions tenant-option-management/tenant-option-management.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ import { FileImportModalComponent } from './file-import-modal/file-import-modal.

export interface TenantOptionRow extends ITenantOption {
id: string;
status?: ImportStatus;
}
export enum ImportStatus {
LOADING = 'LOADING',
NEW = 'NEW',
CONFLICT = 'CONFLICT',
OVERWRITE = 'OVERWRITE',
UPDATED = 'UPDATED',
ADDED = 'ADDED',
}
@Component({
templateUrl: './tenant-option-management.component.html',
Expand Down Expand Up @@ -118,11 +127,8 @@ export class TenantOptionManagementComponent {

openImportFromFileModal() {
const modalRef = this.bsModalService.show(FileImportModalComponent, {});
modalRef.content.closeSubject.pipe(take(1)).subscribe((o) => {
if (o) {
this.rows.push({ id: `${o.category}-${o.key}`, ...o });
this.rows = [...this.rows]; // trigger binding
}
modalRef.content.closeSubject.pipe(take(1)).subscribe(() => {
this.reload();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class TenantOptionManagementService {
return option;
}

private async addOptionToConfiguration(option: ITenantOption & { encrypted: string }) {
async addOptionToConfiguration(option: ITenantOption & { encrypted: string }) {
const config = await this.getConfiguration();
if (config.options.find((o) => o.category === option.category && o.key === option.key)) {
return Promise.reject('Tenant option already exists!');
Expand Down

0 comments on commit 50439e0

Please sign in to comment.