Skip to content

Commit

Permalink
feat: add app builder dashboard migration button plugin (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
reey authored Nov 6, 2024
1 parent d555333 commit aa50577
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 2 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ A feature that allows you to create simulators with the help of Claude AI. You o
![Advanced simulator](screenshots/advanced-simulator-screenshot.png?raw=true "Advanced simulator screenshot")

## `Application builder dashboard migration plugin`

A plugin that offers a button to migrate dashboards created via the deprecated [Application Builder app](https://github.com/Cumulocity-IoT/cumulocity-app-builder) to Cockpit reports.
The mentioned button can be found in the reports list in the Cockpit application once the plugin has been installed to the Cockpit app.


## Contributing

Expand Down
3 changes: 3 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,8 @@
}
}
}
},
"cli": {
"analytics": false
}
}
7 changes: 7 additions & 0 deletions cumulocity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export default {
path: './src/app/advanced-simulator/advanced-simulator.module.ts',
description: 'Allows to generate simulators with the help of Ai.',
},
{
name: 'Application builder dashboard migration',
module: 'AppBuilderDashboardMigrationModule',
path: './src/app/app-builder-dashboard-migration/app-builder-dashboard-migration.module.ts',
description:
'Allows to migrate dashboards generated via application builder to be migrated into cockpit reports.',
},
],
versioningMatrix,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ActionBarItem, ExtensionFactory } from '@c8y/ngx-components';
import { AppBuilderDashboardMigrationButtonComponent } from './app-builder-dashboard-migration-button/app-builder-dashboard-migration-button.component';
import { Observable, of } from 'rxjs';
import { distinctUntilChanged, switchMap } from 'rxjs/operators';

@Injectable({
providedIn: 'root',
})
export class AppBuilderDashboardMigrationButtonService
implements ExtensionFactory<ActionBarItem>
{
get(
activatedRoute?: ActivatedRoute
): Observable<ActionBarItem | ActionBarItem[]> {
return (activatedRoute?.url || of([])).pipe(
switchMap(async (url) => {
if (url?.length !== 1 || url?.[0].path !== 'reports') {
return false;
}

return true;
}),
distinctUntilChanged(),
switchMap(async (show) => {
if (!show) {
return [];
}

return {
component: AppBuilderDashboardMigrationButtonComponent,
placement: 'right' as const,
};
})
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<button
type="button"
class="btn btn-link"
(click)="migrateDashboards()"
[disabled]="!dashboards?.length"
>
<i c8yIcon="process"></i>
Migrate application builder dashboards
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Component, OnInit } from '@angular/core';
import { AlertService, IconDirective } from '@c8y/ngx-components';
import { AppBuilderDashboardMigrationService } from '../app-builder-dashboard-migration.service';
import { IManagedObject } from '@c8y/client';

@Component({
selector: 'li[app-app-builder-dashboard-migration-button]',
templateUrl: './app-builder-dashboard-migration-button.component.html',
standalone: true,
imports: [IconDirective],
})
export class AppBuilderDashboardMigrationButtonComponent implements OnInit {
dashboards: IManagedObject[] = [];
constructor(
private alert: AlertService,
private migrationService: AppBuilderDashboardMigrationService
) {}

async ngOnInit(): Promise<void> {
this.dashboards =
await this.migrationService.getNotMigratedAppBuilderDashboards();
}

async migrateDashboards() {
this.alert.info('Migrating dashboards...');
for (const dashboard of this.dashboards) {
await this.migrationService.migrateDashboard(dashboard);
}
this.alert.success(
'Dashboards migrated successfully, please reload the page.'
);
this.dashboards = [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { NgModule } from '@angular/core';
import { hookActionBar } from '@c8y/ngx-components';
import { AppBuilderDashboardMigrationButtonService } from './app-builder-dashboard-migration-button.service';

@NgModule({
providers: [hookActionBar(AppBuilderDashboardMigrationButtonService)],
})
export class AppBuilderDashboardMigrationModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Injectable } from '@angular/core';
import { IManagedObject, InventoryService } from '@c8y/client';

@Injectable({
providedIn: 'root',
})
export class AppBuilderDashboardMigrationService {
readonly reportPrefix = 'c8y_Dashboard!name!report_';
readonly identifier = 'migratedAppBuilderDashboardsToReport';

constructor(private inventory: InventoryService) {}

async getNotMigratedAppBuilderDashboards() {
const { data: dashboards } = await this.inventory.list({
fragmentType: 'c8y_Dashboard',
pageSize: 2000,
});

const noReportDashboards = dashboards.filter(
(dashboard) =>
!Object.keys(dashboard).some((key) => key.startsWith(this.reportPrefix))
);

const dashboardsWithMarker = noReportDashboards.filter((dashboard) =>
Object.keys(dashboard).some(
(key) =>
key.startsWith('global!presales!') ||
key === 'c8y_Dashboard!name!app-builder-db'
)
);
return dashboardsWithMarker;
}

async migrateDashboard(dashboard: IManagedObject) {
const { id, c8y_Dashboard: dashboardDetails } = dashboard;
const { name, icon, priority } = dashboardDetails;

const { data: reportObject } = await this.inventory.create({
name: name || 'Unnamed app builder dashboard',
icon,
priority,
description: null,
c8y_Report: {},
[this.identifier]: {},
});

await this.inventory.update({
id,
[`${this.reportPrefix}${reportObject.id}`]: {},
[this.identifier]: {},
});
}
}
8 changes: 6 additions & 2 deletions versioningMatrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@
},
"3.4.0": {
"sdk": ">=1020.26.2",
"api": ">=1020.26.2"
"api": ">=1020.0.0"
},
"3.4.1": {
"sdk": ">=1020.26.2",
"api": ">=1020.26.2"
"api": ">=1020.0.0"
},
"3.5.0": {
"sdk": ">=1020.26.2",
"api": ">=1020.0.0"
}
}

0 comments on commit aa50577

Please sign in to comment.