-
Notifications
You must be signed in to change notification settings - Fork 2
NAB-380 #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/application_management
Are you sure you want to change the base?
NAB-380 #28
Changes from all commits
020ecfd
77a3d63
e5daa2f
3c41e30
68377b5
c173387
e6a40a7
130ba38
e5dda5a
0eef678
3a8f3d5
45d697f
df6d620
e59855a
7a02934
4ad5107
3c4b707
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,105 +1,98 @@ | ||
| <div class="app-container"> | ||
| <mat-sidenav-container class="app-mat-sidenav-container" fxLayout="column"> | ||
| <mat-sidenav fxFlex class="app-mat-viewnav" mode="side" disableClose="true" opened> | ||
| <div fxFlex fxLayout="column"> | ||
| <a [href]="config.services.urls.netgrif" target="_blank" class="logo"> | ||
| <img src="../assets/netgrif_logo.svg" alt="Netgrif logo" class="main-toolbar-logo"> | ||
| </a> | ||
| <div fxLayout="column" fxLayoutAlign="start center" fxFlex="100" | ||
| style="padding-top: 4px; padding-bottom: 4px; overflow-y: hidden;"> | ||
| <mat-action-list class="menu-items"> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| (click)="openApplicationDialog()" | ||
| matTooltip="Application" matTooltipPosition="right" | ||
| style="margin-bottom: 4px;"> | ||
| <mat-icon>app_registration</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| <div fxFlex style="overflow-y: auto;"> | ||
| <mat-action-list class="menu-items"> | ||
| @for (process of applicationService.models; track process[0]) { | ||
| <!--TODO trieda active-process nefunguje pri prvotnej inicializácii--> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| [class.active-process]="process[0] === modelService.model.id" | ||
| (click)="switchToProcess(process[0])" | ||
| [matTooltip]="'['+process[0]+'] '+process[1].title.value" | ||
| matTooltipPosition="right"> | ||
| <mat-icon>{{ process[1].icon }}</mat-icon> | ||
| </mat-list-item> | ||
| } | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| (click)="applicationService.addNewEmptyModel()" | ||
| matTooltip="Add new process" matTooltipPosition="right" | ||
| style="margin: 4px 0;"> | ||
| <mat-icon>add</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| </div> | ||
| <div style="overflow-y: hidden;"> | ||
| <mat-divider style="width: 80%;margin: auto;padding: 4px 0;"></mat-divider> | ||
| <mat-action-list class="menu-items"> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.demo.step}}" | ||
| title="{{tutorial.demo.title}}" | ||
| text="{{tutorial.demo.text}}" | ||
| stepPosition="{{tutorial.demo.position}}" | ||
| (click)="openInTab(config.services.urls.engine)" | ||
| matTooltip="Netgrif Demo" matTooltipPosition="right"> | ||
| <mat-icon>play_arrow</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.youtube.step}}" | ||
| title="{{tutorial.youtube.title}}" | ||
| text="{{tutorial.youtube.text}}" | ||
| stepPosition="{{tutorial.youtube.position}}" | ||
| (click)="openInTab(config.services.urls.youtube)" | ||
| matTooltip="Youtube Channel" matTooltipPosition="right"> | ||
| <mat-icon svgIcon="youtube"></mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.github.step}}" | ||
| title="{{tutorial.github.title}}" | ||
| text="{{tutorial.github.text}}" | ||
| stepPosition="{{tutorial.github.position}}" | ||
| (click)="openInTab(config.services.urls.github)" | ||
| matTooltip="Github" matTooltipPosition="right"> | ||
| <mat-icon svgIcon="github">device_hub</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.mortgage.step}}" | ||
| title="{{tutorial.mortgage.title}}" | ||
| text="{{tutorial.mortgage.text}}" | ||
| stepPosition="{{tutorial.mortgage.position}}" | ||
| (click)="addMortgage()" | ||
| matTooltip="Mortgage demo" matTooltipPosition="right"> | ||
| <mat-icon>device_hub</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| <mat-divider style="width: 80%;margin: auto;padding: 4px 0;"></mat-divider> | ||
| <mat-action-list class="menu-items"> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.bug.step}}" | ||
| title="{{tutorial.bug.title}}" | ||
| text="{{tutorial.bug.text}}" | ||
| stepPosition="{{tutorial.bug.position}}" | ||
| (done)="tutorial.onClose()" | ||
| (click)="openInTab(config.services.urls.issues)" | ||
| matTooltip="Report a bug" matTooltipPosition="right"> | ||
| <mat-icon>bug_report</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| (click)="help()" | ||
| matTooltip="Help" matTooltipPosition="right"> | ||
| <mat-icon>help</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <mat-sidenav-container class="app-mat-sidenav-container"> | ||
| <mat-sidenav class="app-mat-viewnav" mode="side" disableClose="true" opened> | ||
| <a [href]="config.services.urls.netgrif" target="_blank" class="logo"> | ||
| <img src="../assets/netgrif_logo.svg" alt="Netgrif logo" class="main-toolbar-logo"> | ||
| </a> | ||
| <mat-action-list class="menu-items"> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.demo.step}}" | ||
| title="{{tutorial.demo.title}}" | ||
| text="{{tutorial.demo.text}}" | ||
| stepPosition="{{tutorial.demo.position}}" | ||
| (click)="openInTab(config.services.urls.engine)" | ||
| matTooltip="Netgrif Demo" matTooltipPosition="right"> | ||
| <mat-icon>play_arrow</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.youtube.step}}" | ||
| title="{{tutorial.youtube.title}}" | ||
| text="{{tutorial.youtube.text}}" | ||
| stepPosition="{{tutorial.youtube.position}}" | ||
| (click)="openInTab(config.services.urls.youtube)" | ||
| matTooltip="Youtube Channel" matTooltipPosition="right"> | ||
| <mat-icon svgIcon="youtube"></mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.github.step}}" | ||
| title="{{tutorial.github.title}}" | ||
| text="{{tutorial.github.text}}" | ||
| stepPosition="{{tutorial.github.position}}" | ||
| (click)="openInTab(config.services.urls.github)" | ||
| matTooltip="Github" matTooltipPosition="right"> | ||
| <mat-icon svgIcon="github">device_hub</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.mortgage.step}}" | ||
| title="{{tutorial.mortgage.title}}" | ||
| text="{{tutorial.mortgage.text}}" | ||
| stepPosition="{{tutorial.mortgage.position}}" | ||
| (click)="addMortgage()" | ||
| matTooltip="Mortgage demo" matTooltipPosition="right"> | ||
| <mat-icon>device_hub</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| <mat-action-list class="app-viewnaw-bottom-list menu-items"> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| joyrideStep="{{tutorial.bug.step}}" | ||
| title="{{tutorial.bug.title}}" | ||
| text="{{tutorial.bug.text}}" | ||
| stepPosition="{{tutorial.bug.position}}" | ||
| (done)="tutorial.onClose()" | ||
| (click)="openInTab(config.services.urls.issues)" | ||
| matTooltip="Report a bug" matTooltipPosition="right"> | ||
| <mat-icon>bug_report</mat-icon> | ||
| </mat-list-item> | ||
| <mat-list-item class="field-list-mat-list-item" | ||
| (click)="help()" | ||
| matTooltip="Help" matTooltipPosition="right"> | ||
| <mat-icon>help</mat-icon> | ||
| </mat-list-item> | ||
| </mat-action-list> | ||
| </mat-sidenav> | ||
| <joyrideStep joyrideStep="{{tutorial.welcome.step}}" stepPosition="{{tutorial.welcome.position}}" | ||
| title="{{tutorial.welcome.title}}" text="{{tutorial.welcome.text}}" | ||
| (next)="tutorial.welcome.onNext()"></joyrideStep> | ||
| <mat-tab-group mat-stretch-tabs="false" mat-align-tabs="start" animationDuration="0ms" class="app-tabs" | ||
| [selectedIndex]="activeProcessIndex()" | ||
| (selectedTabChange)="changeTab($event)"> | ||
| <mat-tab disabled="true"> | ||
| <ng-template mat-tab-label> | ||
| <button mat-icon-button (click)="openApplicationDialog()"> | ||
| <mat-icon class="tab-icon" matTooltip="Application" style="color: rgba(0,0,0,0.6)!important;"> | ||
| app_registration | ||
| </mat-icon> | ||
| </button> | ||
| </ng-template> | ||
| </mat-tab> | ||
| @for (process of applicationService.models; track process[0]) { | ||
| <mat-tab label="{{process[0]}}"> | ||
| <ng-template mat-tab-label> | ||
| @if (process[1].icon) { | ||
| <mat-icon class="tab-icon">{{ process[1].icon }}</mat-icon> | ||
| } | ||
| {{ process[1].title.value }} [{{ process[1].id }}] | ||
| </ng-template> | ||
| </mat-tab> | ||
|
Comment on lines
+78
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find the applicationService and how models is defined
fd "\.ts$" | xargs rg -l "applicationService|class.*Service" | head -20Repository: netgrif/application-builder Length of output: 1088 🏁 Script executed: #!/bin/bash
# Check the switchActiveModel method signature and its usage
rg -n "switchActiveModel" --type ts -B 2 -A 5Repository: netgrif/application-builder Length of output: 3668 🏁 Script executed: #!/bin/bash
# Find where applicationService.models is used and how it's structured
rg -n "applicationService\.models" --type ts -B 2 -A 2Repository: netgrif/application-builder Length of output: 2712 🏁 Script executed: #!/bin/bash
# Find the models getter in application.service.ts
rg -n "get models" --type ts -A 15 src/app/project-builder/application.service.tsRepository: netgrif/application-builder Length of output: 486 🏁 Script executed: #!/bin/bash
# Also check how models is used in the component - does it iterate over entries?
cat -n src/app/app.component.html | sed -n '75,95p'Repository: netgrif/application-builder Length of output: 1101 Tab label mismatch breaks tab switching—textLabel does not match model ID format.
In Fix: Use 🤖 Prompt for AI Agents |
||
| } | ||
| <mat-tab disabled="true"> | ||
| <ng-template mat-tab-label> | ||
| <button mat-icon-button (click)="addNewEmptyModel()"> | ||
| <mat-icon>add</mat-icon> | ||
| </button> | ||
| </ng-template> | ||
| </mat-tab> | ||
| </mat-tab-group> | ||
| <router-outlet></router-outlet> | ||
| </mat-sidenav-container> | ||
| </div> | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,25 +1,23 @@ | ||||||||||||||||||||||
| import {AfterViewInit, Component, HostListener} from '@angular/core'; | ||||||||||||||||||||||
| import {AfterViewInit, Component, HostListener, OnInit} from '@angular/core'; | ||||||||||||||||||||||
| import {MatDialog} from '@angular/material/dialog'; | ||||||||||||||||||||||
| import {Router} from '@angular/router'; | ||||||||||||||||||||||
| import {NetgrifApplicationEngine} from '@netgrif/components-core/'; | ||||||||||||||||||||||
| import {JoyrideService} from 'ngx-joyride'; | ||||||||||||||||||||||
| import {AppBuilderConfigurationService} from './app-builder-configuration.service'; | ||||||||||||||||||||||
| import {DialogApplicationEditComponent} from './dialogs/dialog-application-edit/dialog-application-edit.component'; | ||||||||||||||||||||||
| import {DialogConfirmComponent} from './dialogs/dialog-confirm/dialog-confirm.component'; | ||||||||||||||||||||||
| import {DialogIntroComponent} from './dialogs/dialog-intro/dialog-intro.component'; | ||||||||||||||||||||||
| import {ModelImportService} from './modeler/model-import-service'; | ||||||||||||||||||||||
| import {MortgageService} from './modeler/mortgage.service'; | ||||||||||||||||||||||
| import {ModelService} from './modeler/services/model/model.service'; | ||||||||||||||||||||||
| import {ApplicationService} from './project-builder/application.service'; | ||||||||||||||||||||||
| import {DatabaseStorageService} from './project-builder/database-storage.service'; | ||||||||||||||||||||||
| import {TutorialService} from './tutorial/tutorial-service'; | ||||||||||||||||||||||
| import {MatTabChangeEvent} from '@angular/material/tabs'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Component({ | ||||||||||||||||||||||
| selector: 'nab-root', | ||||||||||||||||||||||
| templateUrl: './app.component.html', | ||||||||||||||||||||||
| styleUrls: ['./app.component.scss'], | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| export class AppComponent implements AfterViewInit { | ||||||||||||||||||||||
| export class AppComponent implements OnInit, AfterViewInit { | ||||||||||||||||||||||
| title = 'Netgrif Application Builder'; | ||||||||||||||||||||||
| config: NetgrifApplicationEngine; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -30,46 +28,33 @@ export class AppComponent implements AfterViewInit { | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| constructor( | ||||||||||||||||||||||
| config: AppBuilderConfigurationService, | ||||||||||||||||||||||
| private router: Router, | ||||||||||||||||||||||
| private matDialog: MatDialog, | ||||||||||||||||||||||
| private readonly joyrideService: JoyrideService, | ||||||||||||||||||||||
| private _mortgageService: MortgageService, | ||||||||||||||||||||||
| private tutorialService: TutorialService, | ||||||||||||||||||||||
| private importService: ModelImportService, | ||||||||||||||||||||||
| private db: DatabaseStorageService, | ||||||||||||||||||||||
| public modelService: ModelService, | ||||||||||||||||||||||
| public applicationService: ApplicationService, | ||||||||||||||||||||||
| ) { | ||||||||||||||||||||||
| this.config = config.get(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ngOnInit(): void { | ||||||||||||||||||||||
| this.applicationService.createApplication(); | ||||||||||||||||||||||
| this.applicationService.switchToFirst(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ngAfterViewInit(): void { | ||||||||||||||||||||||
| // TODO: NAB-326 https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API | ||||||||||||||||||||||
| this.matDialog.open(DialogIntroComponent, { | ||||||||||||||||||||||
| width: '40%', | ||||||||||||||||||||||
| panelClass: 'dialog-width-40', | ||||||||||||||||||||||
| disableClose: true, | ||||||||||||||||||||||
| data: this.db.getAllApplications(), | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /*const oldModel = localStorage.getItem(ModelerConfig.LOCALSTORAGE.DRAFT_MODEL.KEY); | ||||||||||||||||||||||
| if (!oldModel) { | ||||||||||||||||||||||
| return; | ||||||||||||||||||||||
| const apps = this.db.getAllApplications(); | ||||||||||||||||||||||
| if (apps && apps.length > 0) { | ||||||||||||||||||||||
| this.matDialog.open(DialogIntroComponent, { | ||||||||||||||||||||||
| width: '40%', | ||||||||||||||||||||||
| panelClass: 'dialog-width-40', | ||||||||||||||||||||||
| disableClose: true, | ||||||||||||||||||||||
| data: apps, | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| const dialogRef = this.matDialog.open(DialogLocalStorageModelComponent, { | ||||||||||||||||||||||
| data: { | ||||||||||||||||||||||
| id: localStorage.getItem(ModelerConfig.LOCALSTORAGE.DRAFT_MODEL.ID), | ||||||||||||||||||||||
| timestamp: localStorage.getItem(ModelerConfig.LOCALSTORAGE.DRAFT_MODEL.TIMESTAMP), | ||||||||||||||||||||||
| title: localStorage.getItem(ModelerConfig.LOCALSTORAGE.DRAFT_MODEL.TITLE), | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| dialogRef.afterClosed().subscribe(result => { | ||||||||||||||||||||||
| if (result === true) { | ||||||||||||||||||||||
| this.importService.importFromXml(oldModel); | ||||||||||||||||||||||
| } else if (result === false) { | ||||||||||||||||||||||
| localStorage.clear(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| });*/ | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| openApplicationDialog() { | ||||||||||||||||||||||
|
|
@@ -80,14 +65,7 @@ export class AppComponent implements AfterViewInit { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| addMortgage() { | ||||||||||||||||||||||
| const dialogRef = this.matDialog.open(DialogConfirmComponent); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| dialogRef.afterClosed().subscribe(result => { | ||||||||||||||||||||||
| if (result === true) { | ||||||||||||||||||||||
| this._mortgageService.loadModel(); | ||||||||||||||||||||||
| this.router.navigate(['/modeler']); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| this._mortgageService.loadModel(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| help() { | ||||||||||||||||||||||
|
|
@@ -105,8 +83,20 @@ export class AppComponent implements AfterViewInit { | |||||||||||||||||||||
| window.open(url, '_blank'); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| switchToProcess(processId: string) { | ||||||||||||||||||||||
| switchToProcess(processId: string): void { | ||||||||||||||||||||||
| this.applicationService.switchActiveModel(processId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| changeTab(tabEvent: MatTabChangeEvent): void { | ||||||||||||||||||||||
| this.switchToProcess(tabEvent.tab.textLabel); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+90
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Tab switching relies on The Consider using the tab index (minus offsets for disabled tabs) to look up the model directly. Alternative approach using index changeTab(tabEvent: MatTabChangeEvent): void {
- this.switchToProcess(tabEvent.tab.textLabel);
+ const modelIndex = tabEvent.index - 1; // Account for first disabled tab
+ const models = Array.from(this.applicationService.models.values());
+ if (modelIndex >= 0 && modelIndex < models.length) {
+ this.switchToProcess(models[modelIndex].id);
+ }
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| addNewEmptyModel(): void { | ||||||||||||||||||||||
| const model = this.applicationService.addNewEmptyModel(); | ||||||||||||||||||||||
| this.applicationService.switchActiveModel(model.id); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| activeProcessIndex(): number { | ||||||||||||||||||||||
| return this.applicationService.modelList.indexOf(this.applicationService.getActiveModel()) + 1; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 480
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 102
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 203
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 174
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 5103
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 53
🏁 Script executed:
ls -la pnpm-lock.yaml 2>&1Repository: netgrif/application-builder
Length of output: 132
🏁 Script executed:
Repository: netgrif/application-builder
Length of output: 53
🏁 Script executed:
git log --all --oneline | head -5Repository: netgrif/application-builder
Length of output: 151
🏁 Script executed:
git show --stat 3c4b707 | head -30Repository: netgrif/application-builder
Length of output: 1620
Remove
pnpm-lock.yamlfrom.gitignoreto ensure reproducible builds.This project uses pnpm (evidenced by
pnpm-workspace.yaml), makingpnpm-lock.yamlthe lock file that should be committed to ensure all developers and CI environments use identical dependency versions. Ignoring it leads to non-reproducible builds and "works on my machine" issues.The
package-lock.jsonentry is appropriate to ignore since the project uses pnpm, not npm.🤖 Prompt for AI Agents