fix: style regression issues

- add Roboto font face as dependency
- fix font size regression issue in select inputs
- fix scroll regression issue
- fix triggerName not disabled during reschedule
This commit is contained in:
Midhun A Darvin
2024-02-09 20:23:19 +05:30
committed by Fabio Formosa
parent bc0619a92a
commit 7cef35517b
17 changed files with 231 additions and 114 deletions

View File

@@ -26,7 +26,8 @@
"src/favicon.ico" "src/favicon.ico"
], ],
"styles": [ "styles": [
"src/styles.css" "src/styles.css",
"node_modules/roboto-fontface/css/roboto/roboto-fontface.css"
], ],
"scripts": [] "scripts": []
}, },

View File

@@ -32,6 +32,7 @@
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
"moment": "^2.29.1", "moment": "^2.29.1",
"net": "^1.0.2", "net": "^1.0.2",
"roboto-fontface": "^0.10.0",
"rxjs": "6.5.5", "rxjs": "6.5.5",
"sockjs-client": "^1.1.1", "sockjs-client": "^1.1.1",
"stompjs": "^2.3.3", "stompjs": "^2.3.3",
@@ -18246,6 +18247,11 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/roboto-fontface": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz",
"integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g=="
},
"node_modules/run-async": { "node_modules/run-async": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",

View File

@@ -35,6 +35,7 @@
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
"moment": "^2.29.1", "moment": "^2.29.1",
"net": "^1.0.2", "net": "^1.0.2",
"roboto-fontface": "^0.10.0",
"rxjs": "6.5.5", "rxjs": "6.5.5",
"sockjs-client": "^1.1.1", "sockjs-client": "^1.1.1",
"stompjs": "^2.3.3", "stompjs": "^2.3.3",
@@ -87,4 +88,4 @@
"<rootDir>/jest.setup.ts" "<rootDir>/jest.setup.ts"
] ]
} }
} }

View File

@@ -1,6 +1,6 @@
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFill> <div fxLayout="column" fxLayoutAlign="space-between stretch" fxFill>
<app-header fxFlex="0 0 auto"></app-header> <app-header fxFlex="0 0 auto"></app-header>
<div class="content" fxFlex="100" fxFill> <div class="content flex h-100">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
<app-footer fxFlex="0 0 auto"></app-footer> <app-footer fxFlex="0 0 auto"></app-footer>

View File

@@ -7,4 +7,5 @@
.content { .content {
padding: 20px; padding: 20px;
max-height: calc(100vh - 169px);
} }

View File

