Skip to content
This repository has been archived by the owner on Nov 15, 2024. It is now read-only.

Commit

Permalink
1.3.0 merge into dev (#50)
Browse files Browse the repository at this point in the history
* 1.3.0-Dev-1
Initial commit with angular 11

* updated with font mapping

* Bug fixes

* 1.3.0-dev-2
Intermediate commit

* updated with web worker

* updated with upgrade fixes

* updated with runtime widget fixed

* updated with version and fixes

* updated with runtime fix

* Updated with runtime fix

* updated with widget catalog changes for github

* Enhancment:
1. Simulator: Default interval increased to 30 second
2. Simulator: last updated field added

Fixed following:
1. Icon Selector Sytling
2. Simulator default measurement type replaced with fragement name
3. Home page navigation link error (Right Click)

* Enhancement: Dashboard's Smart Rules, Alarms & Data explorer tabs now control from settings

bug: Fixed New Application validations

* Enhancement:
1. Branding: header style and color picker
2. Dashboard: new Help & Support Template

* updated with:
1. Dashboard: Delete confirmation
2. Simulator internval increased
3. Simulator: Device Id added in alternate config

* updated with server side simulator flag

* Simulator enhancement for server side implementation

* Simulator-Bug fix for simulation type

* updated with dashboard catalog changes

* updated with subscribe widget bug fix

* fixed dtdl config for data stracture
updated template catalog to support multiple versions of widget

* Fixed firmware simulator on change issue

* fixed: Widget catalog multiple version support

* updated for RC-1 Release

* fixed: Control by operation issue in simulators

* updated version

* updated with
simulator operations logic
new logo configuration option

* updated to support dev mode for widget catalog and
 dashboard catalog

* regenerated lock file
  • Loading branch information
DarpanLalani authored Feb 23, 2022
1 parent da610f2 commit d11c078
Show file tree
Hide file tree
Showing 81 changed files with 11,256 additions and 7,151 deletions.
9 changes: 7 additions & 2 deletions app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {Injector, NgModule} from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {NavigationError, Router, RouterModule as NgRouterModule} from '@angular/router';
import { UpgradeModule as NgUpgradeModule } from '@angular/upgrade/static';
import {AppStateService, CoreModule, RouterModule} from '@c8y/ngx-components';
import {AppStateService, CoreModule, RouterModule, PluginsModule} from '@c8y/ngx-components';
import {DashboardUpgradeModule, UpgradeModule, HybridAppModule} from '@c8y/ngx-components/upgrade';
import {BuilderModule} from "./builder/builder.module";
import {filter, first, map, startWith, tap, withLatestFrom} from "rxjs/operators";
Expand All @@ -29,6 +29,8 @@ import {CustomWidgetsModule} from "./custom-widgets/custom-widgets.module";
import {RuntimeWidgetInstallerModule, RuntimeWidgetLoaderService} from "cumulocity-runtime-widget-loader";
import { interval } from 'rxjs';
import { SettingsService } from './builder/settings/settings.service';

import { BinaryFileDownloadModule } from '@c8y/ngx-components/binary-file-download';
@NgModule({
imports: [
// Upgrade module must be the first
Expand All @@ -37,8 +39,10 @@ import { SettingsService } from './builder/settings/settings.service';
RouterModule.forRoot(),
NgRouterModule.forRoot([], { enableTracing: false, useHash: true }),
CoreModule.forRoot(),
// PluginsModule,
NgUpgradeModule,
DashboardUpgradeModule,
BinaryFileDownloadModule,
BuilderModule,
SimulationStrategiesModule,
CustomWidgetsModule,
Expand All @@ -47,7 +51,8 @@ import { SettingsService } from './builder/settings/settings.service';
})
export class AppModule extends HybridAppModule {
constructor(protected upgrade: NgUpgradeModule, appStateService: AppStateService, private router: Router,
private runtimeWidgetLoaderService: RuntimeWidgetLoaderService, private injector: Injector,
private runtimeWidgetLoaderService: RuntimeWidgetLoaderService,
private injector: Injector,
private settingsService: SettingsService) {
super();

Expand Down
Binary file removed binary/app-builder-external-assets-1.1.0.tgz
Binary file not shown.
Binary file added binary/app-builder-external-assets-2.0.4.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion builder/app-list/app-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Add application
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-2" *ngFor="let app of applications | async">
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-2" *ngFor="let app of applications">
<div class="card clickable" (click)="openApp(app)">
<div class="dropdown card-actions" dropdown (click)="$event.stopPropagation()" *ngIf="userHasAdminRights">
<button title="Settings" id="appSettings-{{app.name}}" class="dropdown-toggle c8y-dropdown" dropdownToggle type="button">
Expand Down
62 changes: 46 additions & 16 deletions builder/app-list/app-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import {Component} from "@angular/core";
import {
ApplicationService,
IApplication,
PagingStrategy,
RealtimeAction,
Realtime,
// PagingStrategy,
// RealtimeAction,
UserService
} from "@c8y/client";
import {catchError, map} from "rxjs/operators";
Expand All @@ -31,55 +32,84 @@ import { BsModalService, BsModalRef } from 'ngx-bootstrap/modal';
import {NewApplicationModalComponent} from "./new-application-modal.component";
import {Router} from "@angular/router";
import {contextPathFromURL} from "../utils/contextPathFromURL";
import { AppListService } from "./app-list.service";

@Component({
templateUrl: './app-list.component.html'
})
export class AppListComponent {
applications: Observable<IApplication[]>;
// applications: Observable<IApplication[]>;
applications: IApplication[];
allApplications: IApplication[];

userHasAdminRights: boolean;

bsModalRef: BsModalRef;

constructor(private router: Router, private appService: ApplicationService, private appStateService: AppStateService, private modalService: BsModalService, private userService: UserService) {
constructor(private router: Router, private appService: ApplicationService,
private appStateService: AppStateService, private modalService: BsModalService,
private userService: UserService, private appListService: AppListService, private realTimeService: Realtime) {

this.userHasAdminRights = userService.hasRole(appStateService.currentUser.value, "ROLE_APPLICATION_MANAGEMENT_ADMIN")
this.appListService.refreshAppList$.subscribe( () => {
this.getListOfApplications();

});
this.realTimeService.subscribe(
`/applications`,
async (response) => {
if (response && response.data) {
console.log('application realtime', response.data);
}
});
this.getListOfApplications();

}

private async getListOfApplications() {

// Get a list of the applications on the tenant (This includes live updates)
if(this.userHasAdminRights){
this.applications = from(this.appService.list$({ pageSize: 2000, withTotalPages: true }, {
hot: true,
pagingStrategy: PagingStrategy.ALL,
realtime: true,
realtimeAction: RealtimeAction.FULL,
pagingDelay: 0.1
}))
this.allApplications = ( await this.appService.list({ pageSize: 2000, withTotalPages: true }) as any).data ;
if(!this.allApplications || this.allApplications.length === 0) {
this.allApplications = ( await this.appService.listByUser(this.appStateService.currentUser.value, { pageSize: 2000 })).data;
}
this.applications = this.allApplications.filter(app => app.hasOwnProperty('applicationBuilder'));
this.applications = this.applications.sort((a, b) => a.id > b.id ? 1 : -1);
} else {
this.allApplications = ( await this.appService.listByUser(this.appStateService.currentUser.value, { pageSize: 2000 })).data;
this.applications = this.allApplications.filter(app => app.hasOwnProperty('applicationBuilder'));
this.applications = this.applications.sort((a, b) => a.id > b.id ? 1 : -1);
}
/* if(this.userHasAdminRights){
this.applications = from(new Observable(
this.appService.list({ pageSize: 2000, withTotalPages: true }) as any))
.pipe(
// Some users can't get the full list of applications (they don't have permission) so we get them by user instead (without live updates)
catchError(() =>
from(this.appService.listByUser(appStateService.currentUser.value, { pageSize: 2000 }).then(res => res.data))
from(this.appService.listByUser(this.appStateService.currentUser.value, { pageSize: 2000 }).then(res => res.data))
),
map(apps => apps.filter(app => app.hasOwnProperty('applicationBuilder'))),
map((apps: any) => apps.filter(app => app.hasOwnProperty('applicationBuilder'))),
map(apps => apps.sort((a, b) => a.id > b.id ? 1 : -1) )
);
} else {
this.applications = from(this.appService.listByUser(appStateService.currentUser.value, { pageSize: 2000 }).then(res => res.data))
this.applications = from(this.appService.listByUser(this.appStateService.currentUser.value, { pageSize: 2000 }).then(res => res.data))
.pipe(map(apps => apps.filter(app => app.hasOwnProperty('applicationBuilder'))),
map(apps => apps.sort((a, b) => a.id > b.id ? 1 : -1) ) );
}
} */
}

createAppWizard() {
this.bsModalRef = this.modalService.show(NewApplicationModalComponent, { class: 'c8y-wizard' ,initialState :
{ applications: this.applications}});
{ applications: this.applications, allApplications: this.allApplications}});
}

async deleteApplication(id: number) {
await this.appService.delete(id);

// Refresh the applications list
this.appStateService.currentUser.next(this.appStateService.currentUser.value);
this.appListService.RefreshAppList();
}

openApp(app: IApplication & {applicationBuilder?: any}, subPath?: string) {
Expand Down
12 changes: 12 additions & 0 deletions builder/app-list/app-list.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Injectable } from "@angular/core";
import { Subject } from "rxjs";

@Injectable({providedIn: 'root'})
export class AppListService {

refreshAppList$ = new Subject<any>();

RefreshAppList() {
this.refreshAppList$.next(true);
}
}
34 changes: 25 additions & 9 deletions builder/app-list/new-application-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {UpdateableAlert} from "../utils/UpdateableAlert";
import {contextPathFromURL} from "../utils/contextPathFromURL";
import { Observable } from 'rxjs';
import { SettingsService } from './../settings/settings.service';
import { AppListService } from './app-list.service';

@Component({
template: `
Expand All @@ -42,7 +43,7 @@ import { SettingsService } from './../settings/settings.service';
<div class="form-group">
<label for="icon"><span>Icon</span></label>
<icon-selector id="icon" name="icon" [(value)]="appIcon"></icon-selector>
<icon-selector id="icon" name="icon" [(value)]="appIcon" appendTo=".modal-content"></icon-selector>
</div>
<div class="form-group">
Expand All @@ -56,9 +57,9 @@ import { SettingsService } from './../settings/settings.service';
<div class="form-group">
<label for="appCloneName"><span>Clone Existing Application</span></label>
<input type="text" class="form-control" id="appCloneName" name="appCloneName"
placeholder="e.g. Type Application Name/Id (optional)"
placeholder="e.g. Type and select Application Name/Id (optional)"
[(ngModel)]="existingAppName" [typeahead]="appNameList" autocomplete="off">
<span id="helpBlockCloneApp" class="help-block">Only application builder's applications can be cloned here.</span>
</div>
</form>
</div>
Expand All @@ -74,23 +75,33 @@ export class NewApplicationModalComponent implements OnInit {
appPath: string = '';
existingAppName: string = '';
appIcon: string = 'bathtub';
applications: Observable<IApplication[]>;
// applications: Observable<IApplication[]>;
applications: IApplication[];
allApplications: IApplication[];
appList: any = [];
appNameList: any = [];

constructor(public bsModalRef: BsModalRef, private appService: ApplicationService, private appStateService: AppStateService,
private fetchClient: FetchClient, private inventoryService: InventoryService, private alertService: AlertService,
private settingsService: SettingsService) {}
private settingsService: SettingsService, private appListService: AppListService) {}

ngOnInit() {
this.loadApplicationsForClone();
}

async createApplication() {
this.bsModalRef.hide();

let isCloneApp = false;
let appBuilderObj;

// app validation check
const appFound = this.allApplications.find( app => app.name.toLowerCase() === this.appName.toLowerCase() ||
( this.appPath && this.appPath.length > 0 && ( app.contextPath && app.contextPath?.toLowerCase() === this.appPath.toLowerCase())))
if(appFound) {
this.alertService.danger(" Application name or context path already exists!");
return;
}

this.bsModalRef.hide();
if(this.existingAppName) {
const existingApp = this.existingAppName.split(' (');
if(existingApp.length > 1) {
Expand Down Expand Up @@ -286,6 +297,7 @@ export class NewApplicationModalComponent implements OnInit {
}
// Refresh the applications list
this.appStateService.currentUser.next(this.appStateService.currentUser.value);
this.appListService.RefreshAppList();
}

private async updateAppBuilderConfiguration(appBuilderId: any, newAppId: any) {
Expand All @@ -304,12 +316,16 @@ export class NewApplicationModalComponent implements OnInit {
}

loadApplicationsForClone() {
this.applications.subscribe(apps => {
this.appList = this.applications;
if (this.appList && this.appList.length > 0) {
this.appNameList = Array.from(new Set(this.appList.map(app => `${app.name} (${app.id})`)));
}
/* this.applications.subscribe(apps => {
this.appList = apps;
if (this.appList && this.appList.length > 0) {
this.appNameList = Array.from(new Set(this.appList.map(app => `${app.name} (${app.id})`)));
}
});
}); */

}

Expand Down
2 changes: 1 addition & 1 deletion builder/application-config/dashboard-config.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h4 translate>Details</h4>

<div class="form-group">
<label for="icon"><span>Icon</span></label>
<icon-selector id="icon" name="icon" [(value)]="newAppIcon"></icon-selector>
<icon-selector id="icon" name="icon" [(value)]="newAppIcon" ></icon-selector>
</div>
</form>
<button class="btn btn-primary" id="saveApplicationDetails" [disabled]="!editAppBuilderAppForm.form.valid"
Expand Down
37 changes: 27 additions & 10 deletions builder/application-config/dashboard-config.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { TemplateCatalogModalComponent } from "../template-catalog/template-cata
import { TemplateUpdateModalComponent } from "../template-catalog/template-update.component";
import { BinaryDescription, DeviceDescription } from "../template-catalog/template-catalog.model";
import { SettingsService } from './../../builder/settings/settings.service';
import { AlertMessageModalComponent } from "./../../builder/utils/alert-message-modal/alert-message-modal.component";


export interface DashboardConfig {
Expand Down Expand Up @@ -101,17 +102,33 @@ export class DashboardConfigComponent implements OnInit, OnDestroy {
async ngOnInit() {
this.isDashboardCatalogEnabled = await this.settngService.isDashboardCatalogEnabled();
}

private alertModalDialog(message: any): BsModalRef {
return this.modalService.show(AlertMessageModalComponent, { class: 'c8y-wizard', initialState: { message } });
}
async deleteDashboard(application, dashboards: DashboardConfig[], index: number) {
dashboards.splice(index, 1);
application.applicationBuilder.dashboards = [...dashboards];
await this.appService.update({
id: application.id,
applicationBuilder: application.applicationBuilder
} as any);

this.navigation.refresh();
// TODO?
// this.tabs.refresh();
const alertMessage = {
title: 'Delete Dashboard',
description: `You are about to delete this dashboard. This operation is irreversible. Do you want to proceed?`,
type: 'danger',
alertType: 'confirm', //info|confirm,
confirmPrimary: true //confirm Button is primary
}
const installDemoDialogRef = this.alertModalDialog(alertMessage);
await installDemoDialogRef.content.event.subscribe(async data => {
if(data && data.isConfirm) {
dashboards.splice(index, 1);
application.applicationBuilder.dashboards = [...dashboards];
await this.appService.update({
id: application.id,
applicationBuilder: application.applicationBuilder
} as any);

this.navigation.refresh();
// TODO?
// this.tabs.refresh();
}
});
}

async reorderDashboards(app, newDashboardsOrder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ <h4 class="text-uppercase" style="margin:0; letter-spacing: 0.15em;">Edit Dashbo

<div class="form-group">
<label for="icon"><span>Icon</span></label>
<icon-selector id="icon" name="icon" [(value)]="dashboardIcon"></icon-selector>
<icon-selector id="icon" name="icon" [(value)]="dashboardIcon" appendTo=".modal-content"></icon-selector>
</div>
</form>
</div>
Expand Down
Loading

0 comments on commit d11c078

Please sign in to comment.