@@ -1,35 +1,61 @@
<mat-card fxFlex="1 1 auto"> <mat-card class="flex flex-1 max-h-100">
<mat-card-header fxLayout="row" fxLayoutAlign="space-between none" style="padding-right: 1em;"> <mat-card-header class="pb-16">
<mat-card-subtitle><b>JOB LOGS</b></mat-card-subtitle> <mat-card-subtitle ><b>JOB LOGS</b></mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content style="position: relative; height: calc(100% - 3em);"> <mat-card-content class="flex flex-1 overflow-y-auto">
<div *ngIf="!logs || logs.length == 0" fxLayout="row" fxFlexAlign="center stretch" style="text-align: center"> <div class="flex-1">
<div fxFill style="height: 100%;"> <div *ngIf="!logs || logs.length == 0" fxFill class="h-100" style="text-align: center;">
<img src="assets/image/logs.svg" alt="no logs" width="320" style="margin-top: 6em;" /> <img
</div> src="assets/image/logs.svg"
alt="no logs"
width="320"
style="margin-top: 6em" />
</div> </div>
<div id="logs" style="overflow-y: auto; overflow: auto;">
<div id="logs" fxFill style="height: 100%">
<div <div
*ngFor = "let log of logs; let first = first" fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start" fxLayoutGap="10px"> *ngFor="let log of logs; let first = first"
<div style="flex:1; max-width: 300px" > fxLayout="row"
<span [ngClass]="{'animate__animated animate__zoomIn zoomIn firstLog': first}"> [{{log.time|date:'medium'}}]</span> fxLayout.xs="column"
</div> fxLayoutAlign="start"
<div style="flex:1; max-width: 16px"> fxLayoutGap="10px">
<span [ngClass]="{'animated zoomIn firstLog': first}"> <div style="flex: 1; max-width: 300px">
<i class = "fas" [ngClass]="{'fa-check-circle green': log.type == 'INFO', <span
'fa-exclamation-triangle yellow': log.type == 'WARN', [ngClass]="{
'fa-times-circle red': log.type == 'ERROR'}"></i> 'animate__animated animate__zoomIn zoomIn firstLog': first
</span> }">
</div> [{{ log.time | date : 'medium' }}]</span
<div style="flex:1; max-width: 250px"> >
<span [ngClass]="{'animate__animated animate__zoomIn zoomIn firstLog': first}"> </div>
{{log.threadName}} <div style="flex: 1; max-width: 16px">
</span> <span [ngClass]="{ 'animated zoomIn firstLog': first }">
</div> <i
<div style="flex:1"> class="fas"
<span [ngClass]="{'animate__animated animate__zoomIn zoomIn firstLog': first}"> {{log.msg}}</span> [ngClass]="{
</div> 'fa-check-circle green': log.type == 'INFO',
'fa-exclamation-triangle yellow': log.type == 'WARN',
'fa-times-circle red': log.type == 'ERROR'
}"></i>
</span>
</div>
<div style="flex: 1; max-width: 250px">
<span
[ngClass]="{
'animate__animated animate__zoomIn zoomIn firstLog': first
}">
{{ log.threadName }}
</span>
</div>
<div style="flex: 1">
<span
[ngClass]="{
'animate__animated animate__zoomIn zoomIn firstLog': first
}">
{{ log.msg }}</span
>
</div>
</div> </div>
</div> </div>
</mat-card-content> </div>
</mat-card-content>
</mat-card> </mat-card>

View File

@@ -1,3 +1,9 @@
:host {
flex: 1;
display: flex;
flex-direction: column;
}
.red{ .red{
color: red; color: red;
} }

View File

@@ -13,13 +13,13 @@
<mat-card-subtitle style="margin: auto;"><b>SCHEDULER</b></mat-card-subtitle> <mat-card-subtitle style="margin: auto;"><b>SCHEDULER</b></mat-card-subtitle>
</div> </div>
<mat-divider [vertical]="true"></mat-divider> <mat-divider [vertical]="true"></mat-divider>
<div fxLayout="column"> <div fxLayout="column" class="justify-space-between">
<div><label>Name</label></div> <div><label>Name</label></div>
<div><span id="scheduler-name">{{scheduler?.name}}</span></div> <div><span id="scheduler-name" class="font-larger">{{scheduler?.name}}</span></div>
</div> </div>
<div fxLayout="column"> <div fxLayout="column" class="justify-space-between">
<div><label>Instance ID</label></div> <div><label>Instance ID</label></div>
<div><span id="scheduler-instance">{{scheduler?.instanceId}}</span></div> <div><span id="scheduler-instance" class="font-large">{{scheduler?.instanceId}}</span></div>
</div> </div>
</div> </div>
</mat-card-content> </mat-card-content>

View File

@@ -11,7 +11,6 @@ label{
font-size: smaller; font-size: smaller;
} }
#scheduler-name{ #scheduler-name, #scheduler-instance {
text-transform: capitalize; text-transform: capitalize;
font-size: larger;
} }

View File

@@ -35,7 +35,7 @@
> >
<mat-label>Job Class</mat-label> <mat-label>Job Class</mat-label>
<mat-select id="jobClass" name="jobClass" formControlName="jobClass"> <mat-select id="jobClass" name="jobClass" formControlName="jobClass">
<mat-option *ngFor="let job of jobs" [value]="job" style="font-size: 0.8em"> <mat-option *ngFor="let job of jobs" [value]="job">
{{job}} {{job}}
</mat-option> </mat-option>
</mat-select> </mat-select>
@@ -50,8 +50,7 @@
class="full-size-input" class="full-size-input"
> >
<mat-label>Misfire Instruction</mat-label> <mat-label>Misfire Instruction</mat-label>
<mat-select id="misfireInstruction" name="misfireInstruction" formControlName="misfireInstruction" <mat-select id="misfireInstruction" name="misfireInstruction" formControlName="misfireInstruction">
style="font-size: 0.8em">
<mat-option value="MISFIRE_INSTRUCTION_FIRE_NOW">FIRE NOW</mat-option> <mat-option value="MISFIRE_INSTRUCTION_FIRE_NOW">FIRE NOW</mat-option>
<mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT">RESCHEDULE NOW WITH <mat-option value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT">RESCHEDULE NOW WITH
EXISTING REPEAT COUNT EXISTING REPEAT COUNT
@@ -162,8 +161,7 @@
</div> </div>
<div fxFlex="1 1 auto" style="text-align: center" *ngIf="!simpleTriggerReactiveForm.enabled"> <div fxFlex="1 1 auto" style="text-align: center" *ngIf="!simpleTriggerReactiveForm.enabled">
<button mat-raised-button type="button" <button mat-raised-button type="button"
(click)="simpleTriggerReactiveForm.enable();simpleTriggerReactiveForm.controls['triggerName'].disable();">
(click)="simpleTriggerReactiveForm.enable()">
Reschedule Reschedule
</button> </button>
</div> </div>

View File

@@ -57,14 +57,43 @@ export class SimpleTriggerConfigComponent implements OnInit {
this.fetchJobs(); this.fetchJobs();
} }
private fetchJobs() { onSubmitTriggerConfig = () => {
this.jobService.fetchJobs().subscribe(jobs => this.jobs = jobs); console.log(this.existsATriggerInProgress());
const schedulerServiceCall = this.existsATriggerInProgress() ?
this.schedulerService.updateSimpleTriggerConfig : this.schedulerService.saveSimpleTriggerConfig;
const simpleTriggerCommand = this._fromReactiveFormToCommand();
schedulerServiceCall(simpleTriggerCommand)
.subscribe((retTrigger: SimpleTrigger) => {
console.log(retTrigger);
this.trigger = retTrigger;
this.simpleTriggerReactiveForm.setValue(this._fromTriggerToReactiveForm(retTrigger));
this.fetchedTriggers = true;
this.triggerInProgress = this.trigger.mayFireAgain;
if (schedulerServiceCall === this.schedulerService.saveSimpleTriggerConfig) {
this.onNewTrigger.emit(retTrigger);
}
this.closeTriggerForm();
}, error => {
console.error(error);
this.simpleTriggerReactiveForm.setValue(this._fromTriggerToReactiveForm(this.trigger));
});
} }
openTriggerForm() { openTriggerForm() {
this.simpleTriggerReactiveForm.enable(); this.simpleTriggerReactiveForm.enable();
} }
private fetchJobs() {
this.jobService.fetchJobs().subscribe(jobs => this.jobs = jobs);
}
private closeTriggerForm() { private closeTriggerForm() {
this.simpleTriggerReactiveForm.disable(); this.simpleTriggerReactiveForm.disable();
} }
@@ -97,31 +126,6 @@ export class SimpleTriggerConfigComponent implements OnInit {
this.closeTriggerForm(); this.closeTriggerForm();
}; };
onSubmitTriggerConfig = () => {
const schedulerServiceCall = this.existsATriggerInProgress() ?
this.schedulerService.updateSimpleTriggerConfig : this.schedulerService.saveSimpleTriggerConfig;
const simpleTriggerCommand = this._fromReactiveFormToCommand();
schedulerServiceCall(simpleTriggerCommand)
.subscribe((retTrigger: SimpleTrigger) => {
this.trigger = retTrigger;
this.simpleTriggerReactiveForm.setValue(this._fromTriggerToReactiveForm(retTrigger));
this.fetchedTriggers = true;
this.triggerInProgress = this.trigger.mayFireAgain;
if (schedulerServiceCall === this.schedulerService.saveSimpleTriggerConfig) {
this.onNewTrigger.emit(retTrigger);
}
this.closeTriggerForm();
}, error => {
this.simpleTriggerReactiveForm.setValue(this._fromTriggerToReactiveForm(this.trigger));
});
}
private _triggerPeriodValidator(control: AbstractControl): ValidationErrors | null { private _triggerPeriodValidator(control: AbstractControl): ValidationErrors | null {
const startDate = control.get('startDate'); const startDate = control.get('startDate');
const endDate = control.get('endDate'); const endDate = control.get('endDate');
@@ -160,7 +164,7 @@ export class SimpleTriggerConfigComponent implements OnInit {
}; };
private _fromReactiveFormToCommand = (): SimpleTriggerCommand => { private _fromReactiveFormToCommand = (): SimpleTriggerCommand => {
const reactiveFormValue = this.simpleTriggerReactiveForm.value; const reactiveFormValue = this.simpleTriggerReactiveForm.getRawValue();
const simpleTriggerCommand = new SimpleTriggerCommand(); const simpleTriggerCommand = new SimpleTriggerCommand();
simpleTriggerCommand.triggerName = reactiveFormValue.triggerName; simpleTriggerCommand.triggerName = reactiveFormValue.triggerName;
simpleTriggerCommand.jobClass = reactiveFormValue.jobClass; simpleTriggerCommand.jobClass = reactiveFormValue.jobClass;

View File

@@ -6,12 +6,14 @@ import {MatDialog, MatDialogRef} from '@angular/material/dialog';
@Component({ @Component({
template: ` template: `
<h3 mat-dialog-title>Coming Soon</h3> <div style="padding:16px">
<div mat-dialog-content> <h3 mat-dialog-title>Coming Soon</h3>
<p>This feature is in roadmap and it will come with the next releases</p> <div mat-dialog-content>
</div> <p>This feature is in roadmap and it will come with the next releases</p>
<div mat-dialog-actions> </div>
<button mat-button (click)="closeDialog()" style="padding: 0.5em;width: 5em;">Ok</button> <div mat-dialog-actions>
<button mat-button (click)="closeDialog()" style="padding: 0.5em;width: 5em;">Ok</button>
</div>
</div>`, </div>`,
}) })
// tslint:disable-next-line:component-class-suffix // tslint:disable-next-line:component-class-suffix

View File

@@ -1,3 +1,7 @@
:host {
flex: 1;
}
.content { .content {
width: 100%; width: 100%;
} }

View File

@@ -1,40 +1,40 @@
<div id="managerViewContainer" fxLayout="column" fxLayoutAlign="left stretch" fxLayoutGap="10px" fxFill> <div id="managerViewContainer" class="flex flex-column flex-1 gap-6 h-100">
<div id="schedulerBarContainer">
<div id="schedulerBarContainer" fxLayout="column" fxLayoutAlign="left stretch">
<qrzmng-scheduler-control></qrzmng-scheduler-control> <qrzmng-scheduler-control></qrzmng-scheduler-control>
</div> </div>
<div fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="center stretch" fxFlex="1 1 auto"> <div id="manager-content-container" class="flex flex-row flex-1 gap-6">
<div class="flex-1" style="max-width: 250px">
<div fxFlex="0 0 250px">
<div fxLayout="row" fxLayoutAlign="stretch" fxFill> <div fxLayout="row" fxLayoutAlign="stretch" fxFill>
<qrzmng-trigger-list <qrzmng-trigger-list
(onNewTriggerClicked)="onNewTriggerRequested()" (onNewTriggerClicked)="onNewTriggerRequested()"
[openedNewTriggerForm]="newTriggerFormOpened" [openedNewTriggerForm]="newTriggerFormOpened"
(onSelectedTrigger)="setSelectedTrigger($event)" (onSelectedTrigger)="setSelectedTrigger($event)"
fxFill></qrzmng-trigger-list> fxFill></qrzmng-trigger-list>
</div> </div>
</div> </div>
<div fxFlex="1 1 350px"> <div class="flex-1" style="max-width: 350px">
<div fxLayout="row" fxFill> <div fxLayout="row" fxFill>
<div fxLayout="column" fxFill> <div fxLayout="column" fxFill>
<qrzmng-simple-trigger-config fxFill <qrzmng-simple-trigger-config
fxFill
[triggerKey]="selectedTriggerKey" [triggerKey]="selectedTriggerKey"
(onNewTrigger)="onNewTriggerCreated($event)"> (onNewTrigger)="onNewTriggerCreated($event)">
</qrzmng-simple-trigger-config> </qrzmng-simple-trigger-config>
</div> </div>
</div> </div>
</div> </div>
<div fxFlex="1 1 auto" style="margin-left: 20px;"> <div class="flex-1">
<div fxFlex="1 1 auto" fxLayout="column" fxLayoutAlign="start stretch" fxLayoutGap="6px"> <div class="h-100 min-h-100 flex flex-column gap-6">
<progress-panel></progress-panel> <div class="flex flex-column" >
<logs-panel fxFlex="1 1 auto" fxFill></logs-panel> <progress-panel class="flex-1"></progress-panel>
</div> </div>
<div class="flex flex-column flex-1" style="max-height: calc(100% - 136px); min-height: calc(100% - 210px);">
<logs-panel class="flex flex-1 h-100 max-h-100"></logs-panel>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1 +1,10 @@
:host {
display: flex;
flex-direction: column;
flex: 1;
}
#manager-content-container {
height: calc(100% - 80px);
max-height: calc(100% - 80px);
}

View File

@@ -1,12 +1,9 @@
import {Component, OnInit, ViewChild} from '@angular/core'; import { Component, OnInit, ViewChild } from '@angular/core';
import { import { ConfigService, UserService } from '../../services';
ConfigService, import { SimpleTrigger } from '../../model/simple-trigger.model';
UserService import { TriggerKey } from '../../model/triggerKey.model';
} from '../../services'; import { SimpleTriggerConfigComponent } from '../../components/simple-trigger-config';
import {SimpleTrigger} from '../../model/simple-trigger.model'; import { TriggerListComponent } from '../../components';
import {TriggerKey} from '../../model/triggerKey.model';
import {SimpleTriggerConfigComponent} from '../../components/simple-trigger-config';
import {TriggerListComponent} from '../../components';
@Component({ @Component({
selector: 'manager', selector: 'manager',
@@ -14,7 +11,6 @@ import {TriggerListComponent} from '../../components';
styleUrls: ['./manager.component.scss'] styleUrls: ['./manager.component.scss']
}) })
export class ManagerComponent implements OnInit { export class ManagerComponent implements OnInit {
@ViewChild(SimpleTriggerConfigComponent) @ViewChild(SimpleTriggerConfigComponent)
private triggerConfigComponent!: SimpleTriggerConfigComponent; private triggerConfigComponent!: SimpleTriggerConfigComponent;
@@ -25,11 +21,9 @@ export class ManagerComponent implements OnInit {
selectedTriggerKey: TriggerKey; selectedTriggerKey: TriggerKey;
constructor( constructor() {}
) { }
ngOnInit() { ngOnInit() {}
}
onNewTriggerRequested() { onNewTriggerRequested() {
this.triggerConfigComponent.openTriggerForm(); this.triggerConfigComponent.openTriggerForm();
@@ -42,5 +36,4 @@ export class ManagerComponent implements OnInit {
setSelectedTrigger(triggerKey: TriggerKey) { setSelectedTrigger(triggerKey: TriggerKey) {
this.selectedTriggerKey = triggerKey; this.selectedTriggerKey = triggerKey;
} }
} }

View File

@@ -12,3 +12,70 @@ body {
flex:1; flex:1;
background-color: #f1f1f1; background-color: #f1f1f1;
} }
/**
TODO: Remove the below utility classes once tailwind is integrated.
*/
.font-large {
font-size: large;
}
.font-larger {
font-size: larger;
}
.justify-space-between {
justify-content: space-between;
}
.flex {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-column {
flex-direction: column;
}
.flex-1 {
flex: 1;
}
.h-100 {
height: 100%;
}
.min-h-100 {
min-height: 100%;
}
.max-h-100 {
max-height: 100%;
}
.w-100 {
width: 100%;
}
.gap-6 {
gap: 6px;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-y-auto {
overflow-y: auto;
}
.pb-16 {
padding-bottom: 16px !important;
}
.mdc-list-item__primary-text {
font-size: 0.8em !important;
}