From 2e4dcdedb9b5a1bc630387fbf479406c3f856350 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Thu, 28 Nov 2024 22:04:41 -0300 Subject: [PATCH 01/30] [desktop]: Encapsulate p-checkbox into neb-checkbox --- .../app/alignment/alignment.component.html | 7 +- desktop/src/app/app.module.ts | 2 + desktop/src/app/atlas/atlas.component.html | 16 +- .../calibration/calibration.component.html | 8 +- desktop/src/app/camera/camera.component.html | 7 +- .../filterwheel/filterwheel.component.html | 7 +- .../app/filterwheel/filterwheel.component.ts | 5 +- .../src/app/framing/framing.component.html | 7 +- desktop/src/app/image/image.component.html | 73 ++++---- .../app/sequencer/sequencer.component.html | 157 +++++++----------- .../src/app/settings/settings.component.html | 7 +- desktop/src/shared/components/checkbox.ts | 35 ++++ 12 files changed, 158 insertions(+), 173 deletions(-) create mode 100644 desktop/src/shared/components/checkbox.ts diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 8ec67c881..b5c6831ac 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -115,11 +115,10 @@
- + [(value)]="tppaRequest.stopTrackingWhenDone" + (valueChange)="savePreference()" />
diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 45af10547..b22a76490 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -100,6 +100,7 @@ import { MountComponent } from './mount/mount.component' import { RotatorComponent } from './rotator/rotator.component' import { SequencerComponent } from './sequencer/sequencer.component' import { SettingsComponent } from './settings/settings.component' +import { CheckboxComponent } from '../shared/components/checkbox' @NgModule({ declarations: [ @@ -114,6 +115,7 @@ import { SettingsComponent } from './settings/settings.component' CameraComponent, CameraInfoComponent, CameraExposureComponent, + CheckboxComponent, ConfirmDialogComponent, CrossHairComponent, DeviceChooserComponent, diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index 93a870912..1854c2c9a 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -852,12 +852,11 @@ @let groups = 'SATELLITE_GROUP_TYPE' | dropdownOptions; @for (group of groups; track $index) { - + [noWrap]="true" /> }
@@ -886,10 +885,9 @@ [style]="{ width: '80vw' }">
-
diff --git a/desktop/src/app/calibration/calibration.component.html b/desktop/src/app/calibration/calibration.component.html index 53a446168..6919daed6 100644 --- a/desktop/src/app/calibration/calibration.component.html +++ b/desktop/src/app/calibration/calibration.component.html @@ -52,11 +52,9 @@
- +
{{ item.type }}
diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index 407d6f879..a095cd6bb 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -635,12 +635,11 @@ (ngModelChange)="savePreference()" />
- + [(value)]="liveStacking.request.useCalibrationGroup" + (valueChange)="savePreference()" />
-
diff --git a/desktop/src/app/filterwheel/filterwheel.component.ts b/desktop/src/app/filterwheel/filterwheel.component.ts index a47d6b5ab..cc0e3e527 100644 --- a/desktop/src/app/filterwheel/filterwheel.component.ts +++ b/desktop/src/app/filterwheel/filterwheel.component.ts @@ -1,7 +1,6 @@ import { AfterContentInit, Component, HostListener, NgZone, OnDestroy, inject } from '@angular/core' import { ActivatedRoute } from '@angular/router' import hotkeys from 'hotkeys-js' -import { CheckboxChangeEvent } from 'primeng/checkbox' import { Subject, Subscription, debounceTime } from 'rxjs' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' @@ -312,8 +311,8 @@ export class FilterWheelComponent implements AfterContentInit, OnDestroy, Tickab } } - protected shutterToggled(filter: Filter, event: CheckboxChangeEvent) { - this.filters.forEach((e) => (e.dark = !!event.checked && e === filter)) + protected shutterToggled(filter: Filter, checked: boolean) { + this.filters.forEach((e) => (e.dark = checked && e === filter)) this.preference.shutterPosition = this.filters.find((e) => e.dark)?.position ?? 0 this.savePreference() } diff --git a/desktop/src/app/framing/framing.component.html b/desktop/src/app/framing/framing.component.html index 2dbc23b9c..bebbe3365 100644 --- a/desktop/src/app/framing/framing.component.html +++ b/desktop/src/app/framing/framing.component.html @@ -181,11 +181,10 @@ spinnableNumber /> - + [(value)]="preference.updateFovOnChange" + (valueChange)="savePreference()" />
diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index e63a2dc8c..251813ccf 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -163,22 +163,19 @@
Stars & DSOs - +
-
@@ -196,12 +193,10 @@
Minor Planets - +
@@ -224,12 +219,11 @@
-
@if (annotation.request.minorPlanetsMagLimit >= 20 || annotation.request.includeMinorPlanetsWithoutMagnitude) { @@ -307,10 +301,9 @@
- + [(value)]="annotation.displayOnlyFiltered" />
- + [(value)]="solver.request.blind" + (valueChange)="savePreference()" />
@@ -1390,10 +1382,7 @@ [style.border-color]="item.color" (click)="selectFOV(item)">
- +
- Transformed - +
@@ -1679,15 +1668,13 @@ [style]="{ width: 'min-content', minWidth: '338px' }">
- -
diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index a5744b8b9..142285794 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -189,11 +189,10 @@ tooltipPosition="bottom" size="small" (onClick)="duplicateSequence(sequence, i)" /> - + [(value)]="sequence.enabled" + (valueChange)="savePreference()" />
@@ -351,21 +350,18 @@ pTooltip="Dither" tooltipPosition="bottom"> - + [(value)]="plan.dither.enabled" + (valueChange)="savePreference()" />
- + [(value)]="plan.dither.raOnly" + (valueChange)="savePreference()" /> - + [(value)]="plan.autoFocus.enabled" + (valueChange)="savePreference()" />
- - + + [(value)]="plan.autoFocus.onFilterChange" + (valueChange)="savePreference()" />
- + [(value)]="plan.autoFocus.afterElapsedTimeEnabled" + (valueChange)="savePreference()" />
- + [(value)]="plan.autoFocus.afterExposuresEnabled" + (valueChange)="savePreference()" />
- + [(value)]="plan.autoFocus.afterHFDIncreaseEnabled" + (valueChange)="savePreference()" />
- + [(value)]="plan.autoFocus.afterTemperatureChangeEnabled" + (valueChange)="savePreference()" /> - + [(value)]="plan.liveStacking.enabled" + (valueChange)="savePreference()" />
@@ -543,12 +529,11 @@ [(ngModel)]="plan.liveStacking.use32Bits" (ngModelChange)="savePreference()" />
- + [(value)]="plan.liveStacking.useCalibrationGroup" + (valueChange)="savePreference()" />
- + [(value)]="property.properties.EXPOSURE_TIME" />
- + [(value)]="property.properties.EXPOSURE_AMOUNT" />
- + [(value)]="property.properties.EXPOSURE_DELAY" />
- + [(value)]="property.properties.FRAME_TYPE" />
- + [(value)]="property.properties.X" />
- + [(value)]="property.properties.Y" />
- + [(value)]="property.properties.WIDTH" />
- + [(value)]="property.properties.HEIGHT" />
- + [(value)]="property.properties.BIN" />
- + [(value)]="property.properties.FRAME_FORMAT" />
- + [(value)]="property.properties.GAIN" />
- + [(value)]="property.properties.OFFSET" />
- + [(value)]="property.properties.CALIBRATION_GROUP" />
- + [(value)]="property.properties.STACKING_GROUP" />
diff --git a/desktop/src/app/settings/settings.component.html b/desktop/src/app/settings/settings.component.html index 63b7ac5d2..56645d631 100644 --- a/desktop/src/app/settings/settings.component.html +++ b/desktop/src/app/settings/settings.component.html @@ -4,11 +4,10 @@ *ngIf="tab === 'GENERAL'">
- + [(value)]="preference.checkVersion" + (valueChange)="savePreference()" />
diff --git a/desktop/src/shared/components/checkbox.ts b/desktop/src/shared/components/checkbox.ts new file mode 100644 index 000000000..0c3899fcb --- /dev/null +++ b/desktop/src/shared/components/checkbox.ts @@ -0,0 +1,35 @@ +import { Component, input, model, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-checkbox', + template: ` + + `, + styles: ` + neb-checkbox { + .vertical { + flex-direction: column; + gap: 4px; + + .p-checkbox-label { + margin-left: 0px; + } + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class CheckboxComponent { + readonly label = input() + readonly value = model(false) + readonly disabled = input(false) + readonly noWrap = input(false) + readonly vertical = input(false) +} From 196fad0078fd115c2c638d9917ecd668a0277a82 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 29 Nov 2024 00:06:53 -0300 Subject: [PATCH 02/30] [desktop]: Encapsulate p-inputNumber into neb-input-number --- .../app/alignment/alignment.component.html | 34 +- desktop/src/app/app.module.ts | 10 +- desktop/src/app/atlas/atlas.component.html | 148 ++--- .../app/autofocus/autofocus.component.html | 98 ++-- .../calculator/formula/formula.component.html | 36 +- desktop/src/app/camera/camera.component.html | 290 ++++------ .../app/camera/exposure-time.component.html | 23 +- .../filterwheel/filterwheel.component.html | 20 +- .../flat-wizard/flat-wizard.component.html | 92 +--- .../src/app/focuser/focuser.component.html | 55 +- .../src/app/framing/framing.component.html | 127 ++--- desktop/src/app/guider/guider.component.html | 169 ++---- desktop/src/app/home/home.component.html | 20 +- desktop/src/app/image/image.component.html | 514 ++++++------------ desktop/src/app/mount/mount.component.html | 17 +- .../src/app/rotator/rotator.component.html | 38 +- .../app/sequencer/sequencer.component.html | 154 ++---- .../src/app/settings/settings.component.html | 111 ++-- .../{checkbox.ts => checkbox.component.ts} | 0 .../components/input-number.component.ts | 56 ++ .../components/location/location.dialog.html | 80 +-- desktop/src/shared/types/platesolver.types.ts | 2 +- desktop/src/styles.scss | 15 +- 23 files changed, 725 insertions(+), 1384 deletions(-) rename desktop/src/shared/components/{checkbox.ts => checkbox.component.ts} (100%) create mode 100644 desktop/src/shared/components/input-number.component.ts diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index b5c6831ac..54cf3a294 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -75,17 +75,12 @@
- - - - +
@@ -189,17 +184,12 @@
- - - - +
- - - - - - - - + +
- - - - +
@@ -795,40 +769,20 @@
- - - - +
- - - - +
@@ -920,34 +874,22 @@
- - - - - - - - + +
- - - - +
- - - - +
@@ -126,21 +116,13 @@
- - - - +
@@ -158,32 +140,22 @@
- - - - +
- - - - +
diff --git a/desktop/src/app/calculator/formula/formula.component.html b/desktop/src/app/calculator/formula/formula.component.html index d3115cbd5..195f31e38 100644 --- a/desktop/src/app/calculator/formula/formula.component.html +++ b/desktop/src/app/calculator/formula/formula.component.html @@ -11,20 +11,12 @@ {{ item.prefix }}
- - - - +
{{ item.suffix }} @@ -35,17 +27,11 @@

=

{{ formula.result.prefix }} - - - - + {{ formula.result.suffix }}
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -341,37 +278,24 @@
- - + [(value)]="request.binX" + (valueChange)="savePreference()" /> +
- - - - +
@@ -388,38 +312,22 @@
- - - - +
- - - - +
@@ -561,37 +469,23 @@ (ngModelChange)="savePreference()" />
- - - - +
- - - - +
diff --git a/desktop/src/app/camera/exposure-time.component.html b/desktop/src/app/camera/exposure-time.component.html index fe9cffe41..abe7021ba 100644 --- a/desktop/src/app/camera/exposure-time.component.html +++ b/desktop/src/app/camera/exposure-time.component.html @@ -1,19 +1,12 @@
- - - - + + - - - - +
- - - - +
- - - - +
- - - - +
- - - - +
diff --git a/desktop/src/app/focuser/focuser.component.html b/desktop/src/app/focuser/focuser.component.html index fef2984dc..c4dffe449 100644 --- a/desktop/src/app/focuser/focuser.component.html +++ b/desktop/src/app/focuser/focuser.component.html @@ -38,15 +38,10 @@
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -152,35 +120,20 @@ [style]="{ width: '80vw' }">
- - - - - - - - + +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -274,37 +249,23 @@
- - - - +
- - - - +
@@ -384,39 +345,23 @@
- - - - +
- - - - +
diff --git a/desktop/src/app/home/home.component.html b/desktop/src/app/home/home.component.html index 9469a67ad..1aa3e3a3d 100644 --- a/desktop/src/app/home/home.component.html +++ b/desktop/src/app/home/home.component.html @@ -368,18 +368,14 @@
- - - - +
- - - - +
- - - - - - - - + +
- - - - +
- - - - +
- - - - +
@@ -703,30 +653,17 @@
- - - - - - - - + +
-
- - - - +
-
- - + [fractionDigits]="2" + [(value)]="stretch.transformation.meanBackground" /> +
- - - - +
@@ -1055,37 +969,22 @@
- - - - +
- - + [(value)]="starDetector.request.maxStars" /> +
@@ -1218,26 +1117,16 @@ (onClick)="showFOVTelescopeDialog()" pTooltip="Choose telescope" tooltipPosition="bottom" /> - - - - +
- - - - +
Resolution (px)
@@ -1251,114 +1140,69 @@
Pixel Size (µm)
- - + [(value)]="fov.selected.cameraSize.width" + (valueChange)="saveFOV()" /> +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
}
@@ -1697,22 +1517,14 @@ [ngModel]="rotation.transformation.angle + 360" (ngModelChange)="rotate($event - 360)" spinnableNumber /> - - - - +
- - - - +
diff --git a/desktop/src/app/rotator/rotator.component.html b/desktop/src/app/rotator/rotator.component.html index 1161cc306..62b3ceada 100644 --- a/desktop/src/app/rotator/rotator.component.html +++ b/desktop/src/app/rotator/rotator.component.html @@ -32,15 +32,10 @@
- - - - +
- - - - +
- - - - + - - - - - - - - + +
@@ -422,76 +402,56 @@ [disabled]="running || !plan.autoFocus.enabled" [(value)]="plan.autoFocus.afterElapsedTimeEnabled" (valueChange)="savePreference()" /> - - - - +
- - - - +
- - - - +
- - - - +
diff --git a/desktop/src/app/settings/settings.component.html b/desktop/src/app/settings/settings.component.html index 56645d631..47271392f 100644 --- a/desktop/src/app/settings/settings.component.html +++ b/desktop/src/app/settings/settings.component.html @@ -112,48 +112,30 @@ } @if (plateSolverType !== 'PIXINSIGHT') {
- - - - +
- - - - +
} @if (plateSolverType === 'PIXINSIGHT') {
- - - - +
}
@@ -184,35 +166,22 @@ (pathChange)="savePreference()" />
- - - - +
- - - - +
@@ -244,20 +213,12 @@
- - - - +
diff --git a/desktop/src/shared/components/checkbox.ts b/desktop/src/shared/components/checkbox.component.ts similarity index 100% rename from desktop/src/shared/components/checkbox.ts rename to desktop/src/shared/components/checkbox.component.ts diff --git a/desktop/src/shared/components/input-number.component.ts b/desktop/src/shared/components/input-number.component.ts new file mode 100644 index 000000000..ff08fce30 --- /dev/null +++ b/desktop/src/shared/components/input-number.component.ts @@ -0,0 +1,56 @@ +import { Component, computed, input, model, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-input-number', + template: ` + + + + + `, + styles: ` + neb-input-number { + .p-button-icon-only.p-inputnumber-button { + width: 2rem; + } + + .p-inputtext { + border: 1px solid rgba(255, 255, 255, 0) !important; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class InputNumberComponent { + readonly label = input() + readonly min = input() + readonly max = input() + readonly step = input(1) + readonly value = model(0) + readonly disabled = input(false) + readonly fractionDigits = input(0) + readonly format = input(true) + readonly suffix = input() + readonly placeholder = input() + readonly readonly = input(false) + + protected readonly minFractionDigits = computed(() => Math.max(this.fractionDigits(), this.step() < 1 ? 1 : 0)) + protected readonly maxFractionDigits = computed(() => Math.max(this.fractionDigits(), this.minFractionDigits())) +} diff --git a/desktop/src/shared/components/location/location.dialog.html b/desktop/src/shared/components/location/location.dialog.html index 8bb727601..87700ff97 100644 --- a/desktop/src/shared/components/location/location.dialog.html +++ b/desktop/src/shared/components/location/location.dialog.html @@ -10,66 +10,38 @@
- - - - +
- - - - +
- - - - +
- - - - +
Date: Fri, 29 Nov 2024 16:24:37 -0300 Subject: [PATCH 03/30] [desktop]: Encapsulate pInputText into neb-input-text --- desktop/src/app/app.module.ts | 2 + desktop/src/app/atlas/atlas.component.html | 190 +++------ .../app/autofocus/autofocus.component.html | 36 +- .../calibration/calibration.component.html | 10 +- desktop/src/app/camera/camera.component.html | 48 +-- .../filterwheel/filterwheel.component.html | 16 +- .../src/app/framing/framing.component.html | 24 +- desktop/src/app/guider/guider.component.html | 88 ++-- desktop/src/app/home/home.component.html | 22 +- desktop/src/app/image/image.component.html | 402 ++++++------------ .../property/indi-property.component.html | 44 +- desktop/src/app/mount/mount.component.html | 162 +++---- .../app/sequencer/sequencer.component.html | 60 ++- .../src/app/settings/settings.component.html | 72 ++-- .../components/input-number.component.ts | 5 +- .../shared/components/input-text.component.ts | 39 ++ .../components/location/location.dialog.html | 12 +- .../path-chooser/path-chooser.component.html | 21 +- .../path-chooser/path-chooser.component.ts | 55 +-- .../src/shared/services/preference.service.ts | 2 - desktop/src/styles.scss | 3 +- 21 files changed, 470 insertions(+), 843 deletions(-) create mode 100644 desktop/src/shared/components/input-text.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index c033ccb0b..f4d952da2 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -54,6 +54,7 @@ import { DeviceNameComponent } from '../shared/components/device-name/device-nam import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' import { HistogramComponent } from '../shared/components/histogram/histogram.component' import { InputNumberComponent } from '../shared/components/input-number.component' +import { InputTextComponent } from '../shared/components/input-text.component' import { LocationComponent } from '../shared/components/location/location.dialog' import { MapComponent } from '../shared/components/map/map.component' import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' @@ -142,6 +143,7 @@ import { SettingsComponent } from './settings/settings.component' INDIComponent, INDIPropertyComponent, InputNumberComponent, + InputTextComponent, LightBoxComponent, LocationComponent, MapComponent, diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index ef802d1a5..4c8b1ec15 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -169,15 +169,11 @@
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -711,24 +655,16 @@ [style]="{ width: '80vw' }">
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
diff --git a/desktop/src/app/calibration/calibration.component.html b/desktop/src/app/calibration/calibration.component.html index 6919daed6..bc32daac7 100644 --- a/desktop/src/app/calibration/calibration.component.html +++ b/desktop/src/app/calibration/calibration.component.html @@ -120,13 +120,9 @@ [style]="{ width: '80vw', maxWidth: '240px' }">
- - - - +
diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index d5ecb6459..93a650828 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -576,14 +576,10 @@ [style]="{ width: '80vw', maxWidth: '320px' }">
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
diff --git a/desktop/src/app/home/home.component.html b/desktop/src/app/home/home.component.html index 1aa3e3a3d..10d371abf 100644 --- a/desktop/src/app/home/home.component.html +++ b/desktop/src/app/home/home.component.html @@ -349,23 +349,15 @@ [style]="{ width: '90vw' }">
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -529,64 +488,40 @@
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -843,84 +778,52 @@ [multiple]="false" />
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -978,57 +881,38 @@
- - - - +
COMPUTED
- - - - +
- - - - +
- - - - +
- - - - +
SELECTED @@ -1041,44 +925,28 @@
- - - - +
- - - - +
- - - - +
- - - - +
diff --git a/desktop/src/app/indi/property/indi-property.component.html b/desktop/src/app/indi/property/indi-property.component.html index c1fbb23b5..67c174556 100644 --- a/desktop/src/app/indi/property/indi-property.component.html +++ b/desktop/src/app/indi/property/indi-property.component.html @@ -62,25 +62,17 @@
- - - - +
- - - - +
@@ -105,25 +97,17 @@
- - - - +
- - - - +
diff --git a/desktop/src/app/mount/mount.component.html b/desktop/src/app/mount/mount.component.html index 2d62f30f8..20ca74163 100644 --- a/desktop/src/app/mount/mount.component.html +++ b/desktop/src/app/mount/mount.component.html @@ -43,104 +43,64 @@
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
@@ -186,28 +146,18 @@
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - +
- - - - + @if (plateSolverType === 'ASTROMETRY_NET_ONLINE') {
- - - - +
- - - - +
} @if (plateSolverType !== 'PIXINSIGHT') { @@ -227,14 +219,10 @@ *ngIf="tab === 'CAPTURE_NAMING_FORMAT'">
- - - - +
- - - - +
- - - - +
- - - - + () readonly max = input() readonly step = input(1) - readonly value = model(0) + readonly value = model(0) readonly disabled = input(false) readonly fractionDigits = input(0) readonly format = input(true) diff --git a/desktop/src/shared/components/input-text.component.ts b/desktop/src/shared/components/input-text.component.ts new file mode 100644 index 000000000..59efcad0d --- /dev/null +++ b/desktop/src/shared/components/input-text.component.ts @@ -0,0 +1,39 @@ +import { Component, input, model, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-input-text', + template: ` + + + + + `, + styles: ` + neb-input-text { + width: 100%; + display: flex; + align-items: center; + + .p-inputtext { + border: 1px solid rgba(255, 255, 255, 0) !important; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class InputTextComponent { + readonly label = input() + readonly maxLength = input(256) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly value = model() + readonly disabled = input(false) + readonly placeholder = input('') + readonly readonly = input(false) +} diff --git a/desktop/src/shared/components/location/location.dialog.html b/desktop/src/shared/components/location/location.dialog.html index 87700ff97..f34240813 100644 --- a/desktop/src/shared/components/location/location.dialog.html +++ b/desktop/src/shared/components/location/location.dialog.html @@ -1,13 +1,9 @@
- - - - +
- - - - + diff --git a/desktop/src/shared/components/path-chooser/path-chooser.component.ts b/desktop/src/shared/components/path-chooser/path-chooser.component.ts index ae7368fc3..1085415cf 100644 --- a/desktop/src/shared/components/path-chooser/path-chooser.component.ts +++ b/desktop/src/shared/components/path-chooser/path-chooser.component.ts @@ -1,6 +1,5 @@ -import { Component, EventEmitter, Input, Output, inject } from '@angular/core' +import { Component, inject, input, model } from '@angular/core' import { ElectronService } from '../../services/electron.service' -import { PreferenceService } from '../../services/preference.service' @Component({ selector: 'neb-path-chooser', @@ -8,50 +7,28 @@ import { PreferenceService } from '../../services/preference.service' }) export class PathChooserComponent { private readonly electronService = inject(ElectronService) - private readonly preferenceService = inject(PreferenceService) - @Input({ required: true }) - protected readonly key!: string - - @Input() - protected readonly label?: string - - @Input() - protected readonly placeholder?: string - - @Input() - protected readonly disabled: boolean = false - - @Input() - protected readonly readonly: boolean = false - - @Input({ required: true }) - protected readonly directory: boolean = false - - @Input() - protected readonly save: boolean = false - - @Input() - protected path?: string - - @Output() - readonly pathChange = new EventEmitter() + readonly key = input.required() + readonly label = input() + readonly placeholder = input() + readonly path = model() + readonly disabled = input(false) + readonly readonly = input(false) + readonly directory = input.required() + readonly save = input(false) protected async choosePath() { - const preference = this.preferenceService.pathChooser.get() - const lastPath = preference[this.key] || undefined - const defaultPath = lastPath && !this.directory ? window.path.dirname(lastPath) : lastPath + const key = this.key() + const lastPath = localStorage.getItem(key) || undefined + const defaultPath = lastPath && !this.directory() ? window.path.dirname(lastPath) : lastPath - const path = await (this.directory ? this.electronService.openDirectory({ defaultPath }) - : this.save ? this.electronService.saveFile({ defaultPath }) + const path = await (this.directory() ? this.electronService.openDirectory({ defaultPath }) + : this.save() ? this.electronService.saveFile({ defaultPath }) : this.electronService.openFile({ defaultPath })) if (path) { - this.path = path - this.pathChange.emit(path) - - preference[this.key] = path - this.preferenceService.pathChooser.set(preference) + this.path.set(path) + localStorage.setItem(key, path) } } } diff --git a/desktop/src/shared/services/preference.service.ts b/desktop/src/shared/services/preference.service.ts index c0ed69790..75291cd83 100644 --- a/desktop/src/shared/services/preference.service.ts +++ b/desktop/src/shared/services/preference.service.ts @@ -56,7 +56,6 @@ export class PreferenceService { readonly guider: PreferenceData readonly framing: PreferenceData readonly settings: PreferenceData - readonly pathChooser: PreferenceData> constructor() { this.home = this.create('home', () => structuredClone(DEFAULT_HOME_PREFERENCE), homePreferenceWithDefault) @@ -67,7 +66,6 @@ export class PreferenceService { this.guider = this.create('guider', () => structuredClone(DEFAULT_GUIDER_PREFERENCE), guiderPreferenceWithDefault) this.framing = this.create('framing', () => structuredClone(DEFAULT_FRAMING_PREFERENCE), framingPreferenceWithDefault) this.settings = this.create('settings', () => structuredClone(DEFAULT_SETTINGS_PREFERENCE), settingsPreferenceWithDefault) - this.pathChooser = this.create>('pathChooser', () => ({}) as Record) } create(key: string, defaultValue: T | (() => T), withDefault?: (value: T) => T) { diff --git a/desktop/src/styles.scss b/desktop/src/styles.scss index facbc2fce..5d5dbe878 100644 --- a/desktop/src/styles.scss +++ b/desktop/src/styles.scss @@ -178,8 +178,7 @@ p-dropdown, } .border-0, -.p-selectbutton.border-0 .p-button, -.p-inputwrapper.border-0 .p-inputtext { +.p-selectbutton.border-0 .p-button { border: 1px solid rgba(255, 255, 255, 0) !important; } From 5bf753e55de86d13158591f3d030337c0b3ba3e6 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 29 Nov 2024 23:03:30 -0300 Subject: [PATCH 04/30] [desktop]: Encapsulate p-button and pButton into neb-button --- desktop/src/app/about/about.component.html | 4 +- .../app/alignment/alignment.component.html | 89 ++-- desktop/src/app/app.component.html | 47 +- desktop/src/app/app.module.ts | 6 + desktop/src/app/atlas/atlas.component.html | 130 ++---- .../app/autofocus/autofocus.component.html | 37 +- .../calibration/calibration.component.html | 55 +-- desktop/src/app/camera/camera.component.html | 152 +++---- .../app/camera/exposure-time.component.html | 9 +- .../src/app/dustcap/dustcap.component.html | 43 +- .../filterwheel/filterwheel.component.html | 48 +- .../flat-wizard/flat-wizard.component.html | 25 +- .../src/app/focuser/focuser.component.html | 80 ++-- .../src/app/framing/framing.component.html | 22 +- desktop/src/app/guider/guider.component.html | 121 ++--- desktop/src/app/home/home.component.html | 416 +++++++----------- desktop/src/app/home/home.component.scss | 51 --- desktop/src/app/home/home.component.ts | 11 +- desktop/src/app/image/image.component.html | 242 ++++------ desktop/src/app/indi/indi.component.html | 8 +- .../property/indi-property.component.html | 58 +-- .../src/app/lightbox/lightbox.component.html | 31 +- desktop/src/app/mount/mount.component.html | 154 +++---- .../src/app/rotator/rotator.component.html | 78 ++-- .../app/sequencer/sequencer.component.html | 143 ++---- .../src/app/settings/settings.component.html | 50 +-- .../components/button-image.component.ts | 44 ++ .../src/shared/components/button.component.ts | 43 ++ .../shared/components/indicator.component.ts | 42 ++ .../components/input-number.component.ts | 2 +- .../shared/components/input-text.component.ts | 5 +- .../components/location/location.dialog.html | 8 +- .../menu-bar/menu-bar.component.html | 10 +- .../path-chooser/path-chooser.component.html | 11 +- .../slide-menu/slide-menu.component.html | 5 +- .../dialogs/confirm/confirm.dialog.html | 16 +- .../src/shared/types/stardetector.types.ts | 4 +- desktop/src/styles.scss | 17 +- 38 files changed, 911 insertions(+), 1406 deletions(-) delete mode 100644 desktop/src/app/home/home.component.scss create mode 100644 desktop/src/shared/components/button-image.component.ts create mode 100644 desktop/src/shared/components/button.component.ts create mode 100644 desktop/src/shared/components/indicator.component.ts diff --git a/desktop/src/app/about/about.component.html b/desktop/src/app/about/about.component.html index 88293872e..30f1d9deb 100644 --- a/desktop/src/app/about/about.component.html +++ b/desktop/src/app/about/about.component.html @@ -76,12 +76,12 @@ href="https://www.paypal.com/donate/?hosted_button_id=U8TGGJTKSZUCA"> + style="height: 28px" /> - diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 54cf3a294..6f567281c 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -7,14 +7,11 @@ [devices]="cameras" [(device)]="camera" (deviceChange)="cameraChanged()" /> - + (action)="showCameraDialog()" + tooltip="Camera" /> @if (tab === 0) {
@if (pausingOrPaused) { - + severity="success" /> } @else if (!running) { - + severity="success" /> } - - + - + + class="ml-4" + tooltip="View image" + tooltipPosition="top" />
@@ -216,44 +203,36 @@
- - + - + + class="ml-4" + tooltip="View image" + tooltipPosition="top" />
- + (action)="tab === 0 ? tppaInfo.toggle($event) : darvInfo.toggle($event)" /> - - + - + - + - + + (action)="close()" />
diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index f4d952da2..c4de29b34 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -45,6 +45,8 @@ import { TieredMenuModule } from 'primeng/tieredmenu' import { ToastModule } from 'primeng/toast' import { TooltipModule } from 'primeng/tooltip' import { TreeModule } from 'primeng/tree' +import { ButtonImageComponent } from '../shared/components/button-image.component' +import { ButtonComponent } from '../shared/components/button.component' import { CameraExposureComponent } from '../shared/components/camera-exposure/camera-exposure.component' import { CameraInfoComponent } from '../shared/components/camera-info/camera-info.component' import { CheckboxComponent } from '../shared/components/checkbox.component' @@ -53,6 +55,7 @@ import { DeviceListMenuComponent } from '../shared/components/device-list-menu/d import { DeviceNameComponent } from '../shared/components/device-name/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' import { HistogramComponent } from '../shared/components/histogram/histogram.component' +import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' import { InputTextComponent } from '../shared/components/input-text.component' import { LocationComponent } from '../shared/components/location/location.dialog' @@ -112,6 +115,8 @@ import { SettingsComponent } from './settings/settings.component' AppComponent, AtlasComponent, AutoFocusComponent, + ButtonComponent, + ButtonImageComponent, CalculatorComponent, CalibrationComponent, CameraComponent, @@ -140,6 +145,7 @@ import { SettingsComponent } from './settings/settings.component' HistogramComponent, HomeComponent, ImageComponent, + IndicatorComponent, INDIComponent, INDIPropertyComponent, InputNumberComponent, diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index 4c8b1ec15..4209a839a 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -172,15 +172,12 @@ - + + severity="info" />
- + severity="info" />
- - + + tooltip="Filter" />
@@ -396,21 +385,15 @@ label="Search" [(value)]="satellite.search.filter.text" />
- - + + tooltip="Filter" />
@@ -554,37 +537,29 @@
- - + - + - + + label="Frame" />
@@ -603,20 +578,15 @@
- + (action)="ephemerisMenu.show()" /> @if (body.name && canFavorite) { - + tooltip="{{ favorited ? 'Unfavorite' : 'Favorite' }}" + (action)="favorite()" /> }
- + (action)="searchSkyObject()" /> @@ -751,19 +719,15 @@
- - + + (action)="searchSatellite()" /> @@ -871,15 +835,11 @@ {{ item.type | enum }} {{ item.name }} - + tooltip="Remove" + (action)="deleteFavorite(item)" />
diff --git a/desktop/src/app/autofocus/autofocus.component.html b/desktop/src/app/autofocus/autofocus.component.html index 4a46371f8..41eb6d979 100644 --- a/desktop/src/app/autofocus/autofocus.component.html +++ b/desktop/src/app/autofocus/autofocus.component.html @@ -6,14 +6,11 @@ [devices]="cameras" [(device)]="camera" (deviceChange)="cameraChanged()" /> - + (action)="showCameraDialog()" + tooltip="Camera" />
- - + - + + class="ml-4" + tooltip="View image" + tooltipPosition="top" />
diff --git a/desktop/src/app/calibration/calibration.component.html b/desktop/src/app/calibration/calibration.component.html index bc32daac7..b58762f8e 100644 --- a/desktop/src/app/calibration/calibration.component.html +++ b/desktop/src/app/calibration/calibration.component.html @@ -7,16 +7,14 @@
- - + + (action)="openDirectoryToUpload(key)" />
{{ this.frames.get(key)?.length ?? 0 }} frames
@@ -25,12 +23,9 @@ [model]="groupModel" (onShow)="activeGroup = key" [popup]="true" /> - + (action)="groupMenu.toggle($event)" />
@@ -72,33 +67,19 @@
- - + - + + tooltip="Remove" + (action)="deleteFrame(item, frameListBox)" />
@@ -126,12 +107,10 @@
- + (action)="groupDialog.save?.()" /> diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index 93a650828..0fef0a059 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -2,55 +2,39 @@
- - + @if (camera.connected) { + + } @else { + + }
- - + - + + (action)="cameraMenu.show()" />
- + tooltip="Apply" />
@@ -266,15 +247,12 @@ (ngModelChange)="savePreference()" />
- + tooltip="Full size" />
@@ -384,52 +362,42 @@
@if (pausingOrPaused) { - + severity="success" /> } @else if (!running) { - + severity="success" /> } - - + - + + severity="info" />
@@ -580,48 +548,40 @@ label="Light" [(value)]="namingFormat.format.light" (valueChange)="savePreference()" /> - + (action)="resetCameraCaptureNamingFormat('LIGHT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('DARK')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('FLAT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('BIAS')" + tooltip="Reset" />
diff --git a/desktop/src/app/camera/exposure-time.component.html b/desktop/src/app/camera/exposure-time.component.html index abe7021ba..b6f95c11a 100644 --- a/desktop/src/app/camera/exposure-time.component.html +++ b/desktop/src/app/camera/exposure-time.component.html @@ -12,12 +12,11 @@ [model]="model" [popup]="true" appendTo="body" /> - diff --git a/desktop/src/app/dustcap/dustcap.component.html b/desktop/src/app/dustcap/dustcap.component.html index 8b8d05a6a..b8f90fafd 100644 --- a/desktop/src/app/dustcap/dustcap.component.html +++ b/desktop/src/app/dustcap/dustcap.component.html @@ -2,24 +2,21 @@
- - + @if (dustCap.connected) { + + } @else { + + }
@@ -32,21 +29,19 @@
@if (dustCap.parked) { - + (action)="togglePark()" /> } @else { - + (action)="togglePark()" /> }
diff --git a/desktop/src/app/filterwheel/filterwheel.component.html b/desktop/src/app/filterwheel/filterwheel.component.html index cc3fcd0cc..d4e6046d8 100644 --- a/desktop/src/app/filterwheel/filterwheel.component.html +++ b/desktop/src/app/filterwheel/filterwheel.component.html @@ -2,26 +2,21 @@
- - + @if (wheel.connected) { + + } @else { + + }
- + (action)="moveToSelectedFilter()" />
- + severity="info" />
diff --git a/desktop/src/app/flat-wizard/flat-wizard.component.html b/desktop/src/app/flat-wizard/flat-wizard.component.html index c9508d11a..cfcc6416b 100644 --- a/desktop/src/app/flat-wizard/flat-wizard.component.html +++ b/desktop/src/app/flat-wizard/flat-wizard.component.html @@ -7,14 +7,11 @@ [devices]="cameras" [(device)]="camera" (deviceChange)="cameraChanged()" /> - + (action)="showCameraDialog()" + tooltip="Camera" />
- - + + severity="danger" />
diff --git a/desktop/src/app/focuser/focuser.component.html b/desktop/src/app/focuser/focuser.component.html index c4dffe449..02b7498f7 100644 --- a/desktop/src/app/focuser/focuser.component.html +++ b/desktop/src/app/focuser/focuser.component.html @@ -2,26 +2,21 @@
- - + @if (focuser.connected) { + + } @else { + + }
@@ -44,34 +39,25 @@ [value]="focuser.position" />
- - + + tooltip="Sync" />
- + tooltip="Move In" /> - + tooltip="Move Out" />
- + tooltip="Move To" />
diff --git a/desktop/src/app/framing/framing.component.html b/desktop/src/app/framing/framing.component.html index 2a1a2fea6..bd48072cd 100644 --- a/desktop/src/app/framing/framing.component.html +++ b/desktop/src/app/framing/framing.component.html @@ -35,14 +35,10 @@ [step]="0.1" [(value)]="preference.fov" (valueChange)="savePreference()" /> - + (action)="fov.showDialog = true" + tooltip="Calculate" />
- + (action)="frame()" />
@@ -135,12 +129,10 @@
{{ fov.computed.toFixed(3) }}° - + (action)="computeFOV(true)" />
diff --git a/desktop/src/app/guider/guider.component.html b/desktop/src/app/guider/guider.component.html index 2a64b2c57..ffa3b82b8 100644 --- a/desktop/src/app/guider/guider.component.html +++ b/desktop/src/app/guider/guider.component.html @@ -23,24 +23,19 @@ [format]="false" />
- - + @if (guider.connected) { + + } @else { + + }
- - - + + severity="danger" />
@@ -242,77 +233,59 @@
- + (action)="guidePulseStart('NORTH', 'WEST')" + icon="mdi mdi-lg mdi-arrow-top-left-thick" />
- + (action)="guidePulseStart('NORTH')" + icon="mdi mdi-lg mdi-arrow-up-thick" />
- + (action)="guidePulseStart('NORTH', 'EAST')" + icon="mdi mdi-lg mdi-arrow-top-right-thick" />
- + (action)="guidePulseStart('WEST')" + icon="mdi mdi-lg mdi-arrow-left-thick" />
- + severity="danger" />
- + (action)="guidePulseStart('EAST')" + icon="mdi mdi-lg mdi-arrow-right-thick" />
- + (action)="guidePulseStart('SOUTH', 'WEST')" + icon="mdi mdi-lg mdi-arrow-bottom-left-thick" />
- + (action)="guidePulseStart('SOUTH')" + icon="mdi mdi-lg mdi-arrow-down-thick" />
- + (action)="guidePulseStart('SOUTH', 'EAST')" + icon="mdi mdi-lg mdi-arrow-bottom-right-thick" />
diff --git a/desktop/src/app/home/home.component.html b/desktop/src/app/home/home.component.html index 10d371abf..794fd14c7 100644 --- a/desktop/src/app/home/home.component.html +++ b/desktop/src/app/home/home.component.html @@ -1,15 +1,11 @@
- + tooltip="New connection" /> - - + + tooltip="Disconnect" />
- + class="py-1 text-blue-900" />
-
- - -
Camera
-
-
-
- - -
Mount
-
-
-
- - -
Guider
-
-
-
- - -
Filter Wheel
-
-
-
- - -
Focuser
-
-
-
- - -
Rotator
-
-
-
- - -
Dome
-
-
-
- - -
Auxiliary
-
-
+ + + + + + + + @if (preference.showAuxiliary && hasAuxiliary) { -
- - -
Switch
-
-
-
- - -
Light Box
-
-
-
- - -
Dust Cap
-
-
+ + + } -
- - -
Sky Atlas
-
-
-
- - -
Alignment
-
-
-
- - -
Sequencer
-
-
-
- - -
Image Viewer
-
-
-
- - -
Framing
-
-
-
- - -
Auto Focus
-
-
-
- - -
Flat Wizard
-
-
-
- - -
Calibration
-
-
-
- - -
INDI
-
-
-
- - -
Calculator
-
-
-
- - -
Settings
-
-
-
- - -
About
-
-
-
- - -
+ + + + + + + + + + + + +
@@ -377,13 +267,11 @@ - + (action)="saveConnection()" /> diff --git a/desktop/src/app/home/home.component.scss b/desktop/src/app/home/home.component.scss deleted file mode 100644 index fac79d445..000000000 --- a/desktop/src/app/home/home.component.scss +++ /dev/null @@ -1,51 +0,0 @@ -neb-home { - .buttons { - p-button { - display: contents; - - > button { - min-height: 56px; - max-height: 56px; - display: flex; - - img { - height: 32px; - } - } - - &.p-disabled { - img { - filter: grayscale(1); - } - } - } - } - - .indicators { - top: 50%; - right: 0.6rem; - - .indicator { - background-color: #3f3f46; - width: 0.7rem; - height: 0.7rem; - transition: - background-color 0.2s, - color 0.2s, - border-color 0.2s, - box-shadow 0.2s, - outline-color 0.2s; - border-radius: 50%; - cursor: pointer; - margin: 1px; - - &.selected { - background-color: #60a5fa; - } - } - } - - .grid::-webkit-scrollbar { - display: none; - } -} diff --git a/desktop/src/app/home/home.component.ts b/desktop/src/app/home/home.component.ts index 01afb6a60..ff9a4ea07 100644 --- a/desktop/src/app/home/home.component.ts +++ b/desktop/src/app/home/home.component.ts @@ -26,7 +26,6 @@ function scrollPageOf(element: Element) { @Component({ selector: 'neb-home', templateUrl: 'home.component.html', - styleUrls: ['home.component.scss'], encapsulation: ViewEncapsulation.None, }) export class HomeComponent implements AfterContentInit { @@ -669,7 +668,7 @@ export class HomeComponent implements AfterContentInit { } let page = 0 - const scrollChidren = document.getElementsByClassName('scroll-child') + const scrollChidren = document.querySelectorAll('[scroll-page]') for (let i = 0; i < scrollChidren.length; i++) { const child = scrollChidren[i] @@ -684,14 +683,8 @@ export class HomeComponent implements AfterContentInit { event.stopImmediatePropagation() } - protected scrollTo(event: Event, page: number) { - this.page = page - this.scrollToPage(page) - event.stopImmediatePropagation() - } - protected scrollToPage(page: number) { - const scrollChidren = document.getElementsByClassName('scroll-child') + const scrollChidren = document.querySelectorAll('[scroll-page]') for (let i = 0; i < scrollChidren.length; i++) { const child = scrollChidren[i] diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index 05c86ee48..529d4f1ff 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -133,13 +133,10 @@ *ngIf="hasROI" class="roi-coordinates fixed flex flex-row align-items-center gap-2"> X: {{ imageROI.area.x.toFixed(0) }} Y: {{ imageROI.area.y.toFixed(0) }} W: {{ imageROI.area.width.toFixed(0) }} H: {{ imageROI.area.height.toFixed(0) }} - + tooltip="Apply" /> - + (action)="annotateImage()" /> @@ -377,37 +372,29 @@
- - + - + - + + label="Frame" />
@@ -526,55 +513,43 @@
- - + - + - + + label="Frame" />
- - + (action)="solverStart()" />
@@ -633,43 +608,33 @@ [(value)]="stretch.transformation.meanBackground" /> - - + + (action)="restoreAutoStretchMeanBackground()" + tooltip="Reset" /> - - + - + + (action)="stretchImage()" /> @@ -717,12 +682,10 @@ - + (action)="scnrImage()" /> @@ -952,13 +915,11 @@ - + (action)="detectStars()" /> @@ -979,12 +940,10 @@ [style]="{ width: '23px', height: '23px' }" />
- + (action)="showFOVTelescopeDialog()" + tooltip="Choose telescope" />
Resolution (px)
- + (action)="showFOVCameraDialog()" + tooltip="Choose camera" />
Pixel Size (µm)
@@ -1073,15 +1030,12 @@ (valueChange)="saveFOV(false)" />
- + tooltip="Add" + (action)="addFOV()" />
- - + + tooltip="Remove" + (action)="deleteFOV(item)" />
} @@ -1189,13 +1135,11 @@
- + (action)="chooseCamera()" /> @@ -1232,13 +1176,11 @@ - + (action)="chooseTelescope()" /> @@ -1269,14 +1211,11 @@ @if (imageInfo) {
- + tooltip="ROI Size" + (action)="useROIAreaForSaveAs()" />
- + tooltip="Image Size" + (action)="useImageAreaForSaveAs()" />
- + (action)="saveImageAs()" /> @@ -1395,22 +1329,18 @@ [fractionDigits]="2" />
- - + - + - + + (action)="rotate(270)" />
diff --git a/desktop/src/app/indi/indi.component.html b/desktop/src/app/indi/indi.component.html index 7a37ebbbf..6ffcab6d3 100644 --- a/desktop/src/app/indi/indi.component.html +++ b/desktop/src/app/indi/indi.component.html @@ -21,13 +21,11 @@ [model]="groups" class="w-auto" [style]="{ width: '260px' }" /> - + (action)="showLog = true" + severity="success" />
diff --git a/desktop/src/app/indi/property/indi-property.component.html b/desktop/src/app/indi/property/indi-property.component.html index 67c174556..9c6cbc287 100644 --- a/desktop/src/app/indi/property/indi-property.component.html +++ b/desktop/src/app/indi/property/indi-property.component.html @@ -7,50 +7,34 @@
- - - + (action)="sendSwitch(item)" + icon="mdi mdi-{{item.value ? 'check' : 'close'}}" + [severity]="item.value ? 'success' : 'danger'"/>
- + (action)="sendSwitch(item)" + icon="mdi mdi-check" />
- - - + (action)="sendSwitch(item)" + icon="mdi mdi-{{item.value ? 'check' : 'close'}}" + [severity]="item.value ? 'success' : 'danger'"/>
- + (action)="sendNumber()" + icon="mdi mdi-send" />
- + (action)="sendText()" + icon="mdi mdi-send" />
diff --git a/desktop/src/app/lightbox/lightbox.component.html b/desktop/src/app/lightbox/lightbox.component.html index cd6c53cc2..f33c1ed15 100644 --- a/desktop/src/app/lightbox/lightbox.component.html +++ b/desktop/src/app/lightbox/lightbox.component.html @@ -2,24 +2,19 @@
- - + @if (lightBox.connected) { + + } @else { + + }
diff --git a/desktop/src/app/mount/mount.component.html b/desktop/src/app/mount/mount.component.html index 20ca74163..d9bef163e 100644 --- a/desktop/src/app/mount/mount.component.html +++ b/desktop/src/app/mount/mount.component.html @@ -2,37 +2,28 @@
- - + @if (mount.connected) { + + } @else { + + }
- + tooltip="Remote Control" />
@@ -104,12 +95,9 @@
- + (action)="ephemerisMenu.show()" />
@@ -174,93 +162,75 @@
- + icon="mdi mdi-arrow-top-left-thick" />
- + icon="mdi mdi-arrow-up-thick" />
- + icon="mdi mdi-arrow-top-right-thick" />
- + icon="mdi mdi-arrow-left-thick" />
- + (action)="abort()" />
- + icon="mdi mdi-arrow-right-thick" />
- + icon="mdi mdi-arrow-bottom-left-thick" />
- + icon="mdi mdi-arrow-down-thick" />
- + icon="mdi mdi-arrow-bottom-right-thick" />
@@ -274,35 +244,26 @@ (ngModelChange)="trackingToggled()" />
- - + - + + (action)="home()" + tooltip="Home" + severity="info" />
@@ -387,11 +348,11 @@
- + (action)="startRemoteControl()" />
{{ item.host }}:{{ item.port }}
- + tooltip="Stop" + (action)="stopRemoteControl(item.protocol)" />
diff --git a/desktop/src/app/rotator/rotator.component.html b/desktop/src/app/rotator/rotator.component.html index 62b3ceada..3f128d324 100644 --- a/desktop/src/app/rotator/rotator.component.html +++ b/desktop/src/app/rotator/rotator.component.html @@ -2,26 +2,21 @@
- - + @if (rotator.connected) { + + } @else { + + }
@@ -38,24 +33,18 @@ [(value)]="rotator.angle" />
- - + + tooltip="Home" + (action)="home()" />
Reversed - - + + tooltip="Move" />
- + severity="info" />
diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index d2a0d3ff8..6b613f5c3 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -112,33 +112,24 @@ #{{ i + 1 }}
- - + - + + (action)="showRotatorDialog(sequence)" />
- - - + + tooltip="Duplicate" + (action)="duplicateSequence(sequence, i)" /> Mode
- + tooltip="{{ 'Auto sub folder: ' + plan.autoSubFolderMode }}" + (action)="toggleAutoSubFolder()" /> - + (action)="resetCameraCaptureNamingFormat('LIGHT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('DARK')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('FLAT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('BIAS')" + tooltip="Reset" />
@@ -514,48 +481,38 @@
@if (pausingOrPaused) { - + severity="success" /> } @else if (!running) { - + severity="success" /> } - - + + severity="danger" />
- + (action)="add()" />
@@ -566,16 +523,14 @@ [style]="{ maxWidth: '400px' }">
- - + + (action)="selectSequenceProperty(false)" />
- + (action)="copySequencePropertyToSequencies()" /> diff --git a/desktop/src/app/settings/settings.component.html b/desktop/src/app/settings/settings.component.html index 27ba8c5c7..da8e3390b 100644 --- a/desktop/src/app/settings/settings.component.html +++ b/desktop/src/app/settings/settings.component.html @@ -35,23 +35,17 @@
- - + + tooltip="Delete" + (action)="deleteLocation()" />
@@ -223,48 +217,40 @@ label="Light" [(value)]="preference.namingFormat.light" (valueChange)="savePreference()" /> - + (action)="resetCameraCaptureNamingFormat('LIGHT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('DARK')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('FLAT')" + tooltip="Reset" />
- + (action)="resetCameraCaptureNamingFormat('BIAS')" + tooltip="Reset" />
diff --git a/desktop/src/shared/components/button-image.component.ts b/desktop/src/shared/components/button-image.component.ts new file mode 100644 index 000000000..e81459230 --- /dev/null +++ b/desktop/src/shared/components/button-image.component.ts @@ -0,0 +1,44 @@ +import { Component, input, output, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-button-image', + template: ` + + + + @if (label()) { +
{{ label() }}
+ } +
+ `, + styles: ` + neb-button-image { + .p-disabled { + img { + filter: grayscale(1); + } + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class ButtonImageComponent { + readonly label = input() + readonly image = input.required() + readonly imageHeight = input('16px') + readonly tooltip = input() + readonly tooltipPosition = input<'right' | 'left' | 'top' | 'bottom'>('bottom') + readonly disabled = input(false) + readonly severity = input<'success' | 'info' | 'warning' | 'danger' | 'help' | 'primary' | 'secondary' | 'contrast'>() + readonly action = output() +} diff --git a/desktop/src/shared/components/button.component.ts b/desktop/src/shared/components/button.component.ts new file mode 100644 index 000000000..6524fb9ba --- /dev/null +++ b/desktop/src/shared/components/button.component.ts @@ -0,0 +1,43 @@ +import { Component, input, output, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-button', + template: ` + + `, + styles: ` + neb-button { + .p-button { + &.p-button-icon-only { + aspect-ratio: 1; + } + + &:has(.mdi-lg) { + height: 3.25rem; + } + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class ButtonComponent { + readonly label = input() + readonly icon = input() + readonly tooltip = input() + readonly tooltipPosition = input<'right' | 'left' | 'top' | 'bottom'>('bottom') + readonly disabled = input(false) + readonly severity = input<'success' | 'info' | 'warning' | 'danger' | 'help' | 'primary' | 'secondary' | 'contrast'>() + readonly action = output() +} diff --git a/desktop/src/shared/components/indicator.component.ts b/desktop/src/shared/components/indicator.component.ts new file mode 100644 index 000000000..b66137642 --- /dev/null +++ b/desktop/src/shared/components/indicator.component.ts @@ -0,0 +1,42 @@ +import { Component, input, model, ViewEncapsulation } from '@angular/core' + +@Component({ + selector: 'neb-indicator', + template: ` +
+ @for (item of [].constructor(count()); track $index) { + + } +
+ `, + styles: ` + neb-indicator { + .indicator { + background-color: #3f3f46; + width: 0.7rem; + height: 0.7rem; + transition: + background-color 0.2s, + color 0.2s, + border-color 0.2s, + box-shadow 0.2s, + outline-color 0.2s; + border-radius: 50%; + cursor: pointer; + margin: 1px; + + &.selected { + background-color: #60a5fa; + } + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class IndicatorComponent { + readonly count = input.required() + readonly position = model(0) +} diff --git a/desktop/src/shared/components/input-number.component.ts b/desktop/src/shared/components/input-number.component.ts index 947cbde67..5695e8065 100644 --- a/desktop/src/shared/components/input-number.component.ts +++ b/desktop/src/shared/components/input-number.component.ts @@ -46,7 +46,7 @@ export class InputNumberComponent { readonly min = input() readonly max = input() readonly step = input(1) - readonly value = model(0) + readonly value = model(0) readonly disabled = input(false) readonly fractionDigits = input(0) readonly format = input(true) diff --git a/desktop/src/shared/components/input-text.component.ts b/desktop/src/shared/components/input-text.component.ts index 59efcad0d..96ed72086 100644 --- a/desktop/src/shared/components/input-text.component.ts +++ b/desktop/src/shared/components/input-text.component.ts @@ -11,7 +11,9 @@ import { Component, input, model, ViewEncapsulation } from '@angular/core' [readonly]="readonly()" [maxLength]="maxLength()" [placeholder]="placeholder()" - [(ngModel)]="value" /> + [(ngModel)]="value" + [pTooltip]="tooltip()" + tooltipPosition="bottom" /> `, @@ -36,4 +38,5 @@ export class InputTextComponent { readonly disabled = input(false) readonly placeholder = input('') readonly readonly = input(false) + readonly tooltip = input() } diff --git a/desktop/src/shared/components/location/location.dialog.html b/desktop/src/shared/components/location/location.dialog.html index f34240813..8db5b32e0 100644 --- a/desktop/src/shared/components/location/location.dialog.html +++ b/desktop/src/shared/components/location/location.dialog.html @@ -51,12 +51,10 @@ diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.html b/desktop/src/shared/components/menu-bar/menu-bar.component.html index 49fce541b..86bb1889b 100644 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.html +++ b/desktop/src/shared/components/menu-bar/menu-bar.component.html @@ -43,16 +43,12 @@ [value]="item.badge" styleClass="absolute flex justify-content-center align-items-center top-0" [style]="{ width: '14px', minWidth: '14px', height: '14px', minHeight: '14px', right: '-2px' }" /> - + (action)="item.command?.({ originalEvent: $event, item: item, index: i })" /> } } diff --git a/desktop/src/shared/components/path-chooser/path-chooser.component.html b/desktop/src/shared/components/path-chooser/path-chooser.component.html index 885269387..96c1b0fd4 100644 --- a/desktop/src/shared/components/path-chooser/path-chooser.component.html +++ b/desktop/src/shared/components/path-chooser/path-chooser.component.html @@ -5,14 +5,9 @@ [readonly]="readonly()" [placeholder]="placeholder() ?? ''" [(value)]="path" /> - + (action)="choosePath()" + tooltip="{{ directory() ? 'Choose directory' : 'Choose file' }}" /> diff --git a/desktop/src/shared/components/slide-menu/slide-menu.component.html b/desktop/src/shared/components/slide-menu/slide-menu.component.html index 58f9a4bf2..4d57c46ce 100644 --- a/desktop/src/shared/components/slide-menu/slide-menu.component.html +++ b/desktop/src/shared/components/slide-menu/slide-menu.component.html @@ -9,10 +9,9 @@ - + (action)="back($event)" /> diff --git a/desktop/src/shared/dialogs/confirm/confirm.dialog.html b/desktop/src/shared/dialogs/confirm/confirm.dialog.html index 655011566..dc874d812 100644 --- a/desktop/src/shared/dialogs/confirm/confirm.dialog.html +++ b/desktop/src/shared/dialogs/confirm/confirm.dialog.html @@ -1,17 +1,13 @@ {{ message }} diff --git a/desktop/src/shared/types/stardetector.types.ts b/desktop/src/shared/types/stardetector.types.ts index 5093e3ccf..81775bbd5 100644 --- a/desktop/src/shared/types/stardetector.types.ts +++ b/desktop/src/shared/types/stardetector.types.ts @@ -8,8 +8,8 @@ export interface StarDetectorSettings { export interface StarDetectionRequest extends StarDetectorSettings { type: StarDetectorType - minSNR?: number - maxStars?: number + minSNR: number + maxStars: number } export const DEFAULT_STAR_DETECTOR_SETTINGS: StarDetectorSettings = { diff --git a/desktop/src/styles.scss b/desktop/src/styles.scss index 5d5dbe878..5dc7cdafd 100644 --- a/desktop/src/styles.scss +++ b/desktop/src/styles.scss @@ -38,6 +38,10 @@ body { font-family: 'Roboto'; } +a { + display: inline-flex; +} + a:any-link { color: $infoButtonBg; } @@ -182,15 +186,6 @@ p-dropdown, border: 1px solid rgba(255, 255, 255, 0) !important; } -.p-button { - white-space: nowrap; - max-width: 100%; - - &.p-button-icon-only { - min-width: fit-content; - } -} - p-calendar.border-0 .p-calendar-w-btn { border: 0 !important; } @@ -505,3 +500,7 @@ p-tieredmenu *, ::-webkit-scrollbar-corner { background-color: transparent; } + +.no-scrollbar::-webkit-scrollbar { + display: none; +} From 255568d0101a4e1da0737e4a8e391976a574557b Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sat, 30 Nov 2024 21:13:38 -0300 Subject: [PATCH 05/30] [desktop]: Encapsulate p-inputSwitch into neb-switch --- desktop/src/app/app.module.ts | 2 + desktop/src/app/atlas/atlas.component.html | 10 +-- desktop/src/app/camera/camera.component.html | 87 +++++++++---------- .../src/app/lightbox/lightbox.component.html | 12 ++- desktop/src/app/mount/mount.component.html | 10 +-- .../src/app/rotator/rotator.component.html | 10 +-- .../app/sequencer/sequencer.component.html | 10 +-- .../shared/components/checkbox.component.ts | 6 +- .../menu-bar/menu-bar.component.html | 24 ++--- .../menu-item/menu-item.component.html | 8 +- .../src/shared/components/switch.component.ts | 23 +++++ 11 files changed, 112 insertions(+), 90 deletions(-) create mode 100644 desktop/src/shared/components/switch.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index c4de29b34..e3d1f0957 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -65,6 +65,7 @@ import { MenuItemComponent } from '../shared/components/menu-item/menu-item.comp import { MoonComponent } from '../shared/components/moon/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser/path-chooser.component' import { SlideMenuComponent } from '../shared/components/slide-menu/slide-menu.component' +import { SwitchComponent } from '../shared/components/switch.component' import { ConfirmDialogComponent } from '../shared/dialogs/confirm/confirm.dialog' import { NoDropdownDirective } from '../shared/directives/no-dropdown.directive' import { SpinnableNumberDirective } from '../shared/directives/spinnable-number.directive' @@ -164,6 +165,7 @@ import { SettingsComponent } from './settings/settings.component' SettingsComponent, SlideMenuComponent, SpinnableNumberDirective, + SwitchComponent, WinPipe, ], imports: [ diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index 4209a839a..a00baf763 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -766,12 +766,10 @@ styleClass="w-full" />
-
- Date Time - -
+
-
- Cooler ({{ camera.coolerPower | number: '1.1-1' }}%) - + + [(value)]="camera!.cooler" + (valueChange)="toggleCooler()" />
-
- Dew heater - + + [(value)]="camera!.dewHeater" />
@@ -239,14 +239,14 @@
-
- Subframe - + + [(value)]="preference.subFrame" + (valueChange)="savePreference()" />
-
+
- - - - +
Dither -
- Enabled - +
+
-
- RA only - + + [(value)]="dither.request.raOnly" + (valueChange)="savePreference()" />
Live Stacking -
- Enabled - +
+
@@ -489,12 +486,12 @@
-
- 32-bit (slower) - + + [(value)]="liveStacking.request.use32Bits" + (valueChange)="savePreference()" />
-
- Enabled - -
+
-
- Tracking - + + [(value)]="tracking" + (valueChange)="trackingToggled()" />
-
- Reversed - + + [(value)]="rotator.reversed" + (valueChange)="reverse($event)" />
diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index 6b613f5c3..533438cb5 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -437,12 +437,12 @@ appendTo="body" /> -
- 32-bit (slower) - + + [(value)]="plan.liveStacking.use32Bits" + (valueChange)="savePreference()" />
+ (onChange)="action.emit($event); $event.originalEvent?.stopImmediatePropagation()" /> `, styles: ` neb-checkbox { @@ -32,4 +33,5 @@ export class CheckboxComponent { readonly disabled = input(false) readonly noWrap = input(false) readonly vertical = input(false) + readonly action = output() } diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.html b/desktop/src/shared/components/menu-bar/menu-bar.component.html index 86bb1889b..1b4c4a781 100644 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.html +++ b/desktop/src/shared/components/menu-bar/menu-bar.component.html @@ -6,23 +6,25 @@ @if (item.toggleable) {
- {{ item.label }} - + + [value]="item.toggled ?? false" + (valueChange)="item.toggled = $event" + (action)="item.toggle?.($event)" />
} @else if (item.checkable) {
- {{ item.label }} - + + [vertical]="true" + [value]="item.checked ?? false" + (valueChange)="item.checked = $event" + (action)="item.check?.($event)" />
} @else if (item.label && item.splitButtonMenu?.length) { } @if (item.checkable) { - + } @if (item.items?.length || item.slideMenu?.length) { diff --git a/desktop/src/shared/components/switch.component.ts b/desktop/src/shared/components/switch.component.ts new file mode 100644 index 000000000..5d1024110 --- /dev/null +++ b/desktop/src/shared/components/switch.component.ts @@ -0,0 +1,23 @@ +import { Component, input, model, output, ViewEncapsulation } from '@angular/core' +import { InputSwitchChangeEvent } from 'primeng/inputswitch' + +@Component({ + selector: 'neb-switch', + template: ` +
+ {{ label() }} + +
+ `, + styles: ``, + encapsulation: ViewEncapsulation.None, +}) +export class SwitchComponent { + readonly label = input() + readonly value = model(false) + readonly disabled = input(false) + readonly action = output() +} From 7bffacf2343769c04621ff1e4815c9f4181b43ec Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 1 Dec 2024 12:30:22 -0300 Subject: [PATCH 06/30] [desktop]: Encapsulate p-tag into neb-tag --- desktop/src/app/about/about.component.html | 17 ++--- .../app/alignment/alignment.component.html | 8 +- desktop/src/app/app.module.ts | 2 + desktop/src/app/atlas/atlas.component.html | 32 ++++---- .../calculator/formula/formula.component.html | 6 +- desktop/src/app/camera/camera.component.html | 66 +++++++---------- .../filterwheel/filterwheel.component.html | 38 ++++------ desktop/src/app/image/image.component.html | 40 +++------- .../src/shared/components/switch.component.ts | 1 - .../src/shared/components/tag.component.ts | 74 +++++++++++++++++++ desktop/src/styles.scss | 12 --- 11 files changed, 159 insertions(+), 137 deletions(-) create mode 100644 desktop/src/shared/components/tag.component.ts diff --git a/desktop/src/app/about/about.component.html b/desktop/src/app/about/about.component.html index 30f1d9deb..13323977e 100644 --- a/desktop/src/app/about/about.component.html +++ b/desktop/src/app/about/about.component.html @@ -13,16 +13,13 @@

- Nebulosa - - + Nebulosa + +

{{ description }} diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 6f567281c..37fc2fbce 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -44,11 +44,11 @@ *ngIf="method === 'TPPA'" class="absolute flex flex-row align-items-center gap-1" style="right: 8px; top: -2px"> - -

diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index e3d1f0957..579bf3e45 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -66,6 +66,7 @@ import { MoonComponent } from '../shared/components/moon/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser/path-chooser.component' import { SlideMenuComponent } from '../shared/components/slide-menu/slide-menu.component' import { SwitchComponent } from '../shared/components/switch.component' +import { TagComponent } from '../shared/components/tag.component' import { ConfirmDialogComponent } from '../shared/dialogs/confirm/confirm.dialog' import { NoDropdownDirective } from '../shared/directives/no-dropdown.directive' import { SpinnableNumberDirective } from '../shared/directives/spinnable-number.directive' @@ -165,6 +166,7 @@ import { SettingsComponent } from './settings/settings.component' SettingsComponent, SlideMenuComponent, SpinnableNumberDirective, + TagComponent, SwitchComponent, WinPipe, ], diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index a00baf763..76cab89fc 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -21,17 +21,16 @@ - - SDO/HMI -
-
+
@for (season of sun.seasons; track $index) {
@@ -436,10 +435,9 @@ {{ item.id }} {{ item.name }} - + @for (group of item.groups; track $index) { + + } @@ -592,11 +590,11 @@ class="flex w-full align-items-center gap-1 justify-content-center" style="min-width: -webkit-fill-available"> {{ body.name }} - + @for (tag of body.tags; track $index) { + + }
diff --git a/desktop/src/app/calculator/formula/formula.component.html b/desktop/src/app/calculator/formula/formula.component.html index 195f31e38..61d860467 100644 --- a/desktop/src/app/calculator/formula/formula.component.html +++ b/desktop/src/app/calculator/formula/formula.component.html @@ -1,8 +1,8 @@

{{ formula.description }}

- +
@for (item of formula.operands; track $index) { diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index 830ef1a26..6dc25d84a 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -307,55 +307,45 @@
- - + - + - + - + - + - + + (action)="openRotator(preference.rotator)" />
@if (pausingOrPaused) { diff --git a/desktop/src/app/filterwheel/filterwheel.component.html b/desktop/src/app/filterwheel/filterwheel.component.html index d4e6046d8..63354930a 100644 --- a/desktop/src/app/filterwheel/filterwheel.component.html +++ b/desktop/src/app/filterwheel/filterwheel.component.html @@ -23,13 +23,12 @@ class="col-12 pt-0 text-sm text-gray-400 flex align-items-center my-1 gap-1"> {{ moving ? 'moving' : 'idle' }} - - + @if (wheel.connected && currentFilter) { + @if (currentFilter.position) { + + } + + }
@@ -51,16 +50,13 @@ - - - + @if (filter) { + + + @if (filter.dark) { + + } + } {{ filter?.name }}
@@ -72,13 +68,11 @@ - - + + + class="mdi mdi-camera-iris text-gray-300"> {{ item.name }}
diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index 529d4f1ff..a65eb7aaa 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -1051,37 +1051,17 @@
- - - - - - - + + + + + + + @if (item.computed) { - - - + + + }
diff --git a/desktop/src/shared/components/switch.component.ts b/desktop/src/shared/components/switch.component.ts index 5d1024110..e69a51531 100644 --- a/desktop/src/shared/components/switch.component.ts +++ b/desktop/src/shared/components/switch.component.ts @@ -12,7 +12,6 @@ import { InputSwitchChangeEvent } from 'primeng/inputswitch' [(ngModel)]="value" />
`, - styles: ``, encapsulation: ViewEncapsulation.None, }) export class SwitchComponent { diff --git a/desktop/src/shared/components/tag.component.ts b/desktop/src/shared/components/tag.component.ts new file mode 100644 index 000000000..34ca5cdc0 --- /dev/null +++ b/desktop/src/shared/components/tag.component.ts @@ -0,0 +1,74 @@ +import { Component, ElementRef, inject, input, output, ViewEncapsulation } from '@angular/core' + +export type TagSeverity = 'success' | 'secondary' | 'info' | 'warning' | 'danger' | 'contrast' | undefined + +export type TagSize = 'large' | 'normal' + +@Component({ + selector: 'neb-tag, neb-info, neb-success, neb-warn, neb-error', + template: ` + + `, + styles: ` + neb-tag, + neb-info, + neb-success, + neb-warn, + neb-error { + display: contents; + + .p-element { + display: contents; + } + + .p-tag { + border-radius: 2px; + padding: 1.5px 4px; + display: inline-block; + min-height: 12.1px; + + &.large { + font-size: 1.2rem; + line-height: 15px; + padding: 3px 8px; + } + + .p-tag-icon, + .p-tag-value { + line-height: 12.1px; + vertical-align: middle; + } + + .p-tag-icon { + &.mdi::before { + font-size: 0.8rem; + } + } + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class TagComponent { + private readonly elementRef = inject(ElementRef) + + readonly label = input() + readonly icon = input() + readonly disabled = input(false) + readonly size = input('normal') + readonly action = output() + readonly severity = input(this.severityFromTagName((this.elementRef.nativeElement as HTMLElement).tagName.toLowerCase())) + + private severityFromTagName(tagName: string): TagSeverity { + if (tagName.endsWith('-info')) return 'info' + else if (tagName.endsWith('-success')) return 'success' + else if (tagName.endsWith('-warn')) return 'warning' + else if (tagName.endsWith('-error')) return 'danger' + return undefined + } +} diff --git a/desktop/src/styles.scss b/desktop/src/styles.scss index 5dc7cdafd..749071bc2 100644 --- a/desktop/src/styles.scss +++ b/desktop/src/styles.scss @@ -199,18 +199,6 @@ p-calendar.border-0 .p-calendar-w-btn { opacity: 1; } -.p-tag { - border-radius: 2px; - padding: 1px 4px; - display: flex; - min-height: 1rem; - - .p-tag-icon, - .p-tag-value { - line-height: normal; - } -} - .text-overflow-scroll { display: inline-block; white-space: nowrap; From f808c54317ee800a5cbd36cff93354fb76914163 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Tue, 3 Dec 2024 09:52:36 -0300 Subject: [PATCH 07/30] [desktop]: Migrate to new control flow --- desktop/src/app/about/about.component.html | 15 +- .../app/alignment/alignment.component.html | 35 +- desktop/src/app/app.component.html | 80 +-- desktop/src/app/atlas/atlas.component.html | 136 ++--- .../calculator/formula/formula.component.html | 16 +- .../calibration/calibration.component.html | 14 +- desktop/src/app/camera/camera.component.html | 320 ++++++------ .../filterwheel/filterwheel.component.html | 130 ++--- .../src/app/focuser/focuser.component.html | 12 +- desktop/src/app/home/home.component.html | 63 +-- desktop/src/app/image/image.component.html | 415 ++++++++-------- desktop/src/app/indi/indi.component.html | 37 +- .../property/indi-property.component.html | 187 +++---- desktop/src/app/mount/mount.component.html | 64 +-- .../src/app/rotator/rotator.component.html | 22 +- .../app/sequencer/sequencer.component.html | 209 ++++---- .../src/app/settings/settings.component.html | 463 +++++++++--------- .../camera-exposure.component.html | 50 +- .../camera-info/camera-info.component.html | 162 +++--- .../dialog-menu/dialog-menu.component.html | 21 +- .../components/location/location.dialog.html | 20 +- .../menu-bar/menu-bar.component.html | 107 ++-- .../slide-menu/slide-menu.component.html | 11 +- 23 files changed, 1316 insertions(+), 1273 deletions(-) diff --git a/desktop/src/app/about/about.component.html b/desktop/src/app/about/about.component.html index 13323977e..68b8b481d 100644 --- a/desktop/src/app/about/about.component.html +++ b/desktop/src/app/about/about.component.html @@ -54,13 +54,14 @@
- @for (dep of dependencies; track $index) { - - {{ dep.name }} ({{ dep.version }}) - + @for (dep of dependencies; track dep.name) { + @if (dep.link) { + + {{ dep.name }} ({{ dep.version }}) + + } }
diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 37fc2fbce..474e0e202 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -40,17 +40,18 @@ #cameraExposure [info]="status" /> -
- - -
+ @if (method === 'TPPA') { +
+ + +
+ }
@@ -145,13 +146,13 @@ (action)="tppaStart()" icon="mdi mdi-play" severity="success" /> + } @else { + } - - -
{{ title }}
-
{{ subTitle }}
-
- - - - - - - - +@if (showTopBar) { +
+ +
{{ title }}
+
{{ subTitle }}
+
+ @if (topMenu.length) { + + } + @if (!modal) { + @if (topMenu.length) { + + } + @if (pinned) { + + } @else { + + } + + @if (maximizable) { + + } + } + +
+}
diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index 76cab89fc..d1cbb2c8c 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -21,28 +21,28 @@ -
- -
- @for (season of sun.seasons; track $index) { -
- - - {{ seasonName(season.name) | uppercase }} - - {{ season.dateTime | date: 'MM-dd HH:mm' }} -
- } + @if (sun.seasons.length) { +
+ +
+ @for (season of sun.seasons; track $index) { +
+ + + {{ seasonName(season.name) | uppercase }} + + {{ season.dateTime | date: 'MM-dd HH:mm' }} +
+ } +
-
+ }
-
-
-
- Diameter - {{ moon.phases.current.diameter }} arcsec - {{ (moon.phases.current.diameter / 60).toFixed(2) }} arcmin -
-
- Age - {{ moon.phases.current.age }} d -
-
- Lunation - {{ moon.phases.current.lunation }} -
-
- Sub-Solar Lon / Lat - {{ moon.phases.current.subSolarLon }}° / {{ moon.phases.current.subSolarLat }}° -
-
- Sub-Earth Lon / Lat - {{ moon.phases.current.subEarthLon }}° / {{ moon.phases.current.subEarthLat }}° -
-
- Position Angle - {{ moon.phases.current.posAngle }}° + @if (moon.phases) { +
+
+
+ Diameter + {{ moon.phases.current.diameter }} arcsec + {{ (moon.phases.current.diameter / 60).toFixed(2) }} arcmin +
+
+ Age + {{ moon.phases.current.age }} d +
+
+ Lunation + {{ moon.phases.current.lunation }} +
+
+ Sub-Solar Lon / Lat + {{ moon.phases.current.subSolarLon }}° / {{ moon.phases.current.subSolarLat }}° +
+
+ Sub-Earth Lon / Lat + {{ moon.phases.current.subEarthLon }}° / {{ moon.phases.current.subEarthLat }}° +
+
+ Position Angle + {{ moon.phases.current.posAngle }}° +
+
-
- - NASA/SVS - +
+ @for (phase of moon.phases.phases; track $index) { +
+ + @let phaseIcon = phase.name === 'NEW_MOON' ? 'new' : phase.name === 'FIRST_QUARTER' ? 'first-quarter' : phase.name === 'FULL_MOON' ? 'full' : 'last-quarter'; + + {{ phase.name | enum | uppercase }} + + {{ phase.dateTime | date: 'dd HH:mm' }} +
+ }
-
- @for (phase of moon.phases.phases; track $index) { -
- - @let phaseIcon = phase.name === 'NEW_MOON' ? 'new' : phase.name === 'FIRST_QUARTER' ? 'first-quarter' : phase.name === 'FULL_MOON' ? 'full' : 'last-quarter'; - - {{ phase.name | enum | uppercase }} - - {{ phase.dateTime | date: 'dd HH:mm' }} -
- } -
-
+ }
- @for (item of formula.operands; track $index) { + @for (item of formula.operands; track item.label) {
{{ item.prefix }} @@ -34,10 +34,10 @@ [fractionDigits]="formula.result.maxFractionDigits ?? 4" /> {{ formula.result.suffix }}
-
- -
+@if (formula.tip) { +
+ +
+} diff --git a/desktop/src/app/calibration/calibration.component.html b/desktop/src/app/calibration/calibration.component.html index b58762f8e..75995c682 100644 --- a/desktop/src/app/calibration/calibration.component.html +++ b/desktop/src/app/calibration/calibration.component.html @@ -1,7 +1,7 @@
- @for (key of groups; track $index) { + @for (key of groups; track key) { @let value = frames.get(key) ?? [];
@@ -56,12 +56,12 @@ {{ item.exposureTime | exposureTime }} {{ item.width }}x{{ item.height }} {{ item.binX }}x{{ item.binY }} - GAIN: {{ item.gain }} - - {{ item.temperature }}°C - + @if (item.gain) { + GAIN: {{ item.gain }} + } + @if (item.temperature < 100 && item.temperature > -100) { + {{ item.temperature }}°C + }
{{ item.path }}
diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index 6dc25d84a..5744e60d5 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -24,86 +24,92 @@ icon="mdi mdi-image-multiple" (action)="openCameraImage()" tooltip="View image" /> - - -
-
- - - - - - - - - {{ preference.request.savePath || camera.capturesPath }} - -
-
- + @if (hasCalibration) { + + } + @if (canShowMenu) { + + }
+ @if (canShowSavePath) { +
+ @if (request.autoSave) { + + } @else { + + } + @if (request.autoSubFolderMode === 'OFF') { + + } @else if (request.autoSubFolderMode === 'NOON') { + + } @else if (request.autoSubFolderMode === 'MIDNIGHT') { + + } + @if (camera && (preference.request.savePath || camera.capturesPath)) { + + + @if (preference.request.savePath || camera.capturesPath) { + + } + {{ preference.request.savePath || camera.capturesPath }} + + } +
+ } + @if (canShowInfo) { +
+ +
+ }
@@ -307,84 +313,96 @@
- - - - - - - + @if (hasCalibration) { + + } + @if (hasDither) { + + } + @if (hasLiveStacking) { + + } + @if (preference.mount) { + + } + @if (preference.focuser) { + + } + @if (preference.wheel) { + + } + @if (preference.rotator) { + + }
@if (pausingOrPaused) { - + @if (canStartOrAbort) { + + } } @else if (!running) { + @if (canStartOrAbort) { + + } + } + @if (canStartOrAbort && running && !pausingOrPaused) { + label="Pause" + (action)="pauseCapture()" + icon="mdi mdi-pause" + severity="info" /> + } + @if (canStartOrAbort) { + + } + @if (canSave) { + } - - -
diff --git a/desktop/src/app/filterwheel/filterwheel.component.html b/desktop/src/app/filterwheel/filterwheel.component.html index 63354930a..282f12c76 100644 --- a/desktop/src/app/filterwheel/filterwheel.component.html +++ b/desktop/src/app/filterwheel/filterwheel.component.html @@ -18,18 +18,18 @@ tooltip="Connect" /> }
-
- - {{ moving ? 'moving' : 'idle' }} - @if (wheel.connected && currentFilter) { - @if (currentFilter.position) { - + @if (canShowInfo) { +
+ + {{ moving ? 'moving' : 'idle' }} + @if (wheel.connected && currentFilter) { + @if (currentFilter.position) { + + } + } - - } -
+
+ }
@@ -70,9 +70,9 @@ style="min-height: 15px"> - + @if (item.dark) { + + } {{ item.name }}
@@ -89,57 +89,57 @@ (action)="moveToSelectedFilter()" />
-
-
- -
-
- -
-
-
-
- - + @if (filter) { + @if (canEdit) { +
+
+ +
+
+ +
+
+ } +
+
+ + +
-
-
-
- + } + @if (canApply) { +
+
+ +
-
+ }
diff --git a/desktop/src/app/focuser/focuser.component.html b/desktop/src/app/focuser/focuser.component.html index 02b7498f7..4df6df5ac 100644 --- a/desktop/src/app/focuser/focuser.component.html +++ b/desktop/src/app/focuser/focuser.component.html @@ -23,12 +23,12 @@ {{ focuser.moving ? 'moving' : 'idle' }}
-
- - {{ focuser.temperature | number: '1.2-2' }}°C -
+ @if (focuser.hasThermometer) { +
+ + {{ focuser.temperature | number: '1.2-2' }}°C +
+ }
diff --git a/desktop/src/app/home/home.component.html b/desktop/src/app/home/home.component.html index 794fd14c7..a44d70672 100644 --- a/desktop/src/app/home/home.component.html +++ b/desktop/src/app/home/home.component.html @@ -50,40 +50,41 @@ - - + @if (!connected) { + + } @else { + + }
-
-
-
- New version: - {{ newVersion }} + @if (newVersion) { +
+
+
+ New version: + {{ newVersion }} +
+ + +
- - -
-
+ }
- + @if (preference.crossHair && zoom.panZoom) { + + } - - - - - {{ (a.star ?? a.dso ?? a.minorPlanet)?.name?.join(' · ') }} - - - + @if (!transformation.mirrorHorizontal && !transformation.mirrorVertical && annotation.visible) { + + @for (a of annotation.displayOnlyFiltered ? annotation.filtered : annotation.data; track a) { + + + + {{ (a.star ?? a.dso ?? a.minorPlanet)?.name?.join(' · ') }} + + + } + + } - - - - - {{ s.hfd.toFixed(1) }} - - - + @if (!transformation.mirrorHorizontal && !transformation.mirrorVertical && starDetector.visible) { + + @for (s of starDetector.stars; track s) { + + + + {{ s.hfd.toFixed(1) }} + + + } + + } - - @for (item of fov.fovs; track $index) { - @if (item.enabled && item.computed) { - + @if (imageInfo) { + + @for (item of fov.fovs; track $index) { + @if (item.enabled && item.computed) { + + } } - } - + + }
- + @if (hasROI) { + + }
-
- X: {{ imageROI.area.x.toFixed(0) }} Y: {{ imageROI.area.y.toFixed(0) }} W: {{ imageROI.area.width.toFixed(0) }} H: {{ imageROI.area.height.toFixed(0) }} - -
+@if (hasROI) { +
+ X: {{ imageROI.area.x.toFixed(0) }} Y: {{ imageROI.area.y.toFixed(0) }} W: {{ imageROI.area.width.toFixed(0) }} H: {{ imageROI.area.height.toFixed(0) }} + +
+}
- + @if (astronomicalObject.info) {
-
- -
-
- -
-
- -
-
- + @if (astronomicalObject.info.constellation) { +
+ +
+ } + @if (astronomicalObject.info.magnitude) { +
+ +
+ } + @if (astronomicalObject.info.type) { +
+ +
+ } + @if (astronomicalObject.info.distance) { +
+ +
+ } + } + @if (astronomicalObject.info?.type) { + - - + }
@@ -832,24 +838,24 @@
-
- -
-
- -
+ @if (starDetector.request.type !== 'SIRIL') { +
+ +
+ } + @if (starDetector.request.type === 'SIRIL') { +
+ +
+ }
COMPUTED
@@ -1037,47 +1043,48 @@ tooltip="Add" (action)="addFOV()" />
-
- @for (item of fov.fovs; track $index) { -
-
- -
-
- - - - - - - - @if (item.computed) { - - - - } -
-
- - + @if (fov.fovs.length) { +
+ @for (item of fov.fovs; track $index) { +
+
+ +
+
+ + + + + + + + @if (item.computed) { + + + + } +
+
+ + +
-
- } -
+ } +
+ }
@@ -1325,17 +1332,17 @@
-
-
-
X: {{ mouseCoordinate.x }}
-
Y: {{ mouseCoordinate.y }}
-
α: {{ mouseCoordinate.alpha }}
-
δ: {{ mouseCoordinate.delta }}
-
l: {{ mouseCoordinate.l }}
-
b: {{ mouseCoordinate.b }}
+@if (mouseCoordinate && isMouseCoordinateVisible) { +
+
+
X: {{ mouseCoordinate.x }}
+
Y: {{ mouseCoordinate.y }}
+
α: {{ mouseCoordinate.alpha }}
+
δ: {{ mouseCoordinate.delta }}
+
l: {{ mouseCoordinate.l }}
+
b: {{ mouseCoordinate.b }}
+
-
+} diff --git a/desktop/src/app/indi/indi.component.html b/desktop/src/app/indi/indi.component.html index 6ffcab6d3..ffaf614f1 100644 --- a/desktop/src/app/indi/indi.component.html +++ b/desktop/src/app/indi/indi.component.html @@ -30,23 +30,26 @@
-
- -
-
- -
+ @for (property of properties; track property.name) { +
+ @if (!showLog && property.group === group) { + + } +
+ } + @if (showLog) { +
+ +
+ }
diff --git a/desktop/src/app/indi/property/indi-property.component.html b/desktop/src/app/indi/property/indi-property.component.html index 9c6cbc287..dcfaa24bf 100644 --- a/desktop/src/app/indi/property/indi-property.component.html +++ b/desktop/src/app/indi/property/indi-property.component.html @@ -4,103 +4,108 @@ {{ property.label }}
-
- -
-
- -
-
- -
-
-
-
-
- + @for (item of property.items; track item.name) { + -
-
- -
+ (action)="sendSwitch(item)" + icon="mdi mdi-{{ item.value ? 'check' : 'close' }}" + [severity]="item.value ? 'success' : 'danger'" /> + }
-
-
- -
-
-
-
-
-
- + @for (item of property.items; track item.name) { + -
-
- + } +
+ } + @if (property.rule === 'ANY_OF_MANY') { +
+ @for (item of property.items; track item.name) { + -
+ (action)="sendSwitch(item)" + icon="mdi mdi-{{ item.value ? 'check' : 'close' }}" + [severity]="item.value ? 'success' : 'danger'" /> + } +
+ } + } @else if (property.type === 'NUMBER') { +
+
+ @for (item of property.items; track item.name) { +
+ @if (property.perm !== 'WO') { +
+ +
+ } + @if (property.perm !== 'RO') { +
+ +
+ } +
+ } +
+
+ @if (property.perm !== 'RO') { + + }
-
- + } @else if (property.type === 'TEXT') { +
+
+ @for (item of property.items; track item.name) { +
+ @if (property.perm !== 'WO') { +
+ +
+ } + @if (property.perm !== 'RO') { +
+ +
+ } +
+ } +
+
+ @if (property.perm !== 'RO') { + + } +
-
+ }
diff --git a/desktop/src/app/mount/mount.component.html b/desktop/src/app/mount/mount.component.html index c56959be6..e5b7cd7d6 100644 --- a/desktop/src/app/mount/mount.component.html +++ b/desktop/src/app/mount/mount.component.html @@ -244,20 +244,21 @@ (valueChange)="trackingToggled()" />
- - + @if (mount.parked) { + + } @else { + + }
- - Use together with the - - Stellarium Mobile Plus - - - - Use together with the - - Stellarium - - + @if (remoteControl.protocol === 'LX200') { + + Use together with the + + Stellarium Mobile Plus + + + } @else if (remoteControl.protocol === 'STELLARIUM') { + + Use together with the + + Stellarium + + + }
-
-
- + @if (canApply) { +
+
+ +
-
+ }
diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index 533438cb5..a170339ab 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -99,100 +99,103 @@ (cdkDropListDropped)="drop($event)" class="grid px-4 mt-1 flex align-items-center gap-0 overflow-y-auto" style="max-height: calc(100vh - 200px)"> - - -
-
- #{{ i + 1 }} + @for (sequence of plan.sequences; track sequence; let i = $index) { + + +
+
+ #{{ i + 1 }} +
+
+ + + + @if (plan.liveStacking.enabled) { + + @if (plan.liveStacking.useCalibrationGroup) { + + } + } +
+
+ + + + +
-
- - - - - + +
+
+
-
- - - - +
+
- -
-
- -
-
- -
-
- + + }
@@ -494,13 +497,13 @@ (action)="start()" icon="mdi mdi-play" severity="success" /> + } @else if (canStart) { + } -
-
- -
+ @if (plan.liveStacking.enabled) { +
+ +
+ }
-
-
-
- + @if (tab === 'GENERAL') { +
+
+
+ +
-
-
-
-
- - - -
- {{ preference.location.name || '?' }} -
-
-
- -
-
- - + } @else if (tab === 'LOCATION') { +
+
+
+ + + +
+ {{ preference.location.name || '?' }} +
+
+
+ +
+
+ + +
+
+
+
-
-
-
-
-
-
-
- - - - -
-
- -
- @if (plateSolverType === 'ASTROMETRY_NET_ONLINE') { + } @else if (tab === 'PLATE_SOLVER') { +
+
- -
-
- + + + +
- } - @if (plateSolverType !== 'PIXINSIGHT') { + @if (plateSolverType !== 'ASTROMETRY_NET_ONLINE') { +
+ +
+ } @else { +
+ +
+
+ +
+ } + @if (plateSolverType !== 'PIXINSIGHT') { +
+ +
+
+ +
+ } @else { +
+ +
+ } +
+
+ } @else if (tab === 'STAR_DETECTOR') { +
+
- + + + +
-
- +
+
- } - @if (plateSolverType === 'PIXINSIGHT') {
+ [max]="300" />
- } -
-
-
-
-
- - - - -
-
- -
-
- -
-
- + @if (starDetectorType === 'PIXINSIGHT') { +
+ +
+ }
-
-
-
-
- - - - -
-
- -
-
- + } @else if (tab === 'LIVE_STACKER') { +
+
+
+ + + + +
+
+ +
+ @if (liveStackerType === 'PIXINSIGHT') { +
+ +
+ }
-
-
-
-
- - -
-
- - -
-
- - -
-
- - + } @else if (tab === 'CAPTURE_NAMING_FORMAT') { +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
-
+ }
{{ capture.count }} - / {{ capture.amount }} + @if (!capture.looping) { + / {{ capture.amount }} + } @if (!capture.looping) { @@ -25,18 +27,17 @@ - - - {{ capture.remainingTime | exposureTime }} - - - - {{ capture.elapsedTime | exposureTime }} - + @if (showRemainingTime) { + + + {{ capture.remainingTime | exposureTime }} + + } @else { + + + {{ capture.elapsedTime | exposureTime }} + + } } @@ -44,18 +45,17 @@ - - - {{ step.remainingTime | exposureTime }} - - - - {{ step.elapsedTime | exposureTime }} - + @if (showRemainingTime) { + + + {{ step.remainingTime | exposureTime }} + + } @else { + + + {{ step.elapsedTime | exposureTime }} + + } diff --git a/desktop/src/shared/components/camera-info/camera-info.component.html b/desktop/src/shared/components/camera-info/camera-info.component.html index 8aa2004d4..05761a7ab 100644 --- a/desktop/src/shared/components/camera-info/camera-info.component.html +++ b/desktop/src/shared/components/camera-info/camera-info.component.html @@ -1,86 +1,88 @@
-
- - {{ info.frameType }} -
-
- - {{ info.exposureAmount || '∞' }} / {{ info.exposureTime | exposureTime }} -
-
- - {{ info.exposureDelay * 1000000 | exposureTime }} -
-
- - {{ info.x }} {{ info.y }} {{ info.width }} {{ info.height }} -
-
- - {{ info.binX }}x{{ info.binY }} -
-
- - {{ info.gain }} -
-
- - {{ info.offset }} -
-
- - {{ info.frameFormat }} -
-
+ @if (hasType) {
- - {{ filter }} + + {{ info.frameType }}
- -
-
- - {{ info.focusOffset }} -
-
+ } + @if (hasExposure && info.exposureTime) {
- - {{ info.angle.toFixed(1) }}° + + {{ info.exposureAmount || '∞' }} / {{ info.exposureTime | exposureTime }}
- -
+ } + @if (info.exposureDelay) { +
+ + {{ info.exposureDelay * 1000000 | exposureTime }} +
+ } + @if (info.x !== undefined && info.y !== undefined && info.width && info.height) { +
+ + {{ info.x }} {{ info.y }} {{ info.width }} {{ info.height }} +
+ } + @if (info.binX && info.binY) { +
+ + {{ info.binX }}x{{ info.binY }} +
+ } + @if (info.gain) { +
+ + {{ info.gain }} +
+ } + @if (info.offset) { +
+ + {{ info.offset }} +
+ } + @if (info.frameFormat) { +
+ + {{ info.frameFormat }} +
+ } + @if (hasFilter) { +
+
+ + {{ filter }} +
+ @if (canRemoveFilter && !disabled) { + + } +
+ } + @if (hasFilter && focuser && info.focusOffset) { +
+ + {{ info.focusOffset }} +
+ } + @if (rotator && info.angle >= 0) { +
+
+ + {{ info.angle.toFixed(1) }}° +
+ @if (canRemoveAngle && !disabled) { + + } +
+ }
diff --git a/desktop/src/shared/components/dialog-menu/dialog-menu.component.html b/desktop/src/shared/components/dialog-menu/dialog-menu.component.html index 69c950f67..00e126d90 100644 --- a/desktop/src/shared/components/dialog-menu/dialog-menu.component.html +++ b/desktop/src/shared/components/dialog-menu/dialog-menu.component.html @@ -9,15 +9,14 @@ [draggable]="false" (onHide)="hide()" [style]="{ width: 'auto' }"> - - {{ currentHeader }} - - + @if (currentHeader) { + {{ currentHeader }} + } + @if (visible) { + + } diff --git a/desktop/src/shared/components/location/location.dialog.html b/desktop/src/shared/components/location/location.dialog.html index 8db5b32e0..38972432d 100644 --- a/desktop/src/shared/components/location/location.dialog.html +++ b/desktop/src/shared/components/location/location.dialog.html @@ -48,13 +48,13 @@ (longitudeChange)="locationChanged()" />
- +@if (isDialog) { + +} diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.html b/desktop/src/shared/components/menu-bar/menu-bar.component.html index 1b4c4a781..794918d98 100644 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.html +++ b/desktop/src/shared/components/menu-bar/menu-bar.component.html @@ -1,57 +1,58 @@
- - @if (item.visible !== false) { - @if (item.toggleable) { -
- + @if (item.visible !== false) { + @if (item.toggleable) { + @if (item.visible) { +
+ +
+ } + } @else if (item.checkable) { + @if (item.visible) { +
+ +
+ } + } @else if (item.label && item.splitButtonMenu?.length) { + -
- } @else if (item.checkable) { -
- -
- } @else if (item.label && item.splitButtonMenu?.length) { - - } @else { - - + [icon]="item.icon" + [model]="item.splitButtonMenu" + [severity]="item.severity" + [disabled]="item.disabled" + [pTooltip]="item.tooltip" + [tooltipPosition]="item.tooltipPosition ?? 'bottom'" + size="small" + (onClick)="splitButtonClick.emit({ item, event: $event })" + appendTo="body" /> + } @else { + @if (item.badge) { + + } + + } } - } -
+ + }
diff --git a/desktop/src/shared/components/slide-menu/slide-menu.component.html b/desktop/src/shared/components/slide-menu/slide-menu.component.html index 4d57c46ce..6a3ffe07d 100644 --- a/desktop/src/shared/components/slide-menu/slide-menu.component.html +++ b/desktop/src/shared/components/slide-menu/slide-menu.component.html @@ -9,9 +9,10 @@ - + @if (currentMenu !== model) { + + }
From 0845e393e60923fccbac066fad02302d1f1332aa Mon Sep 17 00:00:00 2001 From: tiagohm Date: Tue, 3 Dec 2024 09:53:05 -0300 Subject: [PATCH 08/30] [desktop]: Use neb-button on neb-device-chooser --- desktop/src/shared/components/button.component.ts | 7 +++++-- .../device-chooser/device-chooser.component.html | 9 ++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/desktop/src/shared/components/button.component.ts b/desktop/src/shared/components/button.component.ts index 6524fb9ba..1b8f70745 100644 --- a/desktop/src/shared/components/button.component.ts +++ b/desktop/src/shared/components/button.component.ts @@ -5,7 +5,7 @@ import { Component, input, output, ViewEncapsulation } from '@angular/core' template: ` + styleClass="white-space-nowrap select-none cursor-pointer"> + + `, styles: ` neb-button { @@ -37,6 +39,7 @@ export class ButtonComponent { readonly icon = input() readonly tooltip = input() readonly tooltipPosition = input<'right' | 'left' | 'top' | 'bottom'>('bottom') + readonly rounded = input(true) readonly disabled = input(false) readonly severity = input<'success' | 'info' | 'warning' | 'danger' | 'help' | 'primary' | 'secondary' | 'contrast'>() readonly action = output() diff --git a/desktop/src/shared/components/device-chooser/device-chooser.component.html b/desktop/src/shared/components/device-chooser/device-chooser.component.html index 34892b60a..4b565312b 100644 --- a/desktop/src/shared/components/device-chooser/device-chooser.component.html +++ b/desktop/src/shared/components/device-chooser/device-chooser.component.html @@ -1,8 +1,7 @@ -
@@ -15,7 +14,7 @@ }
- + Date: Wed, 4 Dec 2024 17:26:20 -0300 Subject: [PATCH 09/30] [desktop]: Encapsulate p-dropdown into neb-dropdown-enum --- .../app/alignment/alignment.component.html | 48 +++++--------- desktop/src/app/app.module.ts | 2 + desktop/src/app/atlas/atlas.component.html | 40 ++++------- .../app/autofocus/autofocus.component.html | 48 +++++--------- desktop/src/app/camera/camera.component.html | 36 ++++------ .../filterwheel/filterwheel.component.html | 2 +- .../src/app/framing/framing.component.html | 2 +- desktop/src/app/guider/guider.component.html | 32 +++------ desktop/src/app/home/home.component.html | 2 +- desktop/src/app/image/image.component.html | 66 ++++++------------- desktop/src/app/indi/indi.component.html | 2 +- desktop/src/app/mount/mount.component.html | 19 ++---- .../app/sequencer/sequencer.component.html | 50 +++++--------- .../src/app/settings/settings.component.html | 44 ++++--------- .../shared/components/dropdown.component.ts | 34 ++++++++++ .../menu-bar/menu-bar.component.html | 2 +- desktop/src/shared/pipes/enum.pipe.ts | 8 ++- desktop/src/shared/types/mount.types.ts | 2 +- 18 files changed, 171 insertions(+), 268 deletions(-) create mode 100644 desktop/src/shared/components/dropdown.component.ts diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 474e0e202..7b9d111e7 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -60,17 +60,11 @@
- - - - +
- - - - +
@@ -189,17 +177,11 @@ label="Drift for" />
- - - - +
diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 579bf3e45..04a6f2e6c 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -54,6 +54,7 @@ import { DeviceChooserComponent } from '../shared/components/device-chooser/devi import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' import { DeviceNameComponent } from '../shared/components/device-name/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' +import { DropdownEnumComponent } from '../shared/components/dropdown.component' import { HistogramComponent } from '../shared/components/histogram/histogram.component' import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' @@ -131,6 +132,7 @@ import { SettingsComponent } from './settings/settings.component' DeviceListMenuComponent, DeviceNameComponent, DialogMenuComponent, + DropdownEnumComponent, DropdownOptionsPipe, DustCapComponent, EnumDropdownPipe, diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index d1cbb2c8c..9f17a5e76 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -643,34 +643,20 @@ [(value)]="skyObject.search.filter.radius" />
- - @let constellations = ['ALL'].concat('CONSTELLATION' | dropdownOptions); - - - + @let constellations = ['ALL'].concat('CONSTELLATION' | dropdownOptions); +
- - @let skyObjectTypes = ['ALL'].concat('SKY_OBJECT_TYPE' | dropdownOptions); - - - + @let skyObjectTypes = ['ALL'].concat('SKY_OBJECT_TYPE' | dropdownOptions); +
diff --git a/desktop/src/app/autofocus/autofocus.component.html b/desktop/src/app/autofocus/autofocus.component.html index 41eb6d979..88c9db393 100644 --- a/desktop/src/app/autofocus/autofocus.component.html +++ b/desktop/src/app/autofocus/autofocus.component.html @@ -75,30 +75,18 @@ (valueChange)="savePreference()" />
- - - - +
- - - - +
- - - - +
- - - - +
@@ -481,18 +475,12 @@
- - - - +
diff --git a/desktop/src/app/framing/framing.component.html b/desktop/src/app/framing/framing.component.html index bd48072cd..ca13f7a6f 100644 --- a/desktop/src/app/framing/framing.component.html +++ b/desktop/src/app/framing/framing.component.html @@ -56,7 +56,7 @@ [(ngModel)]="preference.hipsSurvey" (ngModelChange)="savePreference()" styleClass="border-0" - emptyMessage="No HiPS survey found" + emptyMessage="No HiPS survey available" [autoDisplayFirst]="false">
- - - - +
- - - - +
diff --git a/desktop/src/app/home/home.component.html b/desktop/src/app/home/home.component.html index a44d70672..6c387232e 100644 --- a/desktop/src/app/home/home.component.html +++ b/desktop/src/app/home/home.component.html @@ -13,7 +13,7 @@ [(ngModel)]="connection" styleClass="border-0 p-inputtext-sm w-full" [autoDisplayFirst]="false" - emptyMessage="No connection found"> + emptyMessage="No connection available"> diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index ab71f8fac..55e25aa69 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -414,18 +414,11 @@ class="pointer-events-none">
- - - - +
- - - - +
- - - - +
@if (starDetector.request.type !== 'SIRIL') {
@@ -1240,18 +1219,11 @@
}
- - - - +
diff --git a/desktop/src/app/mount/mount.component.html b/desktop/src/app/mount/mount.component.html index e5b7cd7d6..c9a3be77e 100644 --- a/desktop/src/app/mount/mount.component.html +++ b/desktop/src/app/mount/mount.component.html @@ -267,17 +267,12 @@ severity="info" />
- - - - +
@@ -288,7 +283,7 @@ (ngModelChange)="slewRateChanged()" [autoDisplayFirst]="false" styleClass="p-inputtext-sm border-0" - emptyMessage="No rate found" /> + emptyMessage="No rate available" />
diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index a170339ab..d81092edc 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -131,14 +131,11 @@ [severity]="plan.rotator?.connected ? 'success' : 'danger'" (action)="showRotatorDialog(sequence)" /> @if (plan.liveStacking.enabled) { - + [options]="'IMAGE_FILTER_TYPE' | dropdownOptions" + [(value)]="sequence.stackerGroupType" + (valueChange)="savePreference()" /> @if (plan.liveStacking.useCalibrationGroup) { - - - - +
- - - - +
@@ -57,16 +57,10 @@
- - - - +
@if (plateSolverType !== 'ASTROMETRY_NET_ONLINE') {
@@ -125,16 +119,10 @@
- - - - +
- - - - +
+ + + + `, + styles: ` + neb-dropdown-enum { + width: 100%; + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class DropdownEnumComponent { + readonly label = input() + readonly options = input([]) + readonly value = model() + readonly filter = input(false) + readonly disabled = input(false) + readonly emptyMessage = input('Not available') +} diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.html b/desktop/src/shared/components/menu-bar/menu-bar.component.html index 794918d98..da3d2c17d 100644 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.html +++ b/desktop/src/shared/components/menu-bar/menu-bar.component.html @@ -1,5 +1,5 @@
- @for (item of model; track item.label; let i = $index) { + @for (item of model; track item; let i = $index) { @if (item.visible !== false) { @if (item.toggleable) { diff --git a/desktop/src/shared/pipes/enum.pipe.ts b/desktop/src/shared/pipes/enum.pipe.ts index 9f6862dc8..53f75a933 100644 --- a/desktop/src/shared/pipes/enum.pipe.ts +++ b/desktop/src/shared/pipes/enum.pipe.ts @@ -7,7 +7,7 @@ import { DeviceType } from '../types/device.types' import { FlatWizardState } from '../types/flat-wizard.types' import { GuideDirection, GuideState, GuiderPlotMode, GuiderYAxisUnit } from '../types/guider.types' import { Bitpix, ImageChannel, ImageFilterType, SCNRProtectionMethod } from '../types/image.types' -import { MountRemoteControlProtocol } from '../types/mount.types' +import { MountRemoteControlProtocol, TrackMode } from '../types/mount.types' import { PlateSolverType } from '../types/platesolver.types' import { SequencerCaptureMode, SequencerState } from '../types/sequencer.types' import { StarDetectorType } from '../types/stardetector.types' @@ -44,6 +44,7 @@ export type EnumPipeKey = | ImageChannel | MoonPhase | DeviceType + | TrackMode | 'ALL' @Pipe({ name: 'enum' }) @@ -139,6 +140,7 @@ export class EnumPipe implements PipeTransform { CRV: 'Corvus', CUBESAT: 'CubeSats', CURVE_FITTED: 'Curve fitted', + CUSTOM: 'Custom', CVN: 'Canes Venatici', CYG: 'Cygnus', DARK_CLOUD_NEBULA: 'Dark Cloud (nebula)', @@ -249,6 +251,7 @@ export class EnumPipe implements PipeTransform { IRIDIUM_NEXT: 'Iridium NEXT', IRIDIUM: 'Iridium', IRREGULAR_VARIABLE: 'Irregular Variable', + KING: 'King', LAC: 'Lacerta', LAST_30_DAYS: `Last 30 Days' Launches`, LAST_QUARTER: 'Last Quarter', @@ -268,6 +271,7 @@ export class EnumPipe implements PipeTransform { LOW_MASS_X_RAY_BINARY: 'Low Mass X-ray Binary', LOW_SURFACE_BRIGHTNESS_GALAXY: 'Low Surface Brightness Galaxy', LUMINANCE: 'Luminance', + LUNAR: 'Lunar', LUP: 'Lupus', LX200: 'LX200', LYN: 'Lynx', @@ -387,10 +391,12 @@ export class EnumPipe implements PipeTransform { SGE: 'Sagitta', SGR: 'Sagittarius', SHORT: 'Short', + SIDEREAL: 'Sidereal', SINGLE: 'Single', SIRIL: 'Siril', SLEWED: 'Slewed', SLEWING: 'Slewing', + SOLAR: 'Solar', SOLVED: 'Solved', SOLVING: 'Solving', SOUTH: 'South', diff --git a/desktop/src/shared/types/mount.types.ts b/desktop/src/shared/types/mount.types.ts index cd1c34b2f..fd7fab5b9 100644 --- a/desktop/src/shared/types/mount.types.ts +++ b/desktop/src/shared/types/mount.types.ts @@ -7,7 +7,7 @@ export type PierSide = 'EAST' | 'WEST' | 'NEITHER' export type TargetCoordinateType = 'J2000' | 'JNOW' -export type TrackMode = 'SIDEREAL' | ' LUNAR' | 'SOLAR' | 'KING' | 'CUSTOM' +export type TrackMode = 'SIDEREAL' | 'LUNAR' | 'SOLAR' | 'KING' | 'CUSTOM' export type CelestialLocationType = 'ZENITH' | 'NORTH_POLE' | 'SOUTH_POLE' | 'GALACTIC_CENTER' | 'MERIDIAN_EQUATOR' | 'MERIDIAN_ECLIPTIC' | 'EQUATOR_ECLIPTIC' From f0055436de1c252d86a6f50dc1e8f345cbac91c2 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:09:07 -0300 Subject: [PATCH 10/30] [desktop]: Encapsulate p-dropdown into neb-dropdown-item --- .../nebulosa/api/mounts/MountController.kt | 2 +- .../nebulosa/api/mounts/MountMoveTask.kt | 2 +- .../app/alignment/alignment.component.html | 18 +++------ .../src/app/alignment/alignment.component.ts | 2 +- desktop/src/app/app.module.ts | 3 +- desktop/src/app/camera/camera.component.html | 16 +++----- desktop/src/app/mount/mount.component.html | 23 ++++++----- .../app/sequencer/sequencer.component.html | 11 ++---- .../src/app/sequencer/sequencer.component.ts | 2 +- .../shared/components/dropdown.component.ts | 38 +++++++++++++++++++ .../src/shared/pipes/enum-dropdown.pipe.ts | 2 +- desktop/src/shared/services/api.service.ts | 2 +- desktop/src/shared/types/angular.types.ts | 5 --- desktop/src/shared/types/mount.types.ts | 6 +-- .../alpaca/indi/device/mounts/ASCOMMount.kt | 4 +- .../indi/client/device/mount/INDIMount.kt | 6 +-- .../nebulosa/indi/device/mount/SlewRate.kt | 2 +- 17 files changed, 82 insertions(+), 62 deletions(-) diff --git a/api/src/main/kotlin/nebulosa/api/mounts/MountController.kt b/api/src/main/kotlin/nebulosa/api/mounts/MountController.kt index 5601da2e6..9cf50ca60 100644 --- a/api/src/main/kotlin/nebulosa/api/mounts/MountController.kt +++ b/api/src/main/kotlin/nebulosa/api/mounts/MountController.kt @@ -142,7 +142,7 @@ class MountController( val id = pathParameters[ID].notNull() val mount = connectionService.mount(id) ?: return val rate = queryParameters["rate"].notNullOrBlank() - mountService.slewRate(mount, mount.slewRates.first { it.name == rate }) + mountService.slewRate(mount, mount.slewRates.first { it.value == rate }) } private fun move(ctx: RoutingContext) = with(ctx.call) { diff --git a/api/src/main/kotlin/nebulosa/api/mounts/MountMoveTask.kt b/api/src/main/kotlin/nebulosa/api/mounts/MountMoveTask.kt index 4f228bfa7..6b9f83757 100644 --- a/api/src/main/kotlin/nebulosa/api/mounts/MountMoveTask.kt +++ b/api/src/main/kotlin/nebulosa/api/mounts/MountMoveTask.kt @@ -24,7 +24,7 @@ data class MountMoveTask( LOG.d { debug("Mount Move started. mount={}, request={}", mount, request) } mount.slewRates.takeIf { !request.speed.isNullOrBlank() } - ?.find { it.name == request.speed } + ?.find { it.value == request.speed } ?.also { mount.slewRate(it) } start() diff --git a/desktop/src/app/alignment/alignment.component.html b/desktop/src/app/alignment/alignment.component.html index 7b9d111e7..3688976ad 100644 --- a/desktop/src/app/alignment/alignment.component.html +++ b/desktop/src/app/alignment/alignment.component.html @@ -82,18 +82,12 @@ (valueChange)="savePreference()" />
- - - - +
- - - - +
@@ -203,6 +208,7 @@
- - - - +
@if (plan.liveStacking.useCalibrationGroup) { - + [(value)]="sequence.calibrationGroup" + (valueChange)="savePreference()" /> } }
diff --git a/desktop/src/app/sequencer/sequencer.component.ts b/desktop/src/app/sequencer/sequencer.component.ts index a91d1e27b..d1d7d88e7 100644 --- a/desktop/src/app/sequencer/sequencer.component.ts +++ b/desktop/src/app/sequencer/sequencer.component.ts @@ -3,6 +3,7 @@ import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, Q import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' import { DialogMenuComponent } from '../../shared/components/dialog-menu/dialog-menu.component' +import { DropdownItem } from '../../shared/components/dropdown.component' import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' @@ -11,7 +12,6 @@ import { BrowserWindowService } from '../../shared/services/browser-window.servi import { ElectronService } from '../../shared/services/electron.service' import { PreferenceService } from '../../shared/services/preference.service' import { Tickable, Ticker } from '../../shared/services/ticker.service' -import { DropdownItem } from '../../shared/types/angular.types' import { JsonFile } from '../../shared/types/app.types' import { Camera, cameraCaptureNamingFormatWithDefault, FrameType, updateCameraStartCaptureFromCamera } from '../../shared/types/camera.types' import { Focuser } from '../../shared/types/focuser.types' diff --git a/desktop/src/shared/components/dropdown.component.ts b/desktop/src/shared/components/dropdown.component.ts index bf53348d8..de6418d48 100644 --- a/desktop/src/shared/components/dropdown.component.ts +++ b/desktop/src/shared/components/dropdown.component.ts @@ -1,5 +1,42 @@ import { Component, input, model, ViewEncapsulation } from '@angular/core' +export interface DropdownItem { + label: string + value: T +} + +@Component({ + selector: 'neb-dropdown-item', + template: ` + + + + + `, + styles: ` + neb-dropdown-item { + width: 100%; + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class DropdownItemComponent { + readonly label = input() + readonly options = input[]>([]) + readonly value = model() + readonly disabled = input(false) + readonly emptyMessage = input('Not available') +} + @Component({ selector: 'neb-dropdown-enum', template: ` @@ -12,6 +49,7 @@ import { Component, input, model, ViewEncapsulation } from '@angular/core' optionValue="value" styleClass="w-full p-inputtext-sm border-0" [emptyMessage]="emptyMessage()" + [filter]="filter()" [autoDisplayFirst]="false" appendTo="body" /> diff --git a/desktop/src/shared/pipes/enum-dropdown.pipe.ts b/desktop/src/shared/pipes/enum-dropdown.pipe.ts index 9f38969eb..f36c61ac3 100644 --- a/desktop/src/shared/pipes/enum-dropdown.pipe.ts +++ b/desktop/src/shared/pipes/enum-dropdown.pipe.ts @@ -1,5 +1,5 @@ import { Pipe, PipeTransform, inject } from '@angular/core' -import { DropdownItem } from '../types/angular.types' +import { DropdownItem } from '../components/dropdown.component' import { EnumPipe } from './enum.pipe' @Pipe({ name: 'enumDropdown' }) diff --git a/desktop/src/shared/services/api.service.ts b/desktop/src/shared/services/api.service.ts index 63ce56ba5..5ae83a12d 100644 --- a/desktop/src/shared/services/api.service.ts +++ b/desktop/src/shared/services/api.service.ts @@ -159,7 +159,7 @@ export class ApiService { } mountSlewRate(mount: Mount, rate: SlewRate) { - return this.http.put(`mounts/${mount.id}/slew-rate?rate=${rate.name}`) + return this.http.put(`mounts/${mount.id}/slew-rate?rate=${rate.value}`) } mountMove(mount: Mount, direction: GuideDirection, enabled: boolean) { diff --git a/desktop/src/shared/types/angular.types.ts b/desktop/src/shared/types/angular.types.ts index 7abbd0d26..844185944 100644 --- a/desktop/src/shared/types/angular.types.ts +++ b/desktop/src/shared/types/angular.types.ts @@ -2,11 +2,6 @@ export type Severity = 'success' | 'info' | 'warning' | 'danger' export type TooltipPosition = 'right' | 'left' | 'top' | 'bottom' -export interface DropdownItem { - label: string - value: T -} - export function extractDateTime(date: Date) { return [extractDate(date), extractTime(date)] } diff --git a/desktop/src/shared/types/mount.types.ts b/desktop/src/shared/types/mount.types.ts index fd7fab5b9..aaada0bd2 100644 --- a/desktop/src/shared/types/mount.types.ts +++ b/desktop/src/shared/types/mount.types.ts @@ -1,3 +1,4 @@ +import type { DropdownItem } from '../components/dropdown.component' import type { Angle, EquatorialCoordinate } from './atlas.types' import type { Device } from './device.types' import type { GPS } from './gps.types' @@ -19,10 +20,7 @@ export type OrdinalDirection = 'NW' | 'NE' | 'SW' | 'SE' export type MountSlewDirection = CardinalDirection | OrdinalDirection -export interface SlewRate { - name: string - label: string -} +export type SlewRate = DropdownItem export interface Parkable { canPark: boolean diff --git a/nebulosa-alpaca-indi/src/main/kotlin/nebulosa/alpaca/indi/device/mounts/ASCOMMount.kt b/nebulosa-alpaca-indi/src/main/kotlin/nebulosa/alpaca/indi/device/mounts/ASCOMMount.kt index f5bf593f3..aa337700e 100644 --- a/nebulosa-alpaca-indi/src/main/kotlin/nebulosa/alpaca/indi/device/mounts/ASCOMMount.kt +++ b/nebulosa-alpaca-indi/src/main/kotlin/nebulosa/alpaca/indi/device/mounts/ASCOMMount.kt @@ -215,12 +215,12 @@ data class ASCOMMount( } override fun slewRate(rate: SlewRate) { - slewRate = slewRates.firstOrNull { it.name == rate.name } ?: return + slewRate = slewRates.firstOrNull { it.value == rate.value } ?: return sender.fireOnEventReceived(MountSlewRateChanged(this)) } private fun moveAxis(axisType: AxisType, negative: Boolean, enabled: Boolean) { - val rate = slewRate?.name?.let { axisRates[it] }?.second ?: return LOG.d { warn("axisRate is null") } + val rate = slewRate?.value?.let { axisRates[it] }?.second ?: return LOG.d { warn("axisRate is null") } if (enabled) { service.moveAxis(device.number, axisType, if (negative) -(rate.toDouble()) else rate.toDouble()).doRequest() diff --git a/nebulosa-indi-client/src/main/kotlin/nebulosa/indi/client/device/mount/INDIMount.kt b/nebulosa-indi-client/src/main/kotlin/nebulosa/indi/client/device/mount/INDIMount.kt index 26c87c55b..f273bc778 100644 --- a/nebulosa-indi-client/src/main/kotlin/nebulosa/indi/client/device/mount/INDIMount.kt +++ b/nebulosa-indi-client/src/main/kotlin/nebulosa/indi/client/device/mount/INDIMount.kt @@ -107,8 +107,8 @@ internal open class INDIMount( val name = message.firstOnSwitch().name - if (slewRate?.name != name) { - slewRate = slewRates.firstOrNull { it.name == name } + if (slewRate?.value != name) { + slewRate = slewRates.firstOrNull { it.value == name } sender.fireOnEventReceived(MountSlewRateChanged(this)) } } @@ -292,7 +292,7 @@ internal open class INDIMount( override fun slewRate(rate: SlewRate) { if (rate in slewRates) { - sendNewSwitch("TELESCOPE_SLEW_RATE", rate.name to true) + sendNewSwitch("TELESCOPE_SLEW_RATE", rate.value to true) } } diff --git a/nebulosa-indi-device/src/main/kotlin/nebulosa/indi/device/mount/SlewRate.kt b/nebulosa-indi-device/src/main/kotlin/nebulosa/indi/device/mount/SlewRate.kt index 1b749bd4a..1d94a6e54 100644 --- a/nebulosa-indi-device/src/main/kotlin/nebulosa/indi/device/mount/SlewRate.kt +++ b/nebulosa-indi-device/src/main/kotlin/nebulosa/indi/device/mount/SlewRate.kt @@ -1,3 +1,3 @@ package nebulosa.indi.device.mount -data class SlewRate(val name: String, val label: String) +data class SlewRate(val value: String, val label: String) From 4bff8ab22cfaef67546f9099dc8b372880323722 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:31:55 -0300 Subject: [PATCH 11/30] [desktop]: Make MoonComponent single file --- desktop/src/app/app.module.ts | 2 +- .../components/{moon => }/moon.component.ts | 35 +++++++++---------- .../components/moon/moon.component.html | 5 --- 3 files changed, 17 insertions(+), 25 deletions(-) rename desktop/src/shared/components/{moon => }/moon.component.ts (68%) delete mode 100644 desktop/src/shared/components/moon/moon.component.html diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index d350a4fa4..b3836aea7 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -63,7 +63,7 @@ import { LocationComponent } from '../shared/components/location/location.dialog import { MapComponent } from '../shared/components/map/map.component' import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' import { MenuItemComponent } from '../shared/components/menu-item/menu-item.component' -import { MoonComponent } from '../shared/components/moon/moon.component' +import { MoonComponent } from '../shared/components/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser/path-chooser.component' import { SlideMenuComponent } from '../shared/components/slide-menu/slide-menu.component' import { SwitchComponent } from '../shared/components/switch.component' diff --git a/desktop/src/shared/components/moon/moon.component.ts b/desktop/src/shared/components/moon.component.ts similarity index 68% rename from desktop/src/shared/components/moon/moon.component.ts rename to desktop/src/shared/components/moon.component.ts index 330d31c08..57f80efbb 100644 --- a/desktop/src/shared/components/moon/moon.component.ts +++ b/desktop/src/shared/components/moon.component.ts @@ -1,25 +1,23 @@ -import { AfterViewInit, Component, ElementRef, Input, OnChanges, ViewChild, ViewEncapsulation } from '@angular/core' +import { AfterViewInit, Component, ElementRef, OnChanges, ViewEncapsulation, input, viewChild } from '@angular/core' @Component({ selector: 'neb-moon', - templateUrl: 'moon.component.html', + template: ` + + `, encapsulation: ViewEncapsulation.None, }) export class MoonComponent implements AfterViewInit, OnChanges { - @Input() - protected height = 256 + protected readonly height = input(256) + protected readonly width = input(256) + protected readonly illuminationRatio = input(0) + protected readonly waning = input(false) - @Input() - protected width = 256 - - @Input() - protected illuminationRatio = 0 - - @Input() - protected waning = false - - @ViewChild('moon') - private readonly moon?: ElementRef + private readonly moonRef = viewChild.required>('moon') ngAfterViewInit() { this.draw() @@ -31,8 +29,7 @@ export class MoonComponent implements AfterViewInit, OnChanges { // Adapted from https://codepen.io/ardathksheyna/pen/adMyXx. private draw() { - const canvas = this.moon?.nativeElement - if (!canvas) return + const canvas = this.moonRef().nativeElement const ctx = canvas.getContext('2d')! ctx.clearRect(0, 0, canvas.width, canvas.height) @@ -54,9 +51,9 @@ export class MoonComponent implements AfterViewInit, OnChanges { let x1 = Math.ceil(Math.cos(angle) * cx) const y1 = Math.ceil(Math.sin(angle) * cy) const w = x1 * 2 - let x2 = Math.floor(w * this.illuminationRatio) + let x2 = Math.floor(w * this.illuminationRatio()) - if (this.waning) { + if (this.waning()) { x1 = cx + x1 x2 = x1 - (w - x2) } else { diff --git a/desktop/src/shared/components/moon/moon.component.html b/desktop/src/shared/components/moon/moon.component.html deleted file mode 100644 index 960765765..000000000 --- a/desktop/src/shared/components/moon/moon.component.html +++ /dev/null @@ -1,5 +0,0 @@ - From d4bc481302018e3bb002a95dd789d4a0f2fded73 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:33:35 -0300 Subject: [PATCH 12/30] [desktop]: Make MapComponent single file --- desktop/src/app/app.module.ts | 2 +- .../components/location/location.dialog.ts | 2 +- .../components/{map => }/map.component.ts | 43 ++++++++++--------- .../shared/components/map/map.component.html | 4 -- .../shared/components/map/map.component.scss | 4 -- 5 files changed, 24 insertions(+), 31 deletions(-) rename desktop/src/shared/components/{map => }/map.component.ts (61%) delete mode 100644 desktop/src/shared/components/map/map.component.html delete mode 100644 desktop/src/shared/components/map/map.component.scss diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index b3836aea7..db4db8cc1 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -60,7 +60,7 @@ import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' import { InputTextComponent } from '../shared/components/input-text.component' import { LocationComponent } from '../shared/components/location/location.dialog' -import { MapComponent } from '../shared/components/map/map.component' +import { MapComponent } from '../shared/components/map.component' import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' import { MenuItemComponent } from '../shared/components/menu-item/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' diff --git a/desktop/src/shared/components/location/location.dialog.ts b/desktop/src/shared/components/location/location.dialog.ts index 992b70750..e73171c4e 100644 --- a/desktop/src/shared/components/location/location.dialog.ts +++ b/desktop/src/shared/components/location/location.dialog.ts @@ -2,7 +2,7 @@ import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild, injec import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog' import type { Location } from '../../types/atlas.types' import { DEFAULT_LOCATION } from '../../types/atlas.types' -import { MapComponent } from '../map/map.component' +import { MapComponent } from '../map.component' @Component({ selector: 'neb-location', diff --git a/desktop/src/shared/components/map/map.component.ts b/desktop/src/shared/components/map.component.ts similarity index 61% rename from desktop/src/shared/components/map/map.component.ts rename to desktop/src/shared/components/map.component.ts index 48306a04d..9cfe9cfcc 100644 --- a/desktop/src/shared/components/map/map.component.ts +++ b/desktop/src/shared/components/map.component.ts @@ -1,26 +1,27 @@ -import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core' +import { AfterViewInit, Component, ElementRef, OnChanges, ViewEncapsulation, model, viewChild } from '@angular/core' import * as L from 'leaflet' @Component({ selector: 'neb-map', - templateUrl: 'map.component.html', - styleUrls: ['map.component.scss'], + template: ` +
+ `, + styles: ` + neb-map { + display: block; + width: 100%; + } + `, + encapsulation: ViewEncapsulation.None, }) export class MapComponent implements AfterViewInit, OnChanges { - @Input() - protected latitude = 0 - - @Output() - readonly latitudeChange = new EventEmitter() - - @Input() - protected longitude = 0 - - @Output() - readonly longitudeChange = new EventEmitter() + protected readonly latitude = model(0) + protected readonly longitude = model(0) - @ViewChild('map') - private readonly mapRef!: ElementRef + private readonly mapRef = viewChild.required>('map') private map?: L.Map private marker?: L.Marker @@ -35,15 +36,15 @@ export class MapComponent implements AfterViewInit, OnChanges { }) ngAfterViewInit() { - this.map = L.map(this.mapRef.nativeElement, { - center: { lat: this.latitude, lng: this.longitude }, + this.map = L.map(this.mapRef().nativeElement, { + center: { lat: this.latitude(), lng: this.longitude() }, zoom: 5, doubleClickZoom: false, }) this.map.on('dblclick', (event) => { - this.latitudeChange.emit(event.latlng.lat) - this.longitudeChange.emit(event.latlng.lng) + this.latitude.set(event.latlng.lat) + this.longitude.set(event.latlng.lng) this.updateMarker(event.latlng) }) @@ -60,7 +61,7 @@ export class MapComponent implements AfterViewInit, OnChanges { ngOnChanges() { if (this.map) { - const coordinate: L.LatLngLiteral = { lat: this.latitude, lng: this.longitude } + const coordinate: L.LatLngLiteral = { lat: this.latitude(), lng: this.longitude() } this.map.setView(coordinate) this.updateMarker(coordinate) } diff --git a/desktop/src/shared/components/map/map.component.html b/desktop/src/shared/components/map/map.component.html deleted file mode 100644 index 6a925dbe8..000000000 --- a/desktop/src/shared/components/map/map.component.html +++ /dev/null @@ -1,4 +0,0 @@ -
diff --git a/desktop/src/shared/components/map/map.component.scss b/desktop/src/shared/components/map/map.component.scss deleted file mode 100644 index 2486878d8..000000000 --- a/desktop/src/shared/components/map/map.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - display: block; - width: 100%; -} From 312a22de21e15a90eec677db2c05cf7a264f4d17 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:36:37 -0300 Subject: [PATCH 13/30] [desktop]: Make PathChooserComponent single file --- desktop/src/app/app.module.ts | 2 +- .../components/path-chooser.component.ts | 49 +++++++++++++++++++ .../path-chooser/path-chooser.component.html | 13 ----- .../path-chooser/path-chooser.component.ts | 34 ------------- 4 files changed, 50 insertions(+), 48 deletions(-) create mode 100644 desktop/src/shared/components/path-chooser.component.ts delete mode 100644 desktop/src/shared/components/path-chooser/path-chooser.component.html delete mode 100644 desktop/src/shared/components/path-chooser/path-chooser.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index db4db8cc1..7b5b44669 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -64,7 +64,7 @@ import { MapComponent } from '../shared/components/map.component' import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' import { MenuItemComponent } from '../shared/components/menu-item/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' -import { PathChooserComponent } from '../shared/components/path-chooser/path-chooser.component' +import { PathChooserComponent } from '../shared/components/path-chooser.component' import { SlideMenuComponent } from '../shared/components/slide-menu/slide-menu.component' import { SwitchComponent } from '../shared/components/switch.component' import { TagComponent } from '../shared/components/tag.component' diff --git a/desktop/src/shared/components/path-chooser.component.ts b/desktop/src/shared/components/path-chooser.component.ts new file mode 100644 index 000000000..88ac0aab7 --- /dev/null +++ b/desktop/src/shared/components/path-chooser.component.ts @@ -0,0 +1,49 @@ +import { Component, inject, input, model, ViewEncapsulation } from '@angular/core' +import { ElectronService } from '../services/electron.service' + +@Component({ + selector: 'neb-path-chooser', + template: ` +
+ + +
+ `, + encapsulation: ViewEncapsulation.None, +}) +export class PathChooserComponent { + private readonly electronService = inject(ElectronService) + + protected readonly key = input.required() + protected readonly label = input() + protected readonly placeholder = input() + protected readonly path = model() + protected readonly disabled = input(false) + protected readonly readonly = input(false) + protected readonly directory = input.required() + protected readonly save = input(false) + + protected async choosePath() { + const key = this.key() + const lastPath = localStorage.getItem(key) || undefined + const defaultPath = lastPath && !this.directory() ? window.path.dirname(lastPath) : lastPath + + const path = await (this.directory() ? this.electronService.openDirectory({ defaultPath }) + : this.save() ? this.electronService.saveFile({ defaultPath }) + : this.electronService.openFile({ defaultPath })) + + if (path) { + this.path.set(path) + localStorage.setItem(key, path) + } + } +} diff --git a/desktop/src/shared/components/path-chooser/path-chooser.component.html b/desktop/src/shared/components/path-chooser/path-chooser.component.html deleted file mode 100644 index 96c1b0fd4..000000000 --- a/desktop/src/shared/components/path-chooser/path-chooser.component.html +++ /dev/null @@ -1,13 +0,0 @@ -
- - -
diff --git a/desktop/src/shared/components/path-chooser/path-chooser.component.ts b/desktop/src/shared/components/path-chooser/path-chooser.component.ts deleted file mode 100644 index 1085415cf..000000000 --- a/desktop/src/shared/components/path-chooser/path-chooser.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, inject, input, model } from '@angular/core' -import { ElectronService } from '../../services/electron.service' - -@Component({ - selector: 'neb-path-chooser', - templateUrl: 'path-chooser.component.html', -}) -export class PathChooserComponent { - private readonly electronService = inject(ElectronService) - - readonly key = input.required() - readonly label = input() - readonly placeholder = input() - readonly path = model() - readonly disabled = input(false) - readonly readonly = input(false) - readonly directory = input.required() - readonly save = input(false) - - protected async choosePath() { - const key = this.key() - const lastPath = localStorage.getItem(key) || undefined - const defaultPath = lastPath && !this.directory() ? window.path.dirname(lastPath) : lastPath - - const path = await (this.directory() ? this.electronService.openDirectory({ defaultPath }) - : this.save() ? this.electronService.saveFile({ defaultPath }) - : this.electronService.openFile({ defaultPath })) - - if (path) { - this.path.set(path) - localStorage.setItem(key, path) - } - } -} From 87d51bd3771e063b7f4738aafec0e25ca1db5600 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:41:24 -0300 Subject: [PATCH 14/30] [desktop]: Make HistogramComponent single file --- desktop/src/app/app.module.ts | 2 +- desktop/src/app/image/image.component.ts | 2 +- .../{histogram => }/histogram.component.ts | 25 +++++++++++-------- .../histogram/histogram.component.html | 3 --- 4 files changed, 17 insertions(+), 15 deletions(-) rename desktop/src/shared/components/{histogram => }/histogram.component.ts (71%) delete mode 100644 desktop/src/shared/components/histogram/histogram.component.html diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 7b5b44669..ab20c87a6 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -55,7 +55,7 @@ import { DeviceListMenuComponent } from '../shared/components/device-list-menu/d import { DeviceNameComponent } from '../shared/components/device-name/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' import { DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' -import { HistogramComponent } from '../shared/components/histogram/histogram.component' +import { HistogramComponent } from '../shared/components/histogram.component' import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' import { InputTextComponent } from '../shared/components/input-text.component' diff --git a/desktop/src/app/image/image.component.ts b/desktop/src/app/image/image.component.ts index 53ce41422..cddfec8bf 100644 --- a/desktop/src/app/image/image.component.ts +++ b/desktop/src/app/image/image.component.ts @@ -4,7 +4,7 @@ import hotkeys from 'hotkeys-js' import { NgxLegacyMoveableComponent, OnDrag, OnResize, OnRotate } from 'ngx-moveable' import { ContextMenu } from 'primeng/contextmenu' import { DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' -import { HistogramComponent } from '../../shared/components/histogram/histogram.component' +import { HistogramComponent } from '../../shared/components/histogram.component' import { MenuItem } from '../../shared/components/menu-item/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' diff --git a/desktop/src/shared/components/histogram/histogram.component.ts b/desktop/src/shared/components/histogram.component.ts similarity index 71% rename from desktop/src/shared/components/histogram/histogram.component.ts rename to desktop/src/shared/components/histogram.component.ts index a8595842d..b0f446456 100644 --- a/desktop/src/shared/components/histogram/histogram.component.ts +++ b/desktop/src/shared/components/histogram.component.ts @@ -1,23 +1,28 @@ -import { AfterViewInit, Component, ElementRef, ViewChild, ViewEncapsulation } from '@angular/core' -import { ImageHistrogram } from '../../types/image.types' +import { Component, ElementRef, ViewEncapsulation, effect, viewChild } from '@angular/core' +import { ImageHistrogram } from '../types/image.types' @Component({ selector: 'neb-histogram', - templateUrl: 'histogram.component.html', + template: ` + + `, encapsulation: ViewEncapsulation.None, }) -export class HistogramComponent implements AfterViewInit { - @ViewChild('canvas') - private readonly canvas!: ElementRef +export class HistogramComponent { + private readonly canvas = viewChild.required>('canvas') private ctx?: CanvasRenderingContext2D | null - ngAfterViewInit() { - this.ctx = this.canvas.nativeElement.getContext('2d') + constructor() { + effect(() => { + this.ctx = this.canvas().nativeElement.getContext('2d') + }) } update(data: ImageHistrogram, dontClear: boolean = false) { - const canvas = this.canvas.nativeElement + const canvas = this.canvas().nativeElement if (!dontClear || !data.length) { this.ctx?.clearRect(0, 0, canvas.width, canvas.height) @@ -36,7 +41,7 @@ export class HistogramComponent implements AfterViewInit { private drawColorGraph(data: ImageHistrogram, max: number, start: number = 0, end: number = data.length - 1, color: string | CanvasGradient | CanvasPattern) { if (this.ctx) { - const canvas = this.canvas.nativeElement + const canvas = this.canvas().nativeElement const graphHeight = canvas.height const graphWidth = canvas.width diff --git a/desktop/src/shared/components/histogram/histogram.component.html b/desktop/src/shared/components/histogram/histogram.component.html deleted file mode 100644 index 15903fdb1..000000000 --- a/desktop/src/shared/components/histogram/histogram.component.html +++ /dev/null @@ -1,3 +0,0 @@ - From d4f8cbae375c052a3cd8c7e7c3eaba7335ca38ea Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:45:17 -0300 Subject: [PATCH 15/30] [desktop]: Make SlideMenuComponent single file --- desktop/src/app/app.module.ts | 2 +- .../{slide-menu => }/slide-menu.component.ts | 47 ++++++++++++------- .../slide-menu/slide-menu.component.html | 18 ------- 3 files changed, 31 insertions(+), 36 deletions(-) rename desktop/src/shared/components/{slide-menu => }/slide-menu.component.ts (50%) delete mode 100644 desktop/src/shared/components/slide-menu/slide-menu.component.html diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index ab20c87a6..9109a0370 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -65,7 +65,7 @@ import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.compone import { MenuItemComponent } from '../shared/components/menu-item/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser.component' -import { SlideMenuComponent } from '../shared/components/slide-menu/slide-menu.component' +import { SlideMenuComponent } from '../shared/components/slide-menu.component' import { SwitchComponent } from '../shared/components/switch.component' import { TagComponent } from '../shared/components/tag.component' import { ConfirmDialogComponent } from '../shared/dialogs/confirm/confirm.dialog' diff --git a/desktop/src/shared/components/slide-menu/slide-menu.component.ts b/desktop/src/shared/components/slide-menu.component.ts similarity index 50% rename from desktop/src/shared/components/slide-menu/slide-menu.component.ts rename to desktop/src/shared/components/slide-menu.component.ts index 133ad6aeb..9a4d4e108 100644 --- a/desktop/src/shared/components/slide-menu/slide-menu.component.ts +++ b/desktop/src/shared/components/slide-menu.component.ts @@ -1,32 +1,45 @@ -import { Component, ElementRef, EventEmitter, Input, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core' -import type { Nullable } from '../../utils/types' -import { MenuItemCommandEvent, SlideMenuItem } from '../menu-item/menu-item.component' +import { Component, ElementRef, OnInit, TemplateRef, ViewEncapsulation, input, output } from '@angular/core' +import type { Nullable } from '../utils/types' +import { MenuItemCommandEvent, SlideMenuItem } from './menu-item/menu-item.component' @Component({ selector: 'neb-slide-menu', - templateUrl: 'slide-menu.component.html', + template: ` +
+ + + + + + @if (currentMenu !== model()) { + + } +
+ `, encapsulation: ViewEncapsulation.None, }) export class SlideMenuComponent implements OnInit { - @Input({ required: true }) - readonly model!: SlideMenuItem[] - - @Input() - readonly appendTo: Nullable | string> - - @Output() - readonly forward = new EventEmitter() - - @Output() - readonly backward = new EventEmitter() + protected readonly model = input.required() + protected readonly appendTo = input | string>>() + protected readonly forward = output() + protected readonly backward = output() protected currentMenu!: SlideMenuItem[] private readonly navigation: SlideMenuItem[][] = [] ngOnInit() { - this.processMenu(this.model, 0) - this.currentMenu = this.model + const model = this.model() + this.processMenu(model, 0) + this.currentMenu = model } back(event: MouseEvent) { diff --git a/desktop/src/shared/components/slide-menu/slide-menu.component.html b/desktop/src/shared/components/slide-menu/slide-menu.component.html deleted file mode 100644 index 6a3ffe07d..000000000 --- a/desktop/src/shared/components/slide-menu/slide-menu.component.html +++ /dev/null @@ -1,18 +0,0 @@ -
- - - - - - @if (currentMenu !== model) { - - } -
From 0c88da2ea2890296162ced4e6c2b11bebd9a19d5 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:46:34 -0300 Subject: [PATCH 16/30] [desktop]: Make DeviceNameComponent single file --- desktop/src/app/app.module.ts | 2 +- .../components/device-name.component.ts | 19 ++++++++++++++++++ .../device-name/device-name.component.ts | 20 ------------------- 3 files changed, 20 insertions(+), 21 deletions(-) create mode 100644 desktop/src/shared/components/device-name.component.ts delete mode 100644 desktop/src/shared/components/device-name/device-name.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 9109a0370..2e2aea602 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -52,7 +52,7 @@ import { CameraInfoComponent } from '../shared/components/camera-info/camera-inf import { CheckboxComponent } from '../shared/components/checkbox.component' import { DeviceChooserComponent } from '../shared/components/device-chooser/device-chooser.component' import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' -import { DeviceNameComponent } from '../shared/components/device-name/device-name.component' +import { DeviceNameComponent } from '../shared/components/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' import { DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' import { HistogramComponent } from '../shared/components/histogram.component' diff --git a/desktop/src/shared/components/device-name.component.ts b/desktop/src/shared/components/device-name.component.ts new file mode 100644 index 000000000..4e143c469 --- /dev/null +++ b/desktop/src/shared/components/device-name.component.ts @@ -0,0 +1,19 @@ +import { Component, ViewEncapsulation, input } from '@angular/core' +import type { Device } from '../types/device.types' + +@Component({ + selector: 'neb-device-name', + template: ` +
+ {{ device().name }} +
+ DRIVER: {{ device().driverName }} + VERSION: {{ device().driverVersion }} +
+
+ `, + encapsulation: ViewEncapsulation.None, +}) +export class DeviceNameComponent { + protected readonly device = input.required() +} diff --git a/desktop/src/shared/components/device-name/device-name.component.ts b/desktop/src/shared/components/device-name/device-name.component.ts deleted file mode 100644 index 90c43e0c0..000000000 --- a/desktop/src/shared/components/device-name/device-name.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, Input, ViewEncapsulation } from '@angular/core' -import type { Device } from '../../types/device.types' - -@Component({ - selector: 'neb-device-name', - template: ` -
- {{ device.name }} -
- DRIVER: {{ device.driverName }} - VERSION: {{ device.driverVersion }} -
-
- `, - encapsulation: ViewEncapsulation.None, -}) -export class DeviceNameComponent { - @Input({ required: true }) - readonly device!: Device -} From d61ae774108416583b80dee96c93703ab550125f Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 22:57:01 -0300 Subject: [PATCH 17/30] [desktop]: Make DeviceChooserComponent single file --- desktop/src/app/app.module.ts | 2 +- desktop/src/app/home/home.component.ts | 2 +- .../device-chooser.component.ts | 94 ++++++++++--------- .../device-chooser.component.html | 25 ----- 4 files changed, 51 insertions(+), 72 deletions(-) rename desktop/src/shared/components/{device-chooser => }/device-chooser.component.ts (53%) delete mode 100644 desktop/src/shared/components/device-chooser/device-chooser.component.html diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 2e2aea602..acaadfc6d 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -50,7 +50,7 @@ import { ButtonComponent } from '../shared/components/button.component' import { CameraExposureComponent } from '../shared/components/camera-exposure/camera-exposure.component' import { CameraInfoComponent } from '../shared/components/camera-info/camera-info.component' import { CheckboxComponent } from '../shared/components/checkbox.component' -import { DeviceChooserComponent } from '../shared/components/device-chooser/device-chooser.component' +import { DeviceChooserComponent } from '../shared/components/device-chooser.component' import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' import { DeviceNameComponent } from '../shared/components/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' diff --git a/desktop/src/app/home/home.component.ts b/desktop/src/app/home/home.component.ts index ff9a4ea07..87f01d9cc 100644 --- a/desktop/src/app/home/home.component.ts +++ b/desktop/src/app/home/home.component.ts @@ -1,6 +1,6 @@ import { AfterContentInit, Component, inject, NgZone, ViewChild, ViewEncapsulation } from '@angular/core' import packageJson from '../../../package.json' with { type: 'json' } -import { DeviceChooserComponent } from '../../shared/components/device-chooser/device-chooser.component' +import { DeviceChooserComponent } from '../../shared/components/device-chooser.component' import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/shared/components/device-chooser/device-chooser.component.ts b/desktop/src/shared/components/device-chooser.component.ts similarity index 53% rename from desktop/src/shared/components/device-chooser/device-chooser.component.ts rename to desktop/src/shared/components/device-chooser.component.ts index 9bd25a720..f97b05fc2 100644 --- a/desktop/src/shared/components/device-chooser/device-chooser.component.ts +++ b/desktop/src/shared/components/device-chooser.component.ts @@ -1,62 +1,66 @@ -import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject } from '@angular/core' -import { ApiService } from '../../services/api.service' -import { Device } from '../../types/device.types' -import { Undefinable } from '../../utils/types' -import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../device-list-menu/device-list-menu.component' -import { MenuItem } from '../menu-item/menu-item.component' +import { Component, ViewEncapsulation, inject, input, model, output, viewChild } from '@angular/core' +import { ApiService } from '../services/api.service' +import { Device } from '../types/device.types' +import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from './device-list-menu/device-list-menu.component' +import { MenuItem } from './menu-item/menu-item.component' @Component({ selector: 'neb-device-chooser', - templateUrl: 'device-chooser.component.html', + template: ` + +
+ +
+ {{ title() }} + @let dev = device(); + + @if (dev && dev.id) { + {{ dev.name }} + } @else { + {{ noDeviceMessage() || 'Choose a device' }} + } +
+
+
+ + + `, encapsulation: ViewEncapsulation.None, }) export class DeviceChooserComponent { private readonly api = inject(ApiService) - - @Input({ required: true }) - protected readonly title!: string - - @Input() - protected readonly noDeviceMessage?: string - - @Input({ required: true }) - protected readonly icon!: string - - @Input({ required: true }) - protected readonly devices!: T[] - - @Input() - protected readonly hasNone: boolean = false - - @Input() - protected device?: T - - @Input() - protected readonly disabled?: boolean - - @Output() - readonly deviceChange = new EventEmitter() - - @Output() - readonly deviceConnect = new EventEmitter() - - @Output() - readonly deviceDisconnect = new EventEmitter() - - @ViewChild('deviceMenu') - private readonly deviceMenu!: DeviceListMenuComponent + protected readonly title = input.required() + protected readonly noDeviceMessage = input() + protected readonly icon = input.required() + protected readonly devices = input.required() + protected readonly hasNone = input(false) + protected readonly device = model() + protected readonly disabled = input() + protected readonly deviceConnect = output() + protected readonly deviceDisconnect = output() + + private readonly deviceMenu = viewChild.required('deviceMenu') async show() { - const device = await this.deviceMenu.show(this.devices, this.device) + const device = await this.deviceMenu().show(this.devices(), this.device()) if (device) { - this.device = device === 'NONE' ? undefined : device - this.deviceChange.emit(this.device) + this.device.set(device === 'NONE' ? undefined : device) } } hide() { - this.deviceMenu.hide() + this.deviceMenu().hide() } protected async deviceConnected(event: DeviceConnectionCommandEvent) { @@ -108,7 +112,7 @@ export class DeviceChooserComponent { item.disabled = true - return new Promise>((resolve) => { + return new Promise((resolve) => { let counter = 0 const timer = setTimeout(async () => { diff --git a/desktop/src/shared/components/device-chooser/device-chooser.component.html b/desktop/src/shared/components/device-chooser/device-chooser.component.html deleted file mode 100644 index 4b565312b..000000000 --- a/desktop/src/shared/components/device-chooser/device-chooser.component.html +++ /dev/null @@ -1,25 +0,0 @@ - -
- -
- {{ title }} - @if (device && device.id) { - {{ device.name }} - } @else { - {{ noDeviceMessage || 'Choose a device' }} - } -
-
-
- - From 52574377a949c1854267e004f553901f761b913e Mon Sep 17 00:00:00 2001 From: tiagohm Date: Fri, 6 Dec 2024 23:02:25 -0300 Subject: [PATCH 18/30] [desktop]: Make MenuItemComponent single file --- desktop/src/app/app.component.ts | 2 +- desktop/src/app/app.module.ts | 2 +- desktop/src/app/atlas/atlas.component.ts | 2 +- .../app/calibration/calibration.component.ts | 2 +- desktop/src/app/camera/camera.component.ts | 2 +- .../src/app/camera/exposure-time.component.ts | 2 +- desktop/src/app/home/home.component.ts | 2 +- desktop/src/app/image/image.component.ts | 2 +- desktop/src/app/mount/mount.component.ts | 2 +- .../src/app/sequencer/sequencer.component.ts | 2 +- .../src/app/settings/settings.component.ts | 2 +- .../components/device-chooser.component.ts | 8 ++--- .../device-list-menu.component.ts | 2 +- .../dialog-menu/dialog-menu.component.ts | 2 +- .../components/menu-bar/menu-bar.component.ts | 2 +- .../{menu-item => }/menu-item.component.ts | 32 ++++++++++++++++--- .../menu-item/menu-item.component.html | 20 ------------ .../shared/components/slide-menu.component.ts | 2 +- desktop/src/shared/constants.ts | 2 +- 19 files changed, 47 insertions(+), 45 deletions(-) rename desktop/src/shared/components/{menu-item => }/menu-item.component.ts (58%) delete mode 100644 desktop/src/shared/components/menu-item/menu-item.component.html diff --git a/desktop/src/app/app.component.ts b/desktop/src/app/app.component.ts index 45bd251f0..f73dd1a34 100644 --- a/desktop/src/app/app.component.ts +++ b/desktop/src/app/app.component.ts @@ -2,7 +2,7 @@ import { Component, ElementRef, HostListener, NgZone, OnDestroy, inject } from ' import { Title } from '@angular/platform-browser' import hotkeys from 'hotkeys-js' import { APP_CONFIG } from '../environments/environment' -import { MenuItem } from '../shared/components/menu-item/menu-item.component' +import { MenuItem } from '../shared/components/menu-item.component' import { ConfirmationService } from '../shared/services/confirmation.service' import { ElectronService } from '../shared/services/electron.service' diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index acaadfc6d..f4333ca1e 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -62,7 +62,7 @@ import { InputTextComponent } from '../shared/components/input-text.component' import { LocationComponent } from '../shared/components/location/location.dialog' import { MapComponent } from '../shared/components/map.component' import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' -import { MenuItemComponent } from '../shared/components/menu-item/menu-item.component' +import { MenuItemComponent } from '../shared/components/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser.component' import { SlideMenuComponent } from '../shared/components/slide-menu.component' diff --git a/desktop/src/app/atlas/atlas.component.ts b/desktop/src/app/atlas/atlas.component.ts index 96a517a40..f9871ae6a 100644 --- a/desktop/src/app/atlas/atlas.component.ts +++ b/desktop/src/app/atlas/atlas.component.ts @@ -7,7 +7,7 @@ import { ListboxChangeEvent } from 'primeng/listbox' import { OverlayPanel } from 'primeng/overlaypanel' import { timer } from 'rxjs' import { DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' -import { SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' +import { SlideMenuItem } from '../../shared/components/menu-item.component' import { ONE_DECIMAL_PLACE_FORMATTER, TWO_DIGITS_FORMATTER } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/app/calibration/calibration.component.ts b/desktop/src/app/calibration/calibration.component.ts index e4d4fbbed..d21af0abb 100644 --- a/desktop/src/app/calibration/calibration.component.ts +++ b/desktop/src/app/calibration/calibration.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, Component, HostListener, OnDestroy, QueryList, ViewChildren, ViewEncapsulation, inject } from '@angular/core' import { Listbox } from 'primeng/listbox' -import { MenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' diff --git a/desktop/src/app/camera/camera.component.ts b/desktop/src/app/camera/camera.component.ts index b2436f489..08c623238 100644 --- a/desktop/src/app/camera/camera.component.ts +++ b/desktop/src/app/camera/camera.component.ts @@ -1,7 +1,7 @@ import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, ViewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' -import { MenuItemCommandEvent, SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItemCommandEvent, SlideMenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' diff --git a/desktop/src/app/camera/exposure-time.component.ts b/desktop/src/app/camera/exposure-time.component.ts index 8569e4831..e9e704f6b 100644 --- a/desktop/src/app/camera/exposure-time.component.ts +++ b/desktop/src/app/camera/exposure-time.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core' -import { MenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem } from '../../shared/components/menu-item.component' import type { ExposureTimeUnit } from '../../shared/types/camera.types' @Component({ diff --git a/desktop/src/app/home/home.component.ts b/desktop/src/app/home/home.component.ts index 87f01d9cc..d9c64f92a 100644 --- a/desktop/src/app/home/home.component.ts +++ b/desktop/src/app/home/home.component.ts @@ -2,7 +2,7 @@ import { AfterContentInit, Component, inject, NgZone, ViewChild, ViewEncapsulati import packageJson from '../../../package.json' with { type: 'json' } import { DeviceChooserComponent } from '../../shared/components/device-chooser.component' import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' -import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item.component' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' import { ElectronService } from '../../shared/services/electron.service' diff --git a/desktop/src/app/image/image.component.ts b/desktop/src/app/image/image.component.ts index cddfec8bf..5b36ca783 100644 --- a/desktop/src/app/image/image.component.ts +++ b/desktop/src/app/image/image.component.ts @@ -5,7 +5,7 @@ import { NgxLegacyMoveableComponent, OnDrag, OnResize, OnRotate } from 'ngx-move import { ContextMenu } from 'primeng/contextmenu' import { DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' import { HistogramComponent } from '../../shared/components/histogram.component' -import { MenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/app/mount/mount.component.ts b/desktop/src/app/mount/mount.component.ts index 27bbb98dd..0c3323dd9 100644 --- a/desktop/src/app/mount/mount.component.ts +++ b/desktop/src/app/mount/mount.component.ts @@ -2,7 +2,7 @@ import { AfterContentInit, Component, HostListener, NgZone, OnDestroy, inject } import { ActivatedRoute } from '@angular/router' import hotkeys from 'hotkeys-js' import { Subject, Subscription, interval, throttleTime } from 'rxjs' -import { SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' +import { SlideMenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/app/sequencer/sequencer.component.ts b/desktop/src/app/sequencer/sequencer.component.ts index d1d7d88e7..e98ec03b8 100644 --- a/desktop/src/app/sequencer/sequencer.component.ts +++ b/desktop/src/app/sequencer/sequencer.component.ts @@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' import { DialogMenuComponent } from '../../shared/components/dialog-menu/dialog-menu.component' import { DropdownItem } from '../../shared/components/dropdown.component' -import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/app/settings/settings.component.ts b/desktop/src/app/settings/settings.component.ts index 8cc902242..48d82d8b8 100644 --- a/desktop/src/app/settings/settings.component.ts +++ b/desktop/src/app/settings/settings.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, Component, HostListener, inject, OnDestroy } from '@angular/core' import { debounceTime, Subject, Subscription } from 'rxjs' -import { MenuItem } from '../../shared/components/menu-item/menu-item.component' +import { MenuItem } from '../../shared/components/menu-item.component' import { ElectronService } from '../../shared/services/electron.service' import { PreferenceService } from '../../shared/services/preference.service' import { DEFAULT_LOCATION, Location } from '../../shared/types/atlas.types' diff --git a/desktop/src/shared/components/device-chooser.component.ts b/desktop/src/shared/components/device-chooser.component.ts index f97b05fc2..920635778 100644 --- a/desktop/src/shared/components/device-chooser.component.ts +++ b/desktop/src/shared/components/device-chooser.component.ts @@ -2,7 +2,7 @@ import { Component, ViewEncapsulation, inject, input, model, output, viewChild } import { ApiService } from '../services/api.service' import { Device } from '../types/device.types' import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from './device-list-menu/device-list-menu.component' -import { MenuItem } from './menu-item/menu-item.component' +import { MenuItem } from './menu-item.component' @Component({ selector: 'neb-device-chooser', @@ -16,10 +16,10 @@ import { MenuItem } from './menu-item/menu-item.component'
{{ title() }} - @let dev = device(); + @let mDevice = device(); - @if (dev && dev.id) { - {{ dev.name }} + @if (mDevice && mDevice.id) { + {{ mDevice.name }} } @else { {{ noDeviceMessage() || 'Choose a device' }} } diff --git a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts b/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts index 093669583..6209802de 100644 --- a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts +++ b/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts @@ -6,7 +6,7 @@ import { Device } from '../../types/device.types' import { deviceComparator } from '../../utils/comparators' import { Undefinable } from '../../utils/types' import { DialogMenuComponent } from '../dialog-menu/dialog-menu.component' -import { MenuItem, SlideMenuItem } from '../menu-item/menu-item.component' +import { MenuItem, SlideMenuItem } from '../menu-item.component' export interface DeviceConnectionCommandEvent { device: Device diff --git a/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts b/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts index 362444891..64bbd031e 100644 --- a/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts +++ b/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core' import { Undefinable } from '../../utils/types' -import { MenuItemCommandEvent, SlideMenuItem } from '../menu-item/menu-item.component' +import { MenuItemCommandEvent, SlideMenuItem } from '../menu-item.component' @Component({ selector: 'neb-dialog-menu', diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.ts b/desktop/src/shared/components/menu-bar/menu-bar.component.ts index 5924970d3..aa961f316 100644 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.ts +++ b/desktop/src/shared/components/menu-bar/menu-bar.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' -import { MenuItem } from '../menu-item/menu-item.component' +import { MenuItem } from '../menu-item.component' export interface SplitButtonClickEvent { event: MouseEvent diff --git a/desktop/src/shared/components/menu-item/menu-item.component.ts b/desktop/src/shared/components/menu-item.component.ts similarity index 58% rename from desktop/src/shared/components/menu-item/menu-item.component.ts rename to desktop/src/shared/components/menu-item.component.ts index 8a24a01ac..ea1d911e0 100644 --- a/desktop/src/shared/components/menu-item/menu-item.component.ts +++ b/desktop/src/shared/components/menu-item.component.ts @@ -1,7 +1,7 @@ -import { Component, Input, ViewEncapsulation } from '@angular/core' +import { Component, ViewEncapsulation, input } from '@angular/core' import { CheckboxChangeEvent } from 'primeng/checkbox' import { InputSwitchChangeEvent } from 'primeng/inputswitch' -import { Severity, TooltipPosition } from '../../types/angular.types' +import { Severity, TooltipPosition } from '../types/angular.types' export interface MenuItemCommandEvent { originalEvent?: Event @@ -55,10 +55,32 @@ export interface SlideMenuItem extends MenuItem { @Component({ selector: 'neb-menu-item', - templateUrl: 'menu-item.component.html', + template: ` + @let mItem = item(); + + +
+ + {{ mItem.label }} +
+ @if (mItem.toolbarMenu?.length) { + + } + @if (mItem.checkable) { + + } + @if (mItem.items?.length || mItem.slideMenu?.length) { + + } +
+ `, encapsulation: ViewEncapsulation.None, }) export class MenuItemComponent { - @Input({ required: true }) - protected readonly item!: MenuItem + protected readonly item = input.required() } diff --git a/desktop/src/shared/components/menu-item/menu-item.component.html b/desktop/src/shared/components/menu-item/menu-item.component.html deleted file mode 100644 index 505ec0d29..000000000 --- a/desktop/src/shared/components/menu-item/menu-item.component.html +++ /dev/null @@ -1,20 +0,0 @@ - -
- - {{ item.label }} -
- @if (item.toolbarMenu?.length) { - - } - @if (item.checkable) { - - } - @if (item.items?.length || item.slideMenu?.length) { - - } -
diff --git a/desktop/src/shared/components/slide-menu.component.ts b/desktop/src/shared/components/slide-menu.component.ts index 9a4d4e108..5fe0b13a1 100644 --- a/desktop/src/shared/components/slide-menu.component.ts +++ b/desktop/src/shared/components/slide-menu.component.ts @@ -1,6 +1,6 @@ import { Component, ElementRef, OnInit, TemplateRef, ViewEncapsulation, input, output } from '@angular/core' import type { Nullable } from '../utils/types' -import { MenuItemCommandEvent, SlideMenuItem } from './menu-item/menu-item.component' +import { MenuItemCommandEvent, SlideMenuItem } from './menu-item.component' @Component({ selector: 'neb-slide-menu', diff --git a/desktop/src/shared/constants.ts b/desktop/src/shared/constants.ts index cf7016eb0..0ab23073f 100644 --- a/desktop/src/shared/constants.ts +++ b/desktop/src/shared/constants.ts @@ -1,4 +1,4 @@ -import type { MenuItem, SlideMenuItem } from './components/menu-item/menu-item.component' +import type { MenuItem, SlideMenuItem } from './components/menu-item.component' export const EVERY_MINUTE_CRON_TIME = '0 */1 * * * *' From a5b3f19ca04a80fe5c65db2c33ae31962bdf78bc Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sat, 7 Dec 2024 14:07:41 -0300 Subject: [PATCH 19/30] [desktop]: Make CameraExposureComponent single file --- .../src/app/alignment/alignment.component.ts | 2 +- desktop/src/app/app.module.ts | 2 +- .../src/app/autofocus/autofocus.component.ts | 2 +- desktop/src/app/camera/camera.component.ts | 2 +- .../app/flat-wizard/flat-wizard.component.ts | 2 +- .../src/app/sequencer/sequencer.component.ts | 2 +- .../components/camera-exposure.component.ts | 137 ++++++++++++++++++ .../camera-exposure.component.html | 66 --------- .../camera-exposure.component.scss | 29 ---- .../camera-exposure.component.ts | 67 --------- .../shared/services/browser-window.service.ts | 4 +- 11 files changed, 145 insertions(+), 170 deletions(-) create mode 100644 desktop/src/shared/components/camera-exposure.component.ts delete mode 100644 desktop/src/shared/components/camera-exposure/camera-exposure.component.html delete mode 100644 desktop/src/shared/components/camera-exposure/camera-exposure.component.scss delete mode 100644 desktop/src/shared/components/camera-exposure/camera-exposure.component.ts diff --git a/desktop/src/app/alignment/alignment.component.ts b/desktop/src/app/alignment/alignment.component.ts index 562809d8e..7b7f957a9 100644 --- a/desktop/src/app/alignment/alignment.component.ts +++ b/desktop/src/app/alignment/alignment.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' -import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' import { ElectronService } from '../../shared/services/electron.service' diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index f4333ca1e..ad2d24b61 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -47,7 +47,7 @@ import { TooltipModule } from 'primeng/tooltip' import { TreeModule } from 'primeng/tree' import { ButtonImageComponent } from '../shared/components/button-image.component' import { ButtonComponent } from '../shared/components/button.component' -import { CameraExposureComponent } from '../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../shared/components/camera-exposure.component' import { CameraInfoComponent } from '../shared/components/camera-info/camera-info.component' import { CheckboxComponent } from '../shared/components/checkbox.component' import { DeviceChooserComponent } from '../shared/components/device-chooser.component' diff --git a/desktop/src/app/autofocus/autofocus.component.ts b/desktop/src/app/autofocus/autofocus.component.ts index 2e5bf3e66..c456b62b4 100644 --- a/desktop/src/app/autofocus/autofocus.component.ts +++ b/desktop/src/app/autofocus/autofocus.component.ts @@ -2,7 +2,7 @@ import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, i import { ChartData, ChartOptions } from 'chart.js' import { Point } from 'electron' import { UIChart } from 'primeng/chart' -import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' import { ElectronService } from '../../shared/services/electron.service' diff --git a/desktop/src/app/camera/camera.component.ts b/desktop/src/app/camera/camera.component.ts index 08c623238..f2c81ee27 100644 --- a/desktop/src/app/camera/camera.component.ts +++ b/desktop/src/app/camera/camera.component.ts @@ -1,6 +1,6 @@ import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, ViewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { MenuItemCommandEvent, SlideMenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' import { ApiService } from '../../shared/services/api.service' diff --git a/desktop/src/app/flat-wizard/flat-wizard.component.ts b/desktop/src/app/flat-wizard/flat-wizard.component.ts index 90b4dc68d..e6c1a6cff 100644 --- a/desktop/src/app/flat-wizard/flat-wizard.component.ts +++ b/desktop/src/app/flat-wizard/flat-wizard.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' -import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' diff --git a/desktop/src/app/sequencer/sequencer.component.ts b/desktop/src/app/sequencer/sequencer.component.ts index e98ec03b8..4690ea31b 100644 --- a/desktop/src/app/sequencer/sequencer.component.ts +++ b/desktop/src/app/sequencer/sequencer.component.ts @@ -1,7 +1,7 @@ import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop' import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { CameraExposureComponent } from '../../shared/components/camera-exposure/camera-exposure.component' +import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { DialogMenuComponent } from '../../shared/components/dialog-menu/dialog-menu.component' import { DropdownItem } from '../../shared/components/dropdown.component' import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item.component' diff --git a/desktop/src/shared/components/camera-exposure.component.ts b/desktop/src/shared/components/camera-exposure.component.ts new file mode 100644 index 000000000..603e70303 --- /dev/null +++ b/desktop/src/shared/components/camera-exposure.component.ts @@ -0,0 +1,137 @@ +import { Component, input, model, ViewEncapsulation } from '@angular/core' +import { CameraCaptureEvent, CameraCaptureState, DEFAULT_CAMERA_CAPTURE_INFO, DEFAULT_CAMERA_STEP_INFO } from '../types/camera.types' + +@Component({ + selector: 'neb-camera-exposure', + template: ` +
+ + + {{ info() || state || 'IDLE' | enum | lowercase }} + + + + + {{ capture.count }} + @if (!capture.looping) { + / {{ capture.amount }} + } + + @if (!capture.looping) { + + + {{ capture.progress * 100 | number: '1.1-1' }} + + } + @if (capture.looping) { + + + {{ capture.elapsedTime | exposureTime }} + + } @else { + + @if (showRemainingTime()) { + + + {{ capture.remainingTime | exposureTime }} + + } @else { + + + {{ capture.elapsedTime | exposureTime }} + + } + + } + @if (capture.amount !== 1 && (state === 'EXPOSURING' || state === 'WAITING')) { + + @if (showRemainingTime()) { + + + {{ step.remainingTime | exposureTime }} + + } @else { + + + {{ step.elapsedTime | exposureTime }} + + } + + + + {{ step.progress * 100 | number: '1.1-1' }} + + } + +
+ `, + styles: ` + neb-camera-exposure { + min-height: 29px; + width: 100%; + + .state { + padding: 1px 6px; + height: 13px; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class CameraExposureComponent { + protected readonly info = input() + protected readonly showRemainingTime = model(true) + + protected step = structuredClone(DEFAULT_CAMERA_STEP_INFO) + protected capture = structuredClone(DEFAULT_CAMERA_CAPTURE_INFO) + protected state: CameraCaptureState = 'IDLE' + + get currentState() { + return this.state + } + + handleCameraCaptureEvent(event: Omit, looping: boolean = false) { + this.capture.elapsedTime = event.captureElapsedTime + this.capture.remainingTime = event.captureRemainingTime + this.capture.progress = event.captureProgress + this.capture.count = event.exposureCount + this.capture.amount = event.exposureAmount + if (looping) this.capture.looping = looping + + this.step.elapsedTime = event.stepElapsedTime + this.step.remainingTime = event.stepRemainingTime + this.step.progress = event.stepProgress + + if (event.state === 'EXPOSURING') { + this.state = 'EXPOSURING' + } else if (event.state === 'WAITING') { + this.step.elapsedTime = event.stepElapsedTime + this.step.remainingTime = event.stepRemainingTime + this.step.progress = event.stepProgress + this.state = event.state + } else if (event.state === 'CAPTURE_STARTED') { + this.capture.looping = looping || event.exposureAmount <= 0 + this.capture.amount = event.exposureAmount + this.state = 'EXPOSURING' + } else if (event.state === 'EXPOSURE_STARTED') { + this.state = 'EXPOSURING' + } else if (event.state === 'IDLE' || event.state === 'CAPTURE_FINISHED') { + this.reset() + } else if (event.state !== 'EXPOSURE_FINISHED') { + this.state = event.state + } + + return this.state !== 'CAPTURE_FINISHED' && this.state !== 'IDLE' + } + + reset() { + this.state = 'IDLE' + + this.step = structuredClone(DEFAULT_CAMERA_STEP_INFO) + this.capture = structuredClone(DEFAULT_CAMERA_CAPTURE_INFO) + } +} diff --git a/desktop/src/shared/components/camera-exposure/camera-exposure.component.html b/desktop/src/shared/components/camera-exposure/camera-exposure.component.html deleted file mode 100644 index b8776f6b4..000000000 --- a/desktop/src/shared/components/camera-exposure/camera-exposure.component.html +++ /dev/null @@ -1,66 +0,0 @@ -
- - - {{ info || state || 'IDLE' | enum | lowercase }} - - - - - - {{ capture.count }} - @if (!capture.looping) { - / {{ capture.amount }} - } - - @if (!capture.looping) { - - - {{ capture.progress * 100 | number: '1.1-1' }} - - } - @if (capture.looping) { - - - {{ capture.elapsedTime | exposureTime }} - - } @else { - - @if (showRemainingTime) { - - - {{ capture.remainingTime | exposureTime }} - - } @else { - - - {{ capture.elapsedTime | exposureTime }} - - } - - } - - @if (capture.amount !== 1 && (state === 'EXPOSURING' || state === 'WAITING')) { - - @if (showRemainingTime) { - - - {{ step.remainingTime | exposureTime }} - - } @else { - - - {{ step.elapsedTime | exposureTime }} - - } - - - - {{ step.progress * 100 | number: '1.1-1' }} - - } - -
diff --git a/desktop/src/shared/components/camera-exposure/camera-exposure.component.scss b/desktop/src/shared/components/camera-exposure/camera-exposure.component.scss deleted file mode 100644 index c16fb707b..000000000 --- a/desktop/src/shared/components/camera-exposure/camera-exposure.component.scss +++ /dev/null @@ -1,29 +0,0 @@ -:host { - min-height: 29px; - width: 100%; - - .state { - padding: 1px 6px; - height: 13px; - - &.percentage { - min-width: 50px; - } - - &.time { - min-width: 56px; - } - - &.counter { - min-width: 78px; - } - - .mdi:before { - font-size: 0.9rem !important; - } - } - - .mdi-information::before { - font-size: 0.9rem !important; - } -} diff --git a/desktop/src/shared/components/camera-exposure/camera-exposure.component.ts b/desktop/src/shared/components/camera-exposure/camera-exposure.component.ts deleted file mode 100644 index ddcd59bee..000000000 --- a/desktop/src/shared/components/camera-exposure/camera-exposure.component.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Component, Input } from '@angular/core' -import { CameraCaptureEvent, CameraCaptureState, DEFAULT_CAMERA_CAPTURE_INFO, DEFAULT_CAMERA_STEP_INFO } from '../../types/camera.types' - -@Component({ - selector: 'neb-camera-exposure', - templateUrl: 'camera-exposure.component.html', - styleUrls: ['camera-exposure.component.scss'], -}) -export class CameraExposureComponent { - @Input() - protected info?: string - - @Input() - protected showRemainingTime: boolean = true - - @Input() - protected readonly step = structuredClone(DEFAULT_CAMERA_STEP_INFO) - - @Input() - protected readonly capture = structuredClone(DEFAULT_CAMERA_CAPTURE_INFO) - - protected state: CameraCaptureState = 'IDLE' - - get currentState() { - return this.state - } - - handleCameraCaptureEvent(event: Omit, looping: boolean = false) { - this.capture.elapsedTime = event.captureElapsedTime - this.capture.remainingTime = event.captureRemainingTime - this.capture.progress = event.captureProgress - this.capture.count = event.exposureCount - this.capture.amount = event.exposureAmount - if (looping) this.capture.looping = looping - this.step.elapsedTime = event.stepElapsedTime - this.step.remainingTime = event.stepRemainingTime - this.step.progress = event.stepProgress - - if (event.state === 'EXPOSURING') { - this.state = 'EXPOSURING' - } else if (event.state === 'WAITING') { - this.step.elapsedTime = event.stepElapsedTime - this.step.remainingTime = event.stepRemainingTime - this.step.progress = event.stepProgress - this.state = event.state - } else if (event.state === 'CAPTURE_STARTED') { - this.capture.looping = looping || event.exposureAmount <= 0 - this.capture.amount = event.exposureAmount - this.state = 'EXPOSURING' - } else if (event.state === 'EXPOSURE_STARTED') { - this.state = 'EXPOSURING' - } else if (event.state === 'IDLE' || event.state === 'CAPTURE_FINISHED') { - this.reset() - } else if (event.state !== 'EXPOSURE_FINISHED') { - this.state = event.state - } - - return this.state !== 'CAPTURE_FINISHED' && this.state !== 'IDLE' - } - - reset() { - this.state = 'IDLE' - - Object.assign(this.step, DEFAULT_CAMERA_STEP_INFO) - Object.assign(this.capture, DEFAULT_CAMERA_CAPTURE_INFO) - } -} diff --git a/desktop/src/shared/services/browser-window.service.ts b/desktop/src/shared/services/browser-window.service.ts index 5e97d74c5..cf6b0cdcb 100644 --- a/desktop/src/shared/services/browser-window.service.ts +++ b/desktop/src/shared/services/browser-window.service.ts @@ -31,12 +31,12 @@ export class BrowserWindowService { } openCamera(data: Camera, preference: WindowPreference = {}) { - Object.assign(preference, { icon: 'camera', width: 400, height: 477 }) + Object.assign(preference, { icon: 'camera', width: 390, height: 477 }) return this.openWindow({ preference, data, id: `camera.${data.name}`, path: 'camera' }) } openCameraDialog(data: CameraDialogInput, preference: WindowPreference = {}) { - Object.assign(preference, { icon: 'camera', width: 400, height: 424 }) + Object.assign(preference, { icon: 'camera', width: 390, height: 424 }) return this.openModal({ preference, data, id: `camera.${data.camera.name}.modal`, path: 'camera' }) } From b95788f5c66616be46a8199b5e5e32b350d4f14e Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sat, 7 Dec 2024 14:48:45 -0300 Subject: [PATCH 20/30] [desktop]: Make DialogMenuComponent single file --- desktop/src/app/app.module.ts | 2 +- desktop/src/app/atlas/atlas.component.html | 3 +- desktop/src/app/camera/camera.component.html | 8 +- desktop/src/app/mount/mount.component.html | 24 ++---- desktop/src/app/mount/mount.component.ts | 6 +- .../app/sequencer/sequencer.component.html | 5 +- .../src/app/sequencer/sequencer.component.ts | 8 +- .../components/camera-exposure.component.ts | 4 +- .../components/device-chooser.component.ts | 18 ++-- .../device-list-menu.component.ts | 4 +- .../components/device-name.component.ts | 2 +- .../components/dialog-menu.component.ts | 86 +++++++++++++++++++ .../dialog-menu/dialog-menu.component.html | 22 ----- .../dialog-menu/dialog-menu.component.scss | 5 -- .../dialog-menu/dialog-menu.component.ts | 72 ---------------- .../src/shared/components/map.component.ts | 4 +- .../shared/components/menu-item.component.ts | 2 +- .../src/shared/components/moon.component.ts | 8 +- .../components/path-chooser.component.ts | 16 ++-- .../shared/components/slide-menu.component.ts | 9 +- desktop/src/shared/services/api.service.ts | 6 +- 21 files changed, 145 insertions(+), 169 deletions(-) create mode 100644 desktop/src/shared/components/dialog-menu.component.ts delete mode 100644 desktop/src/shared/components/dialog-menu/dialog-menu.component.html delete mode 100644 desktop/src/shared/components/dialog-menu/dialog-menu.component.scss delete mode 100644 desktop/src/shared/components/dialog-menu/dialog-menu.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index ad2d24b61..453772042 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -53,7 +53,7 @@ import { CheckboxComponent } from '../shared/components/checkbox.component' import { DeviceChooserComponent } from '../shared/components/device-chooser.component' import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' import { DeviceNameComponent } from '../shared/components/device-name.component' -import { DialogMenuComponent } from '../shared/components/dialog-menu/dialog-menu.component' +import { DialogMenuComponent } from '../shared/components/dialog-menu.component' import { DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' import { HistogramComponent } from '../shared/components/histogram.component' import { IndicatorComponent } from '../shared/components/indicator.component' diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index 9f17a5e76..f8f9a7b11 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -579,7 +579,7 @@ + (action)="ephemerisMenu.show(ephemerisModel)" /> @if (body.name && canFavorite) { diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index 15f6ffb22..a24f90526 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -28,14 +28,14 @@ } @if (canShowMenu) { + (action)="cameraMenu.show(cameraModel)" /> }
@if (canShowSavePath) { @@ -307,7 +307,7 @@ + (action)="calibrationMenu.show(calibrationModel)" /> } @if (hasDither) { + (action)="ephemerisMenu.show(ephemerisModel)" />
@@ -155,7 +155,7 @@ [icon]="targetCoordinateCommand.icon" styleClass="w-full" (onClick)="targetCoordinateCommandClicked()" - (onDropdownClick)="targetMenu.show()" /> + (onDropdownClick)="targetMenu.show(targetCoordinateModel)" />
@@ -284,17 +284,13 @@ (valueChange)="trackModeChanged()" />
- - - - +
@@ -389,9 +385,7 @@ diff --git a/desktop/src/app/mount/mount.component.ts b/desktop/src/app/mount/mount.component.ts index 0c3323dd9..b745ea31a 100644 --- a/desktop/src/app/mount/mount.component.ts +++ b/desktop/src/app/mount/mount.component.ts @@ -11,7 +11,7 @@ import { ElectronService } from '../../shared/services/electron.service' import { PreferenceService } from '../../shared/services/preference.service' import { Tickable, Ticker } from '../../shared/services/ticker.service' import { BodyTabType, ComputedLocation, DEFAULT_COMPUTED_LOCATION } from '../../shared/types/atlas.types' -import { DEFAULT_MOUNT, DEFAULT_MOUNT_PREFERENCE, DEFAULT_MOUNT_REMOTE_CONTROL_DIALOG, Mount, MountRemoteControlProtocol, MountSlewDirection, SlewRate, TrackMode } from '../../shared/types/mount.types' +import { DEFAULT_MOUNT, DEFAULT_MOUNT_PREFERENCE, DEFAULT_MOUNT_REMOTE_CONTROL_DIALOG, Mount, MountRemoteControlProtocol, MountSlewDirection, TrackMode } from '../../shared/types/mount.types' import { AppComponent } from '../app.component' @Component({ @@ -40,7 +40,7 @@ export class MountComponent implements AfterContentInit, OnDestroy, Tickable { protected tracking = false protected trackMode: TrackMode = 'SIDEREAL' - protected slewRate?: SlewRate + protected slewRate?: string protected slewingDirection?: MountSlewDirection protected readonly ephemerisModel: SlideMenuItem[] = [ @@ -451,7 +451,7 @@ export class MountComponent implements AfterContentInit, OnDestroy, Tickable { private update() { if (this.mount.id) { this.trackMode = this.mount.trackMode - this.slewRate = this.mount.slewRate + this.slewRate = this.mount.slewRate?.value ?? this.mount.slewRates[0]?.value this.tracking = this.mount.tracking this.computeCoordinatePublisher.next() diff --git a/desktop/src/app/sequencer/sequencer.component.html b/desktop/src/app/sequencer/sequencer.component.html index 425561e21..6e8869c06 100644 --- a/desktop/src/app/sequencer/sequencer.component.html +++ b/desktop/src/app/sequencer/sequencer.component.html @@ -149,7 +149,7 @@ + (click)="showSequenceMenu(sequence, sequenceMenu)" /> diff --git a/desktop/src/app/sequencer/sequencer.component.ts b/desktop/src/app/sequencer/sequencer.component.ts index 4690ea31b..7c00887fa 100644 --- a/desktop/src/app/sequencer/sequencer.component.ts +++ b/desktop/src/app/sequencer/sequencer.component.ts @@ -2,7 +2,7 @@ import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop' import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' -import { DialogMenuComponent } from '../../shared/components/dialog-menu/dialog-menu.component' +import { DialogMenuComponent } from '../../shared/components/dialog-menu.component' import { DropdownItem } from '../../shared/components/dropdown.component' import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' @@ -57,7 +57,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable protected path?: string // NOTE: Remove the "plan.sequences.length <= 1" on layout if add more options - protected readonly sequenceModel: SlideMenuItem[] = [ + private readonly sequenceModel: SlideMenuItem[] = [ { icon: 'mdi mdi-content-copy', label: 'Apply to all', @@ -539,7 +539,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable this.savePreference() } - protected showSequenceMenu(sequence: Sequence, dialogMenu: DialogMenuComponent) { + protected showSequenceMenu(sequence: Sequence, menu: DialogMenuComponent) { this.property.sequence = sequence const index = this.plan.sequences.indexOf(sequence) @@ -555,7 +555,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable this.sequenceModel[7].visible = this.sequenceModel[3].visible if (this.sequenceModel.find((e) => e.visible)) { - dialogMenu.show() + menu.show(this.sequenceModel) } } diff --git a/desktop/src/shared/components/camera-exposure.component.ts b/desktop/src/shared/components/camera-exposure.component.ts index 603e70303..4c1fdb494 100644 --- a/desktop/src/shared/components/camera-exposure.component.ts +++ b/desktop/src/shared/components/camera-exposure.component.ts @@ -83,8 +83,8 @@ import { CameraCaptureEvent, CameraCaptureState, DEFAULT_CAMERA_CAPTURE_INFO, DE encapsulation: ViewEncapsulation.None, }) export class CameraExposureComponent { - protected readonly info = input() - protected readonly showRemainingTime = model(true) + readonly info = input() + readonly showRemainingTime = model(true) protected step = structuredClone(DEFAULT_CAMERA_STEP_INFO) protected capture = structuredClone(DEFAULT_CAMERA_CAPTURE_INFO) diff --git a/desktop/src/shared/components/device-chooser.component.ts b/desktop/src/shared/components/device-chooser.component.ts index 920635778..315f3190a 100644 --- a/desktop/src/shared/components/device-chooser.component.ts +++ b/desktop/src/shared/components/device-chooser.component.ts @@ -39,15 +39,15 @@ import { MenuItem } from './menu-item.component' }) export class DeviceChooserComponent { private readonly api = inject(ApiService) - protected readonly title = input.required() - protected readonly noDeviceMessage = input() - protected readonly icon = input.required() - protected readonly devices = input.required() - protected readonly hasNone = input(false) - protected readonly device = model() - protected readonly disabled = input() - protected readonly deviceConnect = output() - protected readonly deviceDisconnect = output() + readonly title = input.required() + readonly noDeviceMessage = input() + readonly icon = input.required() + readonly devices = input.required() + readonly hasNone = input(false) + readonly device = model() + readonly disabled = input() + readonly deviceConnect = output() + readonly deviceDisconnect = output() private readonly deviceMenu = viewChild.required('deviceMenu') diff --git a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts b/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts index 6209802de..7ec2a2b15 100644 --- a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts +++ b/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts @@ -5,7 +5,7 @@ import { isGuideHead } from '../../types/camera.types' import { Device } from '../../types/device.types' import { deviceComparator } from '../../utils/comparators' import { Undefinable } from '../../utils/types' -import { DialogMenuComponent } from '../dialog-menu/dialog-menu.component' +import { DialogMenuComponent } from '../dialog-menu.component' import { MenuItem, SlideMenuItem } from '../menu-item.component' export interface DeviceConnectionCommandEvent { @@ -73,7 +73,7 @@ export class DeviceListMenuComponent { } } - const subscription = this.menu.visibleChange.subscribe((visible) => { + const subscription = this.menu.visible.subscribe((visible) => { if (!visible) { subscription.unsubscribe() resolve(undefined) diff --git a/desktop/src/shared/components/device-name.component.ts b/desktop/src/shared/components/device-name.component.ts index 4e143c469..62a5d0c91 100644 --- a/desktop/src/shared/components/device-name.component.ts +++ b/desktop/src/shared/components/device-name.component.ts @@ -15,5 +15,5 @@ import type { Device } from '../types/device.types' encapsulation: ViewEncapsulation.None, }) export class DeviceNameComponent { - protected readonly device = input.required() + readonly device = input.required() } diff --git a/desktop/src/shared/components/dialog-menu.component.ts b/desktop/src/shared/components/dialog-menu.component.ts new file mode 100644 index 000000000..00605e96c --- /dev/null +++ b/desktop/src/shared/components/dialog-menu.component.ts @@ -0,0 +1,86 @@ +import { Component, ViewEncapsulation, effect, input, model } from '@angular/core' +import { MenuItemCommandEvent, SlideMenuItem } from './menu-item.component' + +@Component({ + selector: 'neb-dialog-menu', + template: ` + + @if (currentHeader) { + {{ currentHeader }} + } + @if (visible()) { + + } + + `, + styles: ` + neb-dialog-menu { + .p-menuitem-content { + border-radius: 4px; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class DialogMenuComponent { + readonly visible = model(false) + readonly header = input() + readonly updateHeaderWithMenuLabel = input(true) + + protected model: SlideMenuItem[] = [] + protected currentHeader = this.header() + private readonly navigationHeader: string[] = [] + + constructor() { + effect(() => { + this.currentHeader = this.header() + }) + } + + show(model: SlideMenuItem[]) { + this.model = model + this.currentHeader = this.header() + this.visible.set(true) + } + + hide() { + this.visible.set(false) + this.navigationHeader.length = 0 + } + + protected next(event: MenuItemCommandEvent) { + if (!event.item?.slideMenu?.length) { + this.hide() + } else { + this.navigationHeader.push(this.currentHeader ?? '') + + if (this.updateHeaderWithMenuLabel()) { + this.currentHeader = event.item.label + } + } + } + + back() { + if (this.navigationHeader.length) { + const header = this.navigationHeader.splice(this.navigationHeader.length - 1, 1)[0] + + if (this.updateHeaderWithMenuLabel()) { + this.currentHeader = header + } + } + } +} diff --git a/desktop/src/shared/components/dialog-menu/dialog-menu.component.html b/desktop/src/shared/components/dialog-menu/dialog-menu.component.html deleted file mode 100644 index 00e126d90..000000000 --- a/desktop/src/shared/components/dialog-menu/dialog-menu.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - @if (currentHeader) { - {{ currentHeader }} - } - @if (visible) { - - } - diff --git a/desktop/src/shared/components/dialog-menu/dialog-menu.component.scss b/desktop/src/shared/components/dialog-menu/dialog-menu.component.scss deleted file mode 100644 index 01a42993d..000000000 --- a/desktop/src/shared/components/dialog-menu/dialog-menu.component.scss +++ /dev/null @@ -1,5 +0,0 @@ -neb-dialog-menu { - .p-menuitem-content { - border-radius: 4px; - } -} diff --git a/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts b/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts deleted file mode 100644 index 64bbd031e..000000000 --- a/desktop/src/shared/components/dialog-menu/dialog-menu.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core' -import { Undefinable } from '../../utils/types' -import { MenuItemCommandEvent, SlideMenuItem } from '../menu-item.component' - -@Component({ - selector: 'neb-dialog-menu', - templateUrl: 'dialog-menu.component.html', - styleUrls: ['dialog-menu.component.scss'], - encapsulation: ViewEncapsulation.None, -}) -export class DialogMenuComponent implements OnChanges { - @Input() - protected visible = false - - @Output() - readonly visibleChange = new EventEmitter() - - @Input() - protected model: SlideMenuItem[] = [] - - @Input() - protected header?: string - - @Input() - protected updateHeaderWithMenuLabel: boolean = true - - protected currentHeader = this.header - private readonly navigationHeader: Undefinable[] = [] - - ngOnChanges(changes: SimpleChanges) { - for (const key in changes) { - if (key === 'header') { - this.currentHeader = changes[key].currentValue as string - } - } - } - - show(model?: SlideMenuItem[]) { - if (model?.length) this.model = model - this.currentHeader = this.header - this.visible = true - this.visibleChange.emit(true) - } - - hide() { - this.visible = false - this.navigationHeader.length = 0 - this.visibleChange.emit(false) - } - - protected next(event: MenuItemCommandEvent) { - if (!event.item?.slideMenu?.length) { - this.hide() - } else { - this.navigationHeader.push(this.currentHeader) - - if (this.updateHeaderWithMenuLabel) { - this.currentHeader = event.item.label - } - } - } - - back() { - if (this.navigationHeader.length) { - const header = this.navigationHeader.splice(this.navigationHeader.length - 1, 1)[0] - - if (this.updateHeaderWithMenuLabel) { - this.currentHeader = header - } - } - } -} diff --git a/desktop/src/shared/components/map.component.ts b/desktop/src/shared/components/map.component.ts index 9cfe9cfcc..e22396888 100644 --- a/desktop/src/shared/components/map.component.ts +++ b/desktop/src/shared/components/map.component.ts @@ -18,8 +18,8 @@ import * as L from 'leaflet' encapsulation: ViewEncapsulation.None, }) export class MapComponent implements AfterViewInit, OnChanges { - protected readonly latitude = model(0) - protected readonly longitude = model(0) + readonly latitude = model(0) + readonly longitude = model(0) private readonly mapRef = viewChild.required>('map') diff --git a/desktop/src/shared/components/menu-item.component.ts b/desktop/src/shared/components/menu-item.component.ts index ea1d911e0..aa1065aaf 100644 --- a/desktop/src/shared/components/menu-item.component.ts +++ b/desktop/src/shared/components/menu-item.component.ts @@ -82,5 +82,5 @@ export interface SlideMenuItem extends MenuItem { encapsulation: ViewEncapsulation.None, }) export class MenuItemComponent { - protected readonly item = input.required() + readonly item = input.required() } diff --git a/desktop/src/shared/components/moon.component.ts b/desktop/src/shared/components/moon.component.ts index 57f80efbb..1866ba7b1 100644 --- a/desktop/src/shared/components/moon.component.ts +++ b/desktop/src/shared/components/moon.component.ts @@ -12,10 +12,10 @@ import { AfterViewInit, Component, ElementRef, OnChanges, ViewEncapsulation, inp encapsulation: ViewEncapsulation.None, }) export class MoonComponent implements AfterViewInit, OnChanges { - protected readonly height = input(256) - protected readonly width = input(256) - protected readonly illuminationRatio = input(0) - protected readonly waning = input(false) + readonly height = input(256) + readonly width = input(256) + readonly illuminationRatio = input(0) + readonly waning = input(false) private readonly moonRef = viewChild.required>('moon') diff --git a/desktop/src/shared/components/path-chooser.component.ts b/desktop/src/shared/components/path-chooser.component.ts index 88ac0aab7..a8f3ff28d 100644 --- a/desktop/src/shared/components/path-chooser.component.ts +++ b/desktop/src/shared/components/path-chooser.component.ts @@ -23,14 +23,14 @@ import { ElectronService } from '../services/electron.service' export class PathChooserComponent { private readonly electronService = inject(ElectronService) - protected readonly key = input.required() - protected readonly label = input() - protected readonly placeholder = input() - protected readonly path = model() - protected readonly disabled = input(false) - protected readonly readonly = input(false) - protected readonly directory = input.required() - protected readonly save = input(false) + readonly key = input.required() + readonly label = input() + readonly placeholder = input() + readonly path = model() + readonly disabled = input(false) + readonly readonly = input(false) + readonly directory = input.required() + readonly save = input(false) protected async choosePath() { const key = this.key() diff --git a/desktop/src/shared/components/slide-menu.component.ts b/desktop/src/shared/components/slide-menu.component.ts index 5fe0b13a1..5889271ac 100644 --- a/desktop/src/shared/components/slide-menu.component.ts +++ b/desktop/src/shared/components/slide-menu.component.ts @@ -1,5 +1,4 @@ import { Component, ElementRef, OnInit, TemplateRef, ViewEncapsulation, input, output } from '@angular/core' -import type { Nullable } from '../utils/types' import { MenuItemCommandEvent, SlideMenuItem } from './menu-item.component' @Component({ @@ -27,10 +26,10 @@ import { MenuItemCommandEvent, SlideMenuItem } from './menu-item.component' encapsulation: ViewEncapsulation.None, }) export class SlideMenuComponent implements OnInit { - protected readonly model = input.required() - protected readonly appendTo = input | string>>() - protected readonly forward = output() - protected readonly backward = output() + readonly model = input.required() + readonly appendTo = input | 'body' | undefined | null>() + readonly forward = output() + readonly backward = output() protected currentMenu!: SlideMenuItem[] diff --git a/desktop/src/shared/services/api.service.ts b/desktop/src/shared/services/api.service.ts index 5ae83a12d..a992bc78d 100644 --- a/desktop/src/shared/services/api.service.ts +++ b/desktop/src/shared/services/api.service.ts @@ -14,7 +14,7 @@ import { GuideDirection, GuideOutput, Guider, GuiderHistoryStep, SettleInfo } fr import { ConnectionStatus, ConnectionType, GitHubRelease } from '../types/home.types' import { AnnotateImageRequest, CoordinateInterpolation, DetectedStar, FOVCamera, FOVTelescope, ImageAnalyzed, ImageAnnotation, ImageChannel, ImageInfo, ImageMousePosition, ImageSaveDialog, ImageSolved, ImageStatistics, ImageTransformation } from '../types/image.types' import { LightBox } from '../types/lightbox.types' -import { CelestialLocationType, Mount, MountRemoteControl, MountRemoteControlProtocol, SlewRate, TrackMode } from '../types/mount.types' +import { CelestialLocationType, Mount, MountRemoteControl, MountRemoteControlProtocol, TrackMode } from '../types/mount.types' import { PlateSolverRequest } from '../types/platesolver.types' import { Rotator } from '../types/rotator.types' import { SequencerPlan } from '../types/sequencer.types' @@ -158,8 +158,8 @@ export class ApiService { return this.http.put(`mounts/${mount.id}/track-mode?mode=${mode}`) } - mountSlewRate(mount: Mount, rate: SlewRate) { - return this.http.put(`mounts/${mount.id}/slew-rate?rate=${rate.value}`) + mountSlewRate(mount: Mount, rate: string) { + return this.http.put(`mounts/${mount.id}/slew-rate?rate=${rate}`) } mountMove(mount: Mount, direction: GuideDirection, enabled: boolean) { From f8decadbd2310db89f7e052379d65e9fc0217064 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sat, 7 Dec 2024 15:44:00 -0300 Subject: [PATCH 21/30] [desktop]: Encapsulate p-dropdown into neb-dropdown --- desktop/src/app/app.module.ts | 3 +- desktop/src/app/atlas/atlas.component.html | 18 ++++------ desktop/src/app/image/image.component.html | 16 +++------ desktop/src/app/indi/indi.component.html | 17 ++++------ desktop/src/app/indi/indi.component.ts | 13 +++++-- .../src/app/settings/settings.component.html | 26 ++++---------- .../src/app/settings/settings.component.ts | 1 - .../shared/components/dropdown.component.ts | 34 +++++++++++++++++++ 8 files changed, 70 insertions(+), 58 deletions(-) diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 453772042..cd84c4e2e 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -54,7 +54,7 @@ import { DeviceChooserComponent } from '../shared/components/device-chooser.comp import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' import { DeviceNameComponent } from '../shared/components/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu.component' -import { DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' +import { DropdownComponent, DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' import { HistogramComponent } from '../shared/components/histogram.component' import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' @@ -132,6 +132,7 @@ import { SettingsComponent } from './settings/settings.component' DeviceListMenuComponent, DeviceNameComponent, DialogMenuComponent, + DropdownComponent, DropdownItemComponent, DropdownEnumComponent, DropdownOptionsPipe, diff --git a/desktop/src/app/atlas/atlas.component.html b/desktop/src/app/atlas/atlas.component.html index f8f9a7b11..9b1d2b352 100644 --- a/desktop/src/app/atlas/atlas.component.html +++ b/desktop/src/app/atlas/atlas.component.html @@ -773,18 +773,12 @@ (valueChange)="timeChanged(undefined, $event)" [format]="false" />
- - - - +
diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index 55e25aa69..4452b3470 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -781,17 +781,11 @@ [value]="(statistics.statistics.maximum * statistics.bitOption.rangeMax).toFixed(statistics.bitOption.decimalPlaces)" />
- - - - +
- - - - +
- - - -
- {{ preference.location.name || '?' }} -
-
-
- -
+
diff --git a/desktop/src/app/settings/settings.component.ts b/desktop/src/app/settings/settings.component.ts index 48d82d8b8..e42f1f94d 100644 --- a/desktop/src/app/settings/settings.component.ts +++ b/desktop/src/app/settings/settings.component.ts @@ -139,7 +139,6 @@ export class SettingsComponent implements AfterViewInit, OnDestroy { protected locationChanged(location?: Location) { if (location) { - this.preference.location = location this.savePreference() this.locationChangePublisher.next(location) } diff --git a/desktop/src/shared/components/dropdown.component.ts b/desktop/src/shared/components/dropdown.component.ts index de6418d48..97f50331d 100644 --- a/desktop/src/shared/components/dropdown.component.ts +++ b/desktop/src/shared/components/dropdown.component.ts @@ -5,6 +5,40 @@ export interface DropdownItem { value: T } +@Component({ + selector: 'neb-dropdown', + template: ` + + + + + `, + styles: ` + neb-dropdown { + width: 100%; + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class DropdownComponent { + readonly label = input() + readonly options = input([]) + readonly value = model() + readonly optionLabel = input('name') + readonly optionValue = input() + readonly disabled = input(false) + readonly emptyMessage = input('Not available') +} + @Component({ selector: 'neb-dropdown-item', template: ` From b4eab83eca23050c56d1daf22f5453b414218e68 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 10:59:59 -0300 Subject: [PATCH 22/30] [desktop]: Encapsulate p-dropdown into neb-dropdown --- .../app/calculator/calculator.component.html | 36 ++++----- .../filterwheel/filterwheel.component.html | 76 +++++++---------- .../src/app/framing/framing.component.html | 44 ++++------ desktop/src/app/home/home.component.html | 81 +++++++++---------- .../shared/components/dropdown.component.ts | 77 ++++++++++++++++-- desktop/src/styles.scss | 1 + 6 files changed, 171 insertions(+), 144 deletions(-) diff --git a/desktop/src/app/calculator/calculator.component.html b/desktop/src/app/calculator/calculator.component.html index 40d22736c..865e4d02c 100644 --- a/desktop/src/app/calculator/calculator.component.html +++ b/desktop/src/app/calculator/calculator.component.html @@ -1,27 +1,21 @@
- - -
- {{ item?.formula?.title }} -
-
- -
- {{ item.formula.title }} + +
+ {{ item.formula.title }} + + @if (!selected) { {{ item.formula.description }} -
-
- + } +
+
+
diff --git a/desktop/src/app/filterwheel/filterwheel.component.html b/desktop/src/app/filterwheel/filterwheel.component.html index 572128754..60163b8ae 100644 --- a/desktop/src/app/filterwheel/filterwheel.component.html +++ b/desktop/src/app/filterwheel/filterwheel.component.html @@ -33,53 +33,35 @@
- - - -
- - @if (filter) { - - - @if (filter.dark) { - - } - } - - {{ filter?.name }} -
-
- -
- - - - @if (item.dark) { - - } - - {{ item.name }} -
-
-
- -
+ +
+ @let mItem = selected ? filter : item; + + + @if (mItem) { + + + @if (mItem.dark) { + + } + } + + {{ mItem?.name }} +
+
+
- - - -
- {{ item?.regime }} ({{ item?.skyFraction | percent: '1.1-1' }}) - {{ item?.id }} -
-
- -
- {{ item.regime }} ({{ item?.skyFraction | percent: '1.1-1' }}) - {{ item.id }} -
-
-
- -
+ +
+ {{ item?.regime }} ({{ item?.skyFraction | percent: '1.1-1' }}) + {{ item?.id }} +
+
+
- - - -
- {{ connection?.name }} -
-
- -
-
- {{ item.name }} - {{ item.type }} | {{ item.host }}:{{ item.port }} -
- - {{ (item.connectedAt | date: 'yyyy-MM-dd HH:mm:ss') ?? 'never' }} -
-
-
- - + + @if (selected) { +
+ {{ connection?.name }} +
+ } @else { +
+
+ {{ item.name }} + {{ item.type }} | {{ item.host }}:{{ item.port }} +
+ + {{ (item.connectedAt | date: 'yyyy-MM-dd HH:mm:ss') ?? 'never' }}
- - - - +
+ + +
+
+ } +
+ @if (!connected) { { label: string value: T } +abstract class DropdownBaseComponent { + abstract readonly label: Signal + abstract readonly options: Signal + abstract readonly value: WritableSignal + abstract readonly disabled: Signal + abstract readonly filter: Signal + abstract readonly emptyMessage: Signal + protected abstract readonly dropdown: Signal + + hide() { + this.dropdown().hide() + } +} + @Component({ selector: 'neb-dropdown', template: ` + appendTo="body" + [panelStyle]="{ maxWidth: '90vw' }"> + + @if (itemTemplate()) { + + } @else { +
+ {{ itemLabel(item) }} +
+ } +
+ + @if (itemTemplate()) { + + } @else { +
+ {{ itemLabel(item) }} +
+ } +
+
`, @@ -29,14 +75,22 @@ export interface DropdownItem { `, encapsulation: ViewEncapsulation.None, }) -export class DropdownComponent { +export class DropdownComponent extends DropdownBaseComponent { readonly label = input() readonly options = input([]) readonly value = model() readonly optionLabel = input('name') readonly optionValue = input() readonly disabled = input(false) + readonly filter = input(false) + readonly filterFields = input() readonly emptyMessage = input('Not available') + readonly itemTemplate = input>() + protected readonly dropdown = viewChild.required('dropdown') + + protected itemLabel(item: unknown) { + return (item as Record)[this.optionLabel()] ?? `${item}` + } } @Component({ @@ -44,15 +98,19 @@ export class DropdownComponent { template: ` + appendTo="body" + [panelStyle]="{ maxWidth: '90vw' }" /> `, @@ -63,12 +121,14 @@ export class DropdownComponent { `, encapsulation: ViewEncapsulation.None, }) -export class DropdownItemComponent { +export class DropdownItemComponent extends DropdownBaseComponent, T> { readonly label = input() readonly options = input[]>([]) readonly value = model() readonly disabled = input(false) + readonly filter = input(false) readonly emptyMessage = input('Not available') + readonly dropdown = viewChild.required('dropdown') } @Component({ @@ -76,6 +136,7 @@ export class DropdownItemComponent { template: ` { [emptyMessage]="emptyMessage()" [filter]="filter()" [autoDisplayFirst]="false" - appendTo="body" /> + appendTo="body" + [panelStyle]="{ maxWidth: '90vw' }" /> `, @@ -96,11 +158,12 @@ export class DropdownItemComponent { `, encapsulation: ViewEncapsulation.None, }) -export class DropdownEnumComponent { +export class DropdownEnumComponent extends DropdownBaseComponent { readonly label = input() readonly options = input([]) readonly value = model() readonly filter = input(false) readonly disabled = input(false) readonly emptyMessage = input('Not available') + readonly dropdown = viewChild.required('dropdown') } diff --git a/desktop/src/styles.scss b/desktop/src/styles.scss index 749071bc2..904690c1c 100644 --- a/desktop/src/styles.scss +++ b/desktop/src/styles.scss @@ -268,6 +268,7 @@ p-dropdown *, p-dropdownitem *, p-tieredmenu *, .p-multiselect-header *, +.p-dropdown-header *, .no-draggable-region, .p-button.p-dialog-header-close { -webkit-app-region: no-drag; From 46487c112fc42a3eae3d462c55b4de3af759edd2 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 11:31:46 -0300 Subject: [PATCH 23/30] [desktop]: Encapsulate p-selectButton into neb-select-button-enum --- desktop/src/app/app.module.ts | 3 + desktop/src/app/camera/camera.component.html | 11 ++- desktop/src/app/home/home.component.html | 5 +- desktop/src/app/image/image.component.html | 32 +++------ desktop/src/app/mount/mount.component.html | 7 +- .../components/select-button.component.ts | 71 +++++++++++++++++++ 6 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 desktop/src/shared/components/select-button.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index cd84c4e2e..196fa4a2c 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -65,6 +65,7 @@ import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.compone import { MenuItemComponent } from '../shared/components/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser.component' +import { SelectButtonEnumComponent, SelectButtonItemComponent } from '../shared/components/select-button.component' import { SlideMenuComponent } from '../shared/components/slide-menu.component' import { SwitchComponent } from '../shared/components/switch.component' import { TagComponent } from '../shared/components/tag.component' @@ -166,6 +167,8 @@ import { SettingsComponent } from './settings/settings.component' NoDropdownDirective, PathChooserComponent, RotatorComponent, + SelectButtonEnumComponent, + SelectButtonItemComponent, SequencerComponent, SettingsComponent, SlideMenuComponent, diff --git a/desktop/src/app/camera/camera.component.html b/desktop/src/app/camera/camera.component.html index a24f90526..73b6f7d5c 100644 --- a/desktop/src/app/camera/camera.component.html +++ b/desktop/src/app/camera/camera.component.html @@ -172,14 +172,11 @@
Exposure Mode - + [options]="'EXPOSURE_MODE' | dropdownOptions" + [(value)]="preference.exposureMode" + (valueChange)="savePreference()" />
- + [(value)]="connectionDialog.connection.type" />
diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index 4452b3470..309d1de1f 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -646,15 +646,10 @@ class="pointer-events-none">
- +
- + [options]="'IMAGE_CHANNEL' | dropdownOptions" + [(value)]="statistics.channel" + (valueChange)="computeStatistics(true)" />
- + [(value)]="saveAs.format" />
@if (imageInfo) {
diff --git a/desktop/src/app/mount/mount.component.html b/desktop/src/app/mount/mount.component.html index 6575a3ce8..3e1f8c35e 100644 --- a/desktop/src/app/mount/mount.component.html +++ b/desktop/src/app/mount/mount.component.html @@ -102,12 +102,11 @@
- + [(value)]="preference.targetCoordinateType" + (valueChange)="computeTargetCoordinates()" />
diff --git a/desktop/src/shared/components/select-button.component.ts b/desktop/src/shared/components/select-button.component.ts new file mode 100644 index 000000000..4359c1196 --- /dev/null +++ b/desktop/src/shared/components/select-button.component.ts @@ -0,0 +1,71 @@ +import { Component, input, model, Signal, viewChild, ViewEncapsulation, WritableSignal } from '@angular/core' +import { SelectButton } from 'primeng/selectbutton' +import { DropdownItem } from './dropdown.component' + +abstract class SelectButtonBaseComponent { + abstract readonly options: Signal + abstract readonly value: WritableSignal + abstract readonly disabled: Signal + protected abstract readonly button: Signal +} + +@Component({ + selector: 'neb-select-button-item', + template: ` + + `, + styles: ` + neb-select-button-enum { + width: 100%; + + .p-button { + font-size: 0.875rem; + padding: 0.652625rem 0.65625rem; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class SelectButtonItemComponent extends SelectButtonBaseComponent, T> { + readonly options = input[]>([]) + readonly value = model() + readonly disabled = input(false) + readonly button = viewChild.required('button') +} + +@Component({ + selector: 'neb-select-button-enum', + template: ` + + `, + styles: ` + neb-select-button-enum { + width: 100%; + + .p-button { + font-size: 0.875rem; + padding: 0.652625rem 0.65625rem; + } + } + `, + encapsulation: ViewEncapsulation.None, +}) +export class SelectButtonEnumComponent extends SelectButtonBaseComponent { + readonly options = input([]) + readonly value = model() + readonly disabled = input(false) + readonly button = viewChild.required('button') +} From f2a1c64eb54ee39bcb7a743a6a38e74cb1140384 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 12:29:44 -0300 Subject: [PATCH 24/30] [desktop]: Make CameraInfoComponent single file --- desktop/src/app/app.module.ts | 2 +- desktop/src/app/image/image.component.html | 34 ++--- .../components/camera-info.component.ts | 127 ++++++++++++++++++ .../camera-info/camera-info.component.html | 88 ------------ .../camera-info/camera-info.component.ts | 57 -------- desktop/src/styles.scss | 36 +++-- 6 files changed, 165 insertions(+), 179 deletions(-) create mode 100644 desktop/src/shared/components/camera-info.component.ts delete mode 100644 desktop/src/shared/components/camera-info/camera-info.component.html delete mode 100644 desktop/src/shared/components/camera-info/camera-info.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 196fa4a2c..4036179f5 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -48,7 +48,7 @@ import { TreeModule } from 'primeng/tree' import { ButtonImageComponent } from '../shared/components/button-image.component' import { ButtonComponent } from '../shared/components/button.component' import { CameraExposureComponent } from '../shared/components/camera-exposure.component' -import { CameraInfoComponent } from '../shared/components/camera-info/camera-info.component' +import { CameraInfoComponent } from '../shared/components/camera-info.component' import { CheckboxComponent } from '../shared/components/checkbox.component' import { DeviceChooserComponent } from '../shared/components/device-chooser.component' import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' diff --git a/desktop/src/app/image/image.component.html b/desktop/src/app/image/image.component.html index 309d1de1f..ec86da3b7 100644 --- a/desktop/src/app/image/image.component.html +++ b/desktop/src/app/image/image.component.html @@ -596,17 +596,14 @@ [(ngModel)]="stretch.transformation.midtone" />
- - - - +
Pixel Size (µm)
- - - - +
+ @let mInfo = info(); + + @if (hasType()) { +
+ + {{ mInfo.frameType }} +
+ } + @if (hasExposure() && mInfo.exposureTime) { +
+ + {{ mInfo.exposureAmount || '∞' }} / {{ mInfo.exposureTime | exposureTime }} +
+ } + @if (mInfo.exposureDelay) { +
+ + {{ mInfo.exposureDelay * 1000000 | exposureTime }} +
+ } + @if (mInfo.x !== undefined && mInfo.y !== undefined && mInfo.width && mInfo.height) { +
+ + {{ mInfo.x }} {{ mInfo.y }} {{ mInfo.width }} {{ mInfo.height }} +
+ } + @if (mInfo.binX && mInfo.binY) { +
+ + {{ mInfo.binX }}x{{ mInfo.binY }} +
+ } + @if (mInfo.gain) { +
+ + {{ mInfo.gain }} +
+ } + @if (mInfo.offset) { +
+ + {{ mInfo.offset }} +
+ } + @if (mInfo.frameFormat) { +
+ + {{ mInfo.frameFormat }} +
+ } + @if (hasFilter) { +
+
+ + {{ filter }} +
+ @if (canRemoveFilter() && !disabled()) { + + } +
+ } + @if (hasFilter && focuser() && mInfo.focusOffset) { +
+ + {{ mInfo.focusOffset }} +
+ } + @if (rotator() && mInfo.angle >= 0) { +
+
+ + {{ mInfo.angle.toFixed(1) }}° +
+ @if (canRemoveAngle() && !disabled()) { + + } +
+ } +
+ `, + encapsulation: ViewEncapsulation.None, +}) +export class CameraInfoComponent { + readonly info = input.required() + readonly disabled = input(false) + readonly wheel = input() + readonly focuser = input() + readonly rotator = input() + readonly hasType = input(true) + readonly hasExposure = input(true) + readonly canRemoveFilter = input(false) + readonly canRemoveAngle = input(false) + readonly filterRemoved = output() + readonly angleRemoved = output() + + get hasFilter() { + const wheel = this.wheel() + return !!wheel && !!this.info().filterPosition && wheel.connected + } + + get filter() { + const wheel = this.wheel() + const info = this.info() + + if (wheel && info.filterPosition) { + return wheel.names[info.filterPosition - 1] || `#${info.filterPosition}` + } else { + return undefined + } + } +} diff --git a/desktop/src/shared/components/camera-info/camera-info.component.html b/desktop/src/shared/components/camera-info/camera-info.component.html deleted file mode 100644 index 05761a7ab..000000000 --- a/desktop/src/shared/components/camera-info/camera-info.component.html +++ /dev/null @@ -1,88 +0,0 @@ -
- @if (hasType) { -
- - {{ info.frameType }} -
- } - @if (hasExposure && info.exposureTime) { -
- - {{ info.exposureAmount || '∞' }} / {{ info.exposureTime | exposureTime }} -
- } - @if (info.exposureDelay) { -
- - {{ info.exposureDelay * 1000000 | exposureTime }} -
- } - @if (info.x !== undefined && info.y !== undefined && info.width && info.height) { -
- - {{ info.x }} {{ info.y }} {{ info.width }} {{ info.height }} -
- } - @if (info.binX && info.binY) { -
- - {{ info.binX }}x{{ info.binY }} -
- } - @if (info.gain) { -
- - {{ info.gain }} -
- } - @if (info.offset) { -
- - {{ info.offset }} -
- } - @if (info.frameFormat) { -
- - {{ info.frameFormat }} -
- } - @if (hasFilter) { -
-
- - {{ filter }} -
- @if (canRemoveFilter && !disabled) { - - } -
- } - @if (hasFilter && focuser && info.focusOffset) { -
- - {{ info.focusOffset }} -
- } - @if (rotator && info.angle >= 0) { -
-
- - {{ info.angle.toFixed(1) }}° -
- @if (canRemoveAngle && !disabled) { - - } -
- } -
diff --git a/desktop/src/shared/components/camera-info/camera-info.component.ts b/desktop/src/shared/components/camera-info/camera-info.component.ts deleted file mode 100644 index d80380794..000000000 --- a/desktop/src/shared/components/camera-info/camera-info.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core' -import type { CameraStartCapture } from '../../types/camera.types' -import type { Focuser } from '../../types/focuser.types' -import type { Rotator } from '../../types/rotator.types' -import type { Wheel } from '../../types/wheel.types' - -@Component({ - selector: 'neb-camera-info', - templateUrl: 'camera-info.component.html', - encapsulation: ViewEncapsulation.None, -}) -export class CameraInfoComponent { - @Input({ required: true }) - protected readonly info!: CameraStartCapture - - @Input() - protected readonly wheel?: Wheel - - @Input() - protected readonly focuser?: Focuser - - @Input() - protected readonly rotator?: Rotator - - @Input() - protected readonly hasType: boolean = true - - @Input() - protected readonly hasExposure: boolean = true - - @Input() - protected readonly canRemoveFilter = false - - @Output() - protected readonly filterRemoved = new EventEmitter() - - @Input() - protected readonly canRemoveAngle = false - - @Output() - protected readonly angleRemoved = new EventEmitter() - - @Input() - protected readonly disabled?: boolean = false - - get hasFilter() { - return !!this.wheel && !!this.info.filterPosition && this.wheel.connected - } - - get filter() { - if (this.wheel && this.info.filterPosition) { - return this.wheel.names[this.info.filterPosition - 1] || `#${this.info.filterPosition}` - } else { - return undefined - } - } -} diff --git a/desktop/src/styles.scss b/desktop/src/styles.scss index 904690c1c..3f8890eff 100644 --- a/desktop/src/styles.scss +++ b/desktop/src/styles.scss @@ -96,23 +96,33 @@ p-table { width: 100%; } -.mdi:before { - display: inline-flex; - justify-content: center; +.mdi { align-items: center; - aspect-ratio: 1; -} + justify-content: center; + vertical-align: middle; + line-height: 0px; + + &::before { + display: inline-flex; + justify-content: center; + align-items: center; + aspect-ratio: 1; + font-size: 1.25rem; + line-height: 0px; + vertical-align: middle; + } -.mdi:before { - font-size: 1.25rem; -} + &.mdi-sm::before { + font-size: 1rem; + } -.mdi.mdi-sm:before { - font-size: 1.05rem; -} + &.mdi-xs::before { + font-size: 0.9rem; + } -.mdi.mdi-lg:before { - font-size: 2rem; + &.mdi-lg::before { + font-size: 2rem; + } } .p-selectbutton { From db80253ffeae02aeccc2101fd80ab550355f6525 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 12:34:07 -0300 Subject: [PATCH 25/30] [desktop]: Make MenuBarComponent single file --- desktop/src/app/app.module.ts | 2 +- .../shared/components/menu-bar.component.ts | 77 +++++++++++++++++++ .../menu-bar/menu-bar.component.html | 58 -------------- .../components/menu-bar/menu-bar.component.ts | 19 ----- 4 files changed, 78 insertions(+), 78 deletions(-) create mode 100644 desktop/src/shared/components/menu-bar.component.ts delete mode 100644 desktop/src/shared/components/menu-bar/menu-bar.component.html delete mode 100644 desktop/src/shared/components/menu-bar/menu-bar.component.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 4036179f5..d001de66c 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -61,7 +61,7 @@ import { InputNumberComponent } from '../shared/components/input-number.componen import { InputTextComponent } from '../shared/components/input-text.component' import { LocationComponent } from '../shared/components/location/location.dialog' import { MapComponent } from '../shared/components/map.component' -import { MenuBarComponent } from '../shared/components/menu-bar/menu-bar.component' +import { MenuBarComponent } from '../shared/components/menu-bar.component' import { MenuItemComponent } from '../shared/components/menu-item.component' import { MoonComponent } from '../shared/components/moon.component' import { PathChooserComponent } from '../shared/components/path-chooser.component' diff --git a/desktop/src/shared/components/menu-bar.component.ts b/desktop/src/shared/components/menu-bar.component.ts new file mode 100644 index 000000000..5d91afdfc --- /dev/null +++ b/desktop/src/shared/components/menu-bar.component.ts @@ -0,0 +1,77 @@ +import { Component, input, output, ViewEncapsulation } from '@angular/core' +import { MenuItem } from './menu-item.component' + +export interface SplitButtonClickEvent { + event: MouseEvent + item: MenuItem +} + +@Component({ + selector: 'neb-menu-bar', + template: ` +
+ @for (item of model(); track item; let i = $index) { + + @if (item.visible !== false) { + @if (item.toggleable) { + @if (item.visible) { +
+ +
+ } + } @else if (item.checkable) { + @if (item.visible) { +
+ +
+ } + } @else if (item.label && item.splitButtonMenu?.length) { + + } @else { + @if (item.badge) { + + } + + } + } +
+ } +
+ `, + encapsulation: ViewEncapsulation.None, +}) +export class MenuBarComponent { + readonly model = input.required() + readonly splitButtonClick = output() +} diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.html b/desktop/src/shared/components/menu-bar/menu-bar.component.html deleted file mode 100644 index da3d2c17d..000000000 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.html +++ /dev/null @@ -1,58 +0,0 @@ -
- @for (item of model; track item; let i = $index) { - - @if (item.visible !== false) { - @if (item.toggleable) { - @if (item.visible) { -
- -
- } - } @else if (item.checkable) { - @if (item.visible) { -
- -
- } - } @else if (item.label && item.splitButtonMenu?.length) { - - } @else { - @if (item.badge) { - - } - - } - } -
- } -
diff --git a/desktop/src/shared/components/menu-bar/menu-bar.component.ts b/desktop/src/shared/components/menu-bar/menu-bar.component.ts deleted file mode 100644 index aa961f316..000000000 --- a/desktop/src/shared/components/menu-bar/menu-bar.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core' -import { MenuItem } from '../menu-item.component' - -export interface SplitButtonClickEvent { - event: MouseEvent - item: MenuItem -} - -@Component({ - selector: 'neb-menu-bar', - templateUrl: 'menu-bar.component.html', -}) -export class MenuBarComponent { - @Input({ required: true }) - protected readonly model!: MenuItem[] - - @Output() - readonly splitButtonClick = new EventEmitter() -} From 2b086a758e0ee7b6c944a253a526dbe1e49eda90 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 12:50:54 -0300 Subject: [PATCH 26/30] [desktop]: Make DeviceListMenuComponent single file --- desktop/src/app/app.module.ts | 2 +- desktop/src/app/atlas/atlas.component.ts | 2 +- desktop/src/app/home/home.component.ts | 2 +- desktop/src/app/image/image.component.ts | 2 +- .../components/device-chooser.component.ts | 2 +- .../device-list-menu.component.ts | 92 ++++++++++--------- .../device-list-menu.component.html | 3 - .../device-list-menu.component.scss | 6 -- desktop/src/shared/services/device.service.ts | 2 +- 9 files changed, 54 insertions(+), 59 deletions(-) rename desktop/src/shared/components/{device-list-menu => }/device-list-menu.component.ts (51%) delete mode 100644 desktop/src/shared/components/device-list-menu/device-list-menu.component.html delete mode 100644 desktop/src/shared/components/device-list-menu/device-list-menu.component.scss diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index d001de66c..85d467eb8 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -51,7 +51,7 @@ import { CameraExposureComponent } from '../shared/components/camera-exposure.co import { CameraInfoComponent } from '../shared/components/camera-info.component' import { CheckboxComponent } from '../shared/components/checkbox.component' import { DeviceChooserComponent } from '../shared/components/device-chooser.component' -import { DeviceListMenuComponent } from '../shared/components/device-list-menu/device-list-menu.component' +import { DeviceListMenuComponent } from '../shared/components/device-list-menu.component' import { DeviceNameComponent } from '../shared/components/device-name.component' import { DialogMenuComponent } from '../shared/components/dialog-menu.component' import { DropdownComponent, DropdownEnumComponent, DropdownItemComponent } from '../shared/components/dropdown.component' diff --git a/desktop/src/app/atlas/atlas.component.ts b/desktop/src/app/atlas/atlas.component.ts index f9871ae6a..410c8ad2f 100644 --- a/desktop/src/app/atlas/atlas.component.ts +++ b/desktop/src/app/atlas/atlas.component.ts @@ -6,7 +6,7 @@ import { UIChart } from 'primeng/chart' import { ListboxChangeEvent } from 'primeng/listbox' import { OverlayPanel } from 'primeng/overlaypanel' import { timer } from 'rxjs' -import { DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' +import { DeviceListMenuComponent } from '../../shared/components/device-list-menu.component' import { SlideMenuItem } from '../../shared/components/menu-item.component' import { ONE_DECIMAL_PLACE_FORMATTER, TWO_DIGITS_FORMATTER } from '../../shared/constants' import { AngularService } from '../../shared/services/angular.service' diff --git a/desktop/src/app/home/home.component.ts b/desktop/src/app/home/home.component.ts index d9c64f92a..f75082c0b 100644 --- a/desktop/src/app/home/home.component.ts +++ b/desktop/src/app/home/home.component.ts @@ -1,7 +1,7 @@ import { AfterContentInit, Component, inject, NgZone, ViewChild, ViewEncapsulation } from '@angular/core' import packageJson from '../../../package.json' with { type: 'json' } import { DeviceChooserComponent } from '../../shared/components/device-chooser.component' -import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' +import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../../shared/components/device-list-menu.component' import { MenuItem, SlideMenuItem } from '../../shared/components/menu-item.component' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' diff --git a/desktop/src/app/image/image.component.ts b/desktop/src/app/image/image.component.ts index 5b36ca783..cefd6a385 100644 --- a/desktop/src/app/image/image.component.ts +++ b/desktop/src/app/image/image.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router' import hotkeys from 'hotkeys-js' import { NgxLegacyMoveableComponent, OnDrag, OnResize, OnRotate } from 'ngx-moveable' import { ContextMenu } from 'primeng/contextmenu' -import { DeviceListMenuComponent } from '../../shared/components/device-list-menu/device-list-menu.component' +import { DeviceListMenuComponent } from '../../shared/components/device-list-menu.component' import { HistogramComponent } from '../../shared/components/histogram.component' import { MenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' diff --git a/desktop/src/shared/components/device-chooser.component.ts b/desktop/src/shared/components/device-chooser.component.ts index 315f3190a..740f1fffa 100644 --- a/desktop/src/shared/components/device-chooser.component.ts +++ b/desktop/src/shared/components/device-chooser.component.ts @@ -1,7 +1,7 @@ import { Component, ViewEncapsulation, inject, input, model, output, viewChild } from '@angular/core' import { ApiService } from '../services/api.service' import { Device } from '../types/device.types' -import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from './device-list-menu/device-list-menu.component' +import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from './device-list-menu.component' import { MenuItem } from './menu-item.component' @Component({ diff --git a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts b/desktop/src/shared/components/device-list-menu.component.ts similarity index 51% rename from desktop/src/shared/components/device-list-menu/device-list-menu.component.ts rename to desktop/src/shared/components/device-list-menu.component.ts index 7ec2a2b15..0b24231a4 100644 --- a/desktop/src/shared/components/device-list-menu/device-list-menu.component.ts +++ b/desktop/src/shared/components/device-list-menu.component.ts @@ -1,12 +1,12 @@ -import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject } from '@angular/core' -import { SEPARATOR_MENU_ITEM } from '../../constants' -import { AngularService } from '../../services/angular.service' -import { isGuideHead } from '../../types/camera.types' -import { Device } from '../../types/device.types' -import { deviceComparator } from '../../utils/comparators' -import { Undefinable } from '../../utils/types' -import { DialogMenuComponent } from '../dialog-menu.component' -import { MenuItem, SlideMenuItem } from '../menu-item.component' +import { Component, ViewEncapsulation, effect, inject, input, output, viewChild } from '@angular/core' +import { SEPARATOR_MENU_ITEM } from '../constants' +import { AngularService } from '../services/angular.service' +import { isGuideHead } from '../types/camera.types' +import { Device } from '../types/device.types' +import { deviceComparator } from '../utils/comparators' +import { Undefinable } from '../utils/types' +import { DialogMenuComponent } from './dialog-menu.component' +import { MenuItem, SlideMenuItem } from './menu-item.component' export interface DeviceConnectionCommandEvent { device: Device @@ -15,44 +15,47 @@ export interface DeviceConnectionCommandEvent { @Component({ selector: 'neb-device-list-menu', - templateUrl: 'device-list-menu.component.html', - styleUrls: ['device-list-menu.component.scss'], + template: ` + + `, + styles: ` + neb-device-list-menu { + .p-menuitem-link { + padding: 0.5rem 0.75rem; + min-height: 43px; + } + } + `, encapsulation: ViewEncapsulation.None, }) export class DeviceListMenuComponent { private readonly angularService = inject(AngularService) - @Input() - protected readonly model: SlideMenuItem[] = [] - - @Input() - protected readonly modelAtFirst: boolean = true - - @Input() - protected readonly disableIfDeviceIsNotConnected: boolean = true - - @Input() - protected header?: string + readonly model = input([]) + readonly modelAtFirst = input(true) + readonly disableIfDeviceIsNotConnected = input(true) + readonly header = input() + readonly hasNone = input(false) + readonly toolbarBuilder = input<(device: Device) => MenuItem[]>() + readonly deviceConnect = output() + readonly deviceDisconnect = output() - @Input() - protected readonly hasNone: boolean = false + readonly menu = viewChild.required('menu') - @Input() - protected readonly toolbarBuilder?: (device: Device) => MenuItem[] + protected currentHeader?: string - @Output() - readonly deviceConnect = new EventEmitter() - - @Output() - readonly deviceDisconnect = new EventEmitter() - - @ViewChild('menu') - private readonly menu!: DialogMenuComponent + constructor() { + effect(() => { + this.currentHeader = this.header() + }) + } show(devices: T[], selected?: NoInfer, header?: string) { const model: SlideMenuItem[] = [] - if (header) this.header = header + this.currentHeader = header || this.header() return new Promise>((resolve) => { if (devices.length <= 0) { @@ -62,7 +65,7 @@ export class DeviceListMenuComponent { } const populateWithModel = () => { - for (const item of this.model) { + for (const item of this.model()) { model.push({ ...item, command: (event) => { @@ -73,19 +76,20 @@ export class DeviceListMenuComponent { } } - const subscription = this.menu.visible.subscribe((visible) => { + const subscription = this.menu().visible.subscribe((visible) => { if (!visible) { subscription.unsubscribe() resolve(undefined) } }) - if (this.model.length > 0 && this.modelAtFirst) { + const modelAtFirst = this.modelAtFirst() + if (this.model().length > 0 && modelAtFirst) { populateWithModel() model.push(SEPARATOR_MENU_ITEM) } - if (this.hasNone) { + if (this.hasNone()) { model.push({ icon: 'mdi mdi-close', label: 'None', @@ -98,12 +102,12 @@ export class DeviceListMenuComponent { } for (const device of devices.sort(deviceComparator)) { - const toolbarMenu = this.toolbarBuilder?.(device) ?? [] + const toolbarMenu = this.toolbarBuilder()?.(device) ?? [] model.push({ label: device.name, selected: selected === device, - disabled: this.disableIfDeviceIsNotConnected && !device.connected, + disabled: this.disableIfDeviceIsNotConnected() && !device.connected, slideMenu: [], toolbarMenu: [ ...toolbarMenu, @@ -126,16 +130,16 @@ export class DeviceListMenuComponent { }) } - if (this.model.length > 0 && !this.modelAtFirst) { + if (this.model().length > 0 && !modelAtFirst) { model.push(SEPARATOR_MENU_ITEM) populateWithModel() } - this.menu.show(model) + this.menu().show(model) }) } hide() { - this.menu.hide() + this.menu().hide() } } diff --git a/desktop/src/shared/components/device-list-menu/device-list-menu.component.html b/desktop/src/shared/components/device-list-menu/device-list-menu.component.html deleted file mode 100644 index 2b1bab0aa..000000000 --- a/desktop/src/shared/components/device-list-menu/device-list-menu.component.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/desktop/src/shared/components/device-list-menu/device-list-menu.component.scss b/desktop/src/shared/components/device-list-menu/device-list-menu.component.scss deleted file mode 100644 index ef8a048d3..000000000 --- a/desktop/src/shared/components/device-list-menu/device-list-menu.component.scss +++ /dev/null @@ -1,6 +0,0 @@ -neb-device-list-menu { - .p-menuitem-link { - padding: 0.5rem 0.75rem; - min-height: 43px; - } -} diff --git a/desktop/src/shared/services/device.service.ts b/desktop/src/shared/services/device.service.ts index aecb8e380..5c9939d1f 100644 --- a/desktop/src/shared/services/device.service.ts +++ b/desktop/src/shared/services/device.service.ts @@ -1,5 +1,5 @@ import { inject, Injectable } from '@angular/core' -import { DeviceListMenuComponent } from '../components/device-list-menu/device-list-menu.component' +import { DeviceListMenuComponent } from '../components/device-list-menu.component' import { Device } from '../types/device.types' import { AngularService } from './angular.service' From fde37922035c8b7dcb8b01ac3d191d82b43697f4 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 13:06:39 -0300 Subject: [PATCH 27/30] [desktop]: Make LocationComponent single file --- desktop/src/app/app.module.ts | 2 +- .../src/app/settings/settings.component.html | 2 +- .../src/app/settings/settings.component.ts | 9 +-- .../shared/components/location.component.ts | 75 +++++++++++++++++++ .../components/location/location.dialog.html | 60 --------------- .../components/location/location.dialog.ts | 48 ------------ 6 files changed, 81 insertions(+), 115 deletions(-) create mode 100644 desktop/src/shared/components/location.component.ts delete mode 100644 desktop/src/shared/components/location/location.dialog.html delete mode 100644 desktop/src/shared/components/location/location.dialog.ts diff --git a/desktop/src/app/app.module.ts b/desktop/src/app/app.module.ts index 85d467eb8..bd5cdd25c 100644 --- a/desktop/src/app/app.module.ts +++ b/desktop/src/app/app.module.ts @@ -59,7 +59,7 @@ import { HistogramComponent } from '../shared/components/histogram.component' import { IndicatorComponent } from '../shared/components/indicator.component' import { InputNumberComponent } from '../shared/components/input-number.component' import { InputTextComponent } from '../shared/components/input-text.component' -import { LocationComponent } from '../shared/components/location/location.dialog' +import { LocationComponent } from '../shared/components/location.component' import { MapComponent } from '../shared/components/map.component' import { MenuBarComponent } from '../shared/components/menu-bar.component' import { MenuItemComponent } from '../shared/components/menu-item.component' diff --git a/desktop/src/app/settings/settings.component.html b/desktop/src/app/settings/settings.component.html index c67035250..187bc0892 100644 --- a/desktop/src/app/settings/settings.component.html +++ b/desktop/src/app/settings/settings.component.html @@ -37,7 +37,7 @@
+ (update)="locationChanged()" />
diff --git a/desktop/src/app/settings/settings.component.ts b/desktop/src/app/settings/settings.component.ts index e42f1f94d..a35bba9c4 100644 --- a/desktop/src/app/settings/settings.component.ts +++ b/desktop/src/app/settings/settings.component.ts @@ -137,11 +137,10 @@ export class SettingsComponent implements AfterViewInit, OnDestroy { } } - protected locationChanged(location?: Location) { - if (location) { - this.savePreference() - this.locationChangePublisher.next(location) - } + protected locationChanged(location: Location = this.preference.location) { + this.preference.location = location + this.savePreference() + this.locationChangePublisher.next(location) } protected resetCameraCaptureNamingFormat(type: FrameType) { diff --git a/desktop/src/shared/components/location.component.ts b/desktop/src/shared/components/location.component.ts new file mode 100644 index 000000000..59ed85b7a --- /dev/null +++ b/desktop/src/shared/components/location.component.ts @@ -0,0 +1,75 @@ +import { AfterViewInit, Component, input, output, viewChild, ViewEncapsulation } from '@angular/core' +import type { Location } from '../types/atlas.types' +import { MapComponent } from './map.component' + +@Component({ + selector: 'neb-location', + template: ` + @let mLocation = location(); + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ `, + encapsulation: ViewEncapsulation.None, +}) +export class LocationComponent implements AfterViewInit { + readonly location = input.required() + readonly update = output() + + readonly map = viewChild.required('map') + + ngAfterViewInit() { + this.map().refresh() + } + + protected locationUpdated() { + this.update.emit() + } +} diff --git a/desktop/src/shared/components/location/location.dialog.html b/desktop/src/shared/components/location/location.dialog.html deleted file mode 100644 index 38972432d..000000000 --- a/desktop/src/shared/components/location/location.dialog.html +++ /dev/null @@ -1,60 +0,0 @@ -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-@if (isDialog) { - -} diff --git a/desktop/src/shared/components/location/location.dialog.ts b/desktop/src/shared/components/location/location.dialog.ts deleted file mode 100644 index e73171c4e..000000000 --- a/desktop/src/shared/components/location/location.dialog.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core' -import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog' -import type { Location } from '../../types/atlas.types' -import { DEFAULT_LOCATION } from '../../types/atlas.types' -import { MapComponent } from '../map.component' - -@Component({ - selector: 'neb-location', - templateUrl: 'location.dialog.html', -}) -export class LocationComponent implements AfterViewInit { - private readonly dialogRef = inject(DynamicDialogRef, { optional: true }) - - @ViewChild('map') - private readonly map?: MapComponent - - @Input() - readonly location!: Location - - @Output() - readonly locationChange = new EventEmitter() - - get isDialog() { - return !!this.dialogRef - } - - constructor() { - const config = inject>(DynamicDialogConfig, { optional: true }) - - if (config) { - this.location = config.data ?? structuredClone(DEFAULT_LOCATION) - } - } - - ngAfterViewInit() { - this.map?.refresh() - } - - save() { - this.dialogRef?.close(this.location) - } - - locationChanged() { - if (!this.isDialog) { - this.locationChange.emit(this.location) - } - } -} From f72a34732443558eb5447010c43c44149cb19064 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 13:37:20 -0300 Subject: [PATCH 28/30] [desktop]: Migrate to input/output signal --- .../calculator/formula/formula.component.html | 22 +++-- .../calculator/formula/formula.component.ts | 10 +- .../app/camera/exposure-time.component.html | 15 ++- .../src/app/camera/exposure-time.component.ts | 95 +++++++------------ .../property/indi-property.component.html | 50 +++++----- .../indi/property/indi-property.component.ts | 39 ++++---- 6 files changed, 102 insertions(+), 129 deletions(-) diff --git a/desktop/src/app/calculator/formula/formula.component.html b/desktop/src/app/calculator/formula/formula.component.html index 8f064cfc3..6320fb7e0 100644 --- a/desktop/src/app/calculator/formula/formula.component.html +++ b/desktop/src/app/calculator/formula/formula.component.html @@ -1,11 +1,13 @@ -

{{ formula.description }}

+@let mFormula = formula(); + +

{{ mFormula.description }}

- @for (item of formula.operands; track item.label) { + @for (item of mFormula.operands; track item.label) {
{{ item.prefix }} @@ -26,18 +28,18 @@

=

- {{ formula.result.prefix }} + {{ mFormula.result.prefix }} - {{ formula.result.suffix }} + [value]="mFormula.result.value ?? 0" + [fractionDigits]="mFormula.result.maxFractionDigits ?? 4" /> + {{ mFormula.result.suffix }}
-@if (formula.tip) { +@if (mFormula.tip) {
+ [text]="mFormula.tip" />
} diff --git a/desktop/src/app/calculator/formula/formula.component.ts b/desktop/src/app/calculator/formula/formula.component.ts index 181e86e6d..802281f4c 100644 --- a/desktop/src/app/calculator/formula/formula.component.ts +++ b/desktop/src/app/calculator/formula/formula.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core' +import { Component, input } from '@angular/core' import type { CalculatorFormula } from '../../../shared/types/calculator.types' @Component({ @@ -7,14 +7,14 @@ import type { CalculatorFormula } from '../../../shared/types/calculator.types' styleUrls: ['formula.component.scss'], }) export class FormulaComponent { - @Input({ required: true }) - protected readonly formula!: CalculatorFormula + protected readonly formula = input.required() calculateFormula() { - const result = this.formula.calculate(...this.formula.operands.map((e) => e.value)) + const formula = this.formula() + const result = formula.calculate(...formula.operands.map((e) => e.value)) if (result !== undefined) { - this.formula.result.value = result + formula.result.value = result } } } diff --git a/desktop/src/app/camera/exposure-time.component.html b/desktop/src/app/camera/exposure-time.component.html index b6f95c11a..10dc08676 100644 --- a/desktop/src/app/camera/exposure-time.component.html +++ b/desktop/src/app/camera/exposure-time.component.html @@ -1,23 +1,22 @@
- + [min]="currentMin" + [max]="currentMax" />
diff --git a/desktop/src/app/camera/exposure-time.component.ts b/desktop/src/app/camera/exposure-time.component.ts index e9e704f6b..8f1777e8b 100644 --- a/desktop/src/app/camera/exposure-time.component.ts +++ b/desktop/src/app/camera/exposure-time.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core' +import { AfterViewInit, ChangeDetectionStrategy, Component, OnChanges, SimpleChanges, ViewEncapsulation, input, model, signal } from '@angular/core' import { MenuItem } from '../../shared/components/menu-item.component' import type { ExposureTimeUnit } from '../../shared/types/camera.types' @@ -9,44 +9,15 @@ import type { ExposureTimeUnit } from '../../shared/types/camera.types' changeDetection: ChangeDetectionStrategy.OnPush, }) export class ExposureTimeComponent implements AfterViewInit, OnChanges { - @Input({ required: true }) - protected exposureTime: number = 0 - - @Output() - readonly exposureTimeChange = new EventEmitter() - - @Input() - protected unit: ExposureTimeUnit = 'MICROSECOND' - - @Output() - readonly unitChange = new EventEmitter() - - @Input() - protected readonly min: number = 0 - - @Input() - protected readonly max: number = 600000000 - - @Input() - protected readonly disabled: boolean = false - - @Input() - protected readonly canExposureTime: boolean = true - - @Input() - protected readonly canExposureTimeUnit: boolean = true - - @Input() - protected readonly normalized: boolean = true - - @Input() - protected readonly label?: string - - protected readonly current = { - exposureTime: this.exposureTime, - min: this.min, - max: this.max, - } + readonly exposureTime = model.required() + readonly unit = model('MICROSECOND') + readonly min = input(0) + readonly max = input(600000000) + readonly disabled = input(false) + readonly canExposureTime = input(true) + readonly canExposureTimeUnit = input(true) + readonly normalized = input(true) + readonly label = input() protected readonly model: MenuItem[] = [ { @@ -75,7 +46,11 @@ export class ExposureTimeComponent implements AfterViewInit, OnChanges { }, ] - private exposureTimeInMicroseconds = 0 + protected currentExposureTime = 0 + protected currentMin = 0 + protected currentMax = 0 + + private readonly exposureTimeInMicroseconds = signal(0) ngOnChanges(changes: SimpleChanges) { for (const key in changes) { @@ -88,39 +63,39 @@ export class ExposureTimeComponent implements AfterViewInit, OnChanges { this.exposureTimeUnitChanged(change.currentValue) break case 'exposureTime': - this.exposureTimeChanged(change.currentValue, 'MICROSECOND', this.normalized && this.exposureTimeInMicroseconds !== change.currentValue) + this.exposureTimeChanged(change.currentValue, 'MICROSECOND', this.normalized() && this.exposureTimeInMicroseconds !== change.currentValue) break case 'min': case 'max': this.exposureTimeMinMaxChanged() break case 'normalized': - this.normalize(this.exposureTime) + this.normalize(this.exposureTime()) break } } } ngAfterViewInit() { - this.updateExposureTime(this.current.exposureTime, this.unit, this.unit) + this.updateExposureTime(this.currentExposureTime, this.unit(), this.unit()) } protected exposureTimeUnitChanged(value: ExposureTimeUnit) { - this.updateExposureTime(this.current.exposureTime, value, this.unit, false) + this.updateExposureTime(this.currentExposureTime, value, this.unit(), false) } - protected exposureTimeChanged(value: number, from: ExposureTimeUnit = this.unit, normalize: boolean = false) { - this.updateExposureTime(value, this.unit, from, normalize) + protected exposureTimeChanged(value: number, from: ExposureTimeUnit = this.unit(), normalize: boolean = false) { + this.updateExposureTime(value, this.unit(), from, normalize) } protected exposureTimeMinMaxChanged() { - this.updateExposureTime(this.current.exposureTime, this.unit, this.unit, false) + this.updateExposureTime(this.currentExposureTime, this.unit(), this.unit(), false) } protected exposureTimeUnitWheeled(event: WheelEvent) { if (event.deltaY) { const units: ExposureTimeUnit[] = ['MINUTE', 'SECOND', 'MILLISECOND', 'MICROSECOND'] - const index = units.indexOf(this.unit) + const index = units.indexOf(this.unit()) if (index >= 0) { if (event.deltaY > 0) { @@ -134,17 +109,17 @@ export class ExposureTimeComponent implements AfterViewInit, OnChanges { } } - private updateExposureTime(value: number, unit: ExposureTimeUnit, from: ExposureTimeUnit, normalize: boolean = this.normalized) { + private updateExposureTime(value: number, unit: ExposureTimeUnit, from: ExposureTimeUnit, normalize: boolean = this.normalized()) { const a = ExposureTimeComponent.exposureUnitFactor(from) const b = ExposureTimeComponent.exposureUnitFactor(unit) if (!a || !b) return - this.current.min = Math.max(1, Math.trunc(((this.min || 1) * b) / 60000000)) - this.current.max = Math.max(1, Math.trunc(((this.max || 600000000) * b) / 60000000)) - this.current.exposureTime = Math.max(1, Math.trunc((value * b) / a)) + this.currentMin = Math.max(1, Math.trunc(((this.min() || 1) * b) / 60000000)) + this.currentMax = Math.max(1, Math.trunc(((this.max() || 600000000) * b) / 60000000)) + this.currentExposureTime = Math.max(1, Math.trunc((value * b) / a)) - const exposureTimeInMicroseconds = Math.trunc((this.current.exposureTime * 60000000) / b) + const exposureTimeInMicroseconds = Math.trunc((value * 60000000) / a) if (normalize) { if (this.normalize(exposureTimeInMicroseconds)) { @@ -152,20 +127,18 @@ export class ExposureTimeComponent implements AfterViewInit, OnChanges { } } - if (this.exposureTime !== exposureTimeInMicroseconds) { - this.exposureTime = exposureTimeInMicroseconds - this.exposureTimeInMicroseconds = exposureTimeInMicroseconds - this.exposureTimeChange.emit(exposureTimeInMicroseconds) + if (this.exposureTime() !== exposureTimeInMicroseconds) { + this.exposureTime.set(exposureTimeInMicroseconds) + this.exposureTimeInMicroseconds.set(exposureTimeInMicroseconds) } - if (this.unit !== unit) { - this.unit = unit - this.unitChange.emit(unit) + if (this.unit() !== unit) { + this.unit.set(unit) } } private normalize(exposureTime: number) { - if (!this.normalized) { + if (!this.normalized()) { return false } diff --git a/desktop/src/app/indi/property/indi-property.component.html b/desktop/src/app/indi/property/indi-property.component.html index dcfaa24bf..09cc6209f 100644 --- a/desktop/src/app/indi/property/indi-property.component.html +++ b/desktop/src/app/indi/property/indi-property.component.html @@ -1,15 +1,17 @@ +@let mProperty = property(); +
- - {{ property.label }} + + {{ mProperty.label }}
- @if (property.type === 'SWITCH') { - @if (property.rule === 'ONE_OF_MANY') { + @if (mProperty.type === 'SWITCH') { + @if (mProperty.rule === 'ONE_OF_MANY') {
- @for (item of property.items; track item.name) { + @for (item of mProperty.items; track item.name) { } - @if (property.rule === 'AT_MOST_ONE') { + @if (mProperty.rule === 'AT_MOST_ONE') {
- @for (item of property.items; track item.name) { + @for (item of mProperty.items; track item.name) { }
} - @if (property.rule === 'ANY_OF_MANY') { + @if (mProperty.rule === 'ANY_OF_MANY') {
- @for (item of property.items; track item.name) { + @for (item of mProperty.items; track item.name) { } - } @else if (property.type === 'NUMBER') { + } @else if (mProperty.type === 'NUMBER') {
- @for (item of property.items; track item.name) { + @for (item of mProperty.items; track item.name) {
- @if (property.perm !== 'WO') { + @if (mProperty.perm !== 'WO') {
} - @if (property.perm !== 'RO') { + @if (mProperty.perm !== 'RO') {
- @if (property.perm !== 'RO') { + @if (mProperty.perm !== 'RO') { }
- } @else if (property.type === 'TEXT') { + } @else if (mProperty.type === 'TEXT') {
- @for (item of property.items; track item.name) { + @for (item of mProperty.items; track item.name) {
- @if (property.perm !== 'WO') { + @if (mProperty.perm !== 'WO') {
} - @if (property.perm !== 'RO') { + @if (mProperty.perm !== 'RO') {
- @if (property.perm !== 'RO') { + @if (mProperty.perm !== 'RO') { diff --git a/desktop/src/app/indi/property/indi-property.component.ts b/desktop/src/app/indi/property/indi-property.component.ts index 19ea8e510..2710b65d6 100644 --- a/desktop/src/app/indi/property/indi-property.component.ts +++ b/desktop/src/app/indi/property/indi-property.component.ts @@ -1,4 +1,4 @@ -import { AfterContentInit, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core' +import { Component, ViewEncapsulation, effect, input, output } from '@angular/core' import type { INDIProperty, INDIPropertyItem, INDISendProperty, INDISendPropertyItem } from '../../../shared/types/device.types' @Component({ @@ -7,32 +7,29 @@ import type { INDIProperty, INDIPropertyItem, INDISendProperty, INDISendProperty styleUrls: ['indi-property.component.scss'], encapsulation: ViewEncapsulation.None, }) -export class INDIPropertyComponent implements AfterContentInit { - @Input({ required: true }) - protected property!: INDIProperty +export class INDIPropertyComponent { + readonly property = input.required() + readonly disabled = input(false) + readonly send = output() - @Input() - protected disabled = false - - @Output() - readonly send = new EventEmitter() - - ngAfterContentInit() { - for (const item of this.property.items) { - if (!item.valueToSend) { - item.valueToSend = `${item.value}` + constructor() { + effect(() => { + for (const item of this.property().items) { + if (!item.valueToSend) { + item.valueToSend = `${item.value}` + } } - } + }) } sendSwitch(item: INDIPropertyItem) { const property: INDISendProperty = { - name: this.property.name, + name: this.property().name, type: 'SWITCH', items: [ { name: item.name, - value: this.property.rule === 'ANY_OF_MANY' ? !item.value : true, + value: this.property().rule === 'ANY_OF_MANY' ? !item.value : true, }, ], } @@ -43,12 +40,12 @@ export class INDIPropertyComponent implements AfterContentInit { sendNumber() { const items: INDISendPropertyItem[] = [] - for (const item of this.property.items) { + for (const item of this.property().items) { items.push({ name: item.name, value: item.valueToSend }) } const property: INDISendProperty = { - name: this.property.name, + name: this.property().name, type: 'NUMBER', items, } @@ -59,12 +56,12 @@ export class INDIPropertyComponent implements AfterContentInit { sendText() { const items: INDISendPropertyItem[] = [] - for (const item of this.property.items) { + for (const item of this.property().items) { items.push({ name: item.name, value: item.valueToSend }) } const property: INDISendProperty = { - name: this.property.name, + name: this.property().name, type: 'TEXT', items, } From 692dbb4d56061b2f7c9ad9b3c8fb39cabc2572fd Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 13:54:19 -0300 Subject: [PATCH 29/30] [desktop]: Migrate to viewChild signal --- .../src/app/alignment/alignment.component.ts | 11 ++- desktop/src/app/atlas/atlas.component.ts | 27 +++---- .../src/app/autofocus/autofocus.component.ts | 15 ++-- .../calibration/calibration.component.html | 2 + .../app/calibration/calibration.component.ts | 7 +- desktop/src/app/camera/camera.component.ts | 9 +-- .../app/flat-wizard/flat-wizard.component.ts | 10 +-- desktop/src/app/guider/guider.component.ts | 8 +- desktop/src/app/home/home.component.ts | 9 +-- desktop/src/app/image/image.component.ts | 75 ++++++++----------- desktop/src/app/indi/indi.component.html | 2 +- desktop/src/app/indi/indi.component.ts | 7 +- .../src/app/sequencer/sequencer.component.ts | 11 ++- 13 files changed, 82 insertions(+), 111 deletions(-) diff --git a/desktop/src/app/alignment/alignment.component.ts b/desktop/src/app/alignment/alignment.component.ts index 7b7f957a9..296368e27 100644 --- a/desktop/src/app/alignment/alignment.component.ts +++ b/desktop/src/app/alignment/alignment.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' +import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, inject, viewChild } from '@angular/core' import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { ApiService } from '../../shared/services/api.service' import { BrowserWindowService } from '../../shared/services/browser-window.service' @@ -43,8 +43,7 @@ export class AlignmentComponent implements AfterViewInit, OnDestroy, Tickable { protected darvRequest = this.preference.darvRequest protected readonly darvResult = structuredClone(DEFAULT_DARV_RESULT) - @ViewChild('cameraExposure') - private readonly cameraExposure!: CameraExposureComponent + private readonly cameraExposure = viewChild.required('cameraExposure') get pausingOrPaused() { return this.status === 'PAUSING' || this.status === 'PAUSED' @@ -170,7 +169,7 @@ export class AlignmentComponent implements AfterViewInit, OnDestroy, Tickable { this.tppaResult.altitudeErrorDirection = event.altitudeErrorDirection this.tppaResult.totalError = event.totalError } else if (event.state === 'FINISHED') { - this.cameraExposure.reset() + this.cameraExposure().reset() } else if (event.state === 'SOLVED' || event.state === 'SLEWED') { this.tppaResult.failed = false this.tppaResult.rightAscension = event.rightAscension @@ -180,7 +179,7 @@ export class AlignmentComponent implements AfterViewInit, OnDestroy, Tickable { } if (event.capture.state !== 'CAPTURE_FINISHED') { - this.cameraExposure.handleCameraCaptureEvent(event.capture, true) + this.cameraExposure().handleCameraCaptureEvent(event.capture, true) } }) } @@ -190,7 +189,7 @@ export class AlignmentComponent implements AfterViewInit, OnDestroy, Tickable { if (event.camera.id === this.camera?.id) { ngZone.run(() => { this.status = event.state - this.running = this.cameraExposure.handleCameraCaptureEvent(event.capture) + this.running = this.cameraExposure().handleCameraCaptureEvent(event.capture) if (event.state === 'FORWARD' || event.state === 'BACKWARD') { this.darvResult.direction = event.direction diff --git a/desktop/src/app/atlas/atlas.component.ts b/desktop/src/app/atlas/atlas.component.ts index 410c8ad2f..34cf981da 100644 --- a/desktop/src/app/atlas/atlas.component.ts +++ b/desktop/src/app/atlas/atlas.component.ts @@ -1,4 +1,4 @@ -import { AfterContentInit, AfterViewInit, Component, HostListener, NgZone, OnDestroy, OnInit, ViewChild, ViewEncapsulation, inject } from '@angular/core' +import { AfterContentInit, AfterViewInit, Component, HostListener, NgZone, OnDestroy, OnInit, ViewEncapsulation, inject, viewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { Chart, ChartData, ChartOptions } from 'chart.js' import zoomPlugin from 'chartjs-plugin-zoom' @@ -346,17 +346,10 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, }, ] - @ViewChild('deviceMenu') - private readonly deviceMenu!: DeviceListMenuComponent - - @ViewChild('dateTimeAndLocationPanel') - private readonly dateTimeAndLocationPanel!: OverlayPanel - - @ViewChild('favoritesPanel') - private readonly favoritesPanel!: OverlayPanel - - @ViewChild('chart') - private readonly chart!: UIChart + private readonly deviceMenu = viewChild.required('deviceMenu') + private readonly dateTimeAndLocationPanel = viewChild.required('dateTimeAndLocationPanel') + private readonly favoritesPanel = viewChild.required('favoritesPanel') + private readonly chart = viewChild.required('chart') get body() { switch (this.tab) { @@ -409,7 +402,7 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, icon: 'mdi mdi-bookmark', tooltip: 'Favorites', command: (e) => { - this.favoritesPanel.toggle(e.originalEvent) + this.favoritesPanel().toggle(e.originalEvent) }, }) @@ -417,7 +410,7 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, icon: 'mdi mdi-calendar', tooltip: 'Date Time and Location', command: (e) => { - this.dateTimeAndLocationPanel.toggle(e.originalEvent) + this.dateTimeAndLocationPanel().toggle(e.originalEvent) }, }) @@ -858,7 +851,7 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, [24.0, 90], ] - this.chart.refresh() + this.chart().refresh() } private async refreshChart(force: boolean = false) { @@ -908,7 +901,7 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, } } finally { this.updateAltitudeChart() - this.chart.refresh() + this.chart().refresh() } } @@ -978,6 +971,6 @@ export class AtlasComponent implements OnInit, AfterContentInit, AfterViewInit, private async executeMount(action: (mount: Mount) => void | Promise, showConfirmation: boolean = true) { const mounts = await this.api.mounts() - return this.deviceService.executeAction(this.deviceMenu, mounts, action, showConfirmation) + return this.deviceService.executeAction(this.deviceMenu(), mounts, action, showConfirmation) } } diff --git a/desktop/src/app/autofocus/autofocus.component.ts b/desktop/src/app/autofocus/autofocus.component.ts index c456b62b4..8b4878f0d 100644 --- a/desktop/src/app/autofocus/autofocus.component.ts +++ b/desktop/src/app/autofocus/autofocus.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' +import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, inject, viewChild } from '@angular/core' import { ChartData, ChartOptions } from 'chart.js' import { Point } from 'electron' import { UIChart } from 'primeng/chart' @@ -205,11 +205,8 @@ export class AutoFocusComponent implements AfterViewInit, OnDestroy, Tickable { ], } - @ViewChild('cameraExposure') - private readonly cameraExposure!: CameraExposureComponent - - @ViewChild('chart') - private readonly chart!: UIChart + private readonly cameraExposure = viewChild.required('cameraExposure') + private readonly chart = viewChild.required('chart') private get trendLineLeftDataset() { return this.chartData.datasets[0] @@ -314,7 +311,7 @@ export class AutoFocusComponent implements AfterViewInit, OnDestroy, Tickable { this.starHFD = event.starHFD if (event.capture) { - this.cameraExposure.handleCameraCaptureEvent(event.capture, true) + this.cameraExposure().handleCameraCaptureEvent(event.capture, true) } if (state === 'CURVE_FITTED') { @@ -440,7 +437,7 @@ export class AutoFocusComponent implements AfterViewInit, OnDestroy, Tickable { zoom.limits!['x']!.max = scales['x']!.max zoom.limits!['y']!.max = scales['y']!.max - this.chart.refresh() + this.chart().refresh() } private clearChart() { @@ -450,7 +447,7 @@ export class AutoFocusComponent implements AfterViewInit, OnDestroy, Tickable { dataset.data = [] } - this.chart.refresh() + this.chart().refresh() } private loadPreference() { diff --git a/desktop/src/app/calibration/calibration.component.html b/desktop/src/app/calibration/calibration.component.html index 75995c682..c65a706bb 100644 --- a/desktop/src/app/calibration/calibration.component.html +++ b/desktop/src/app/calibration/calibration.component.html @@ -10,10 +10,12 @@
{{ this.frames.get(key)?.length ?? 0 }} frames diff --git a/desktop/src/app/calibration/calibration.component.ts b/desktop/src/app/calibration/calibration.component.ts index d21af0abb..786850f51 100644 --- a/desktop/src/app/calibration/calibration.component.ts +++ b/desktop/src/app/calibration/calibration.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, HostListener, OnDestroy, QueryList, ViewChildren, ViewEncapsulation, inject } from '@angular/core' +import { AfterViewInit, Component, HostListener, OnDestroy, ViewEncapsulation, inject, viewChildren } from '@angular/core' import { Listbox } from 'primeng/listbox' import { MenuItem } from '../../shared/components/menu-item.component' import { SEPARATOR_MENU_ITEM } from '../../shared/constants' @@ -135,8 +135,7 @@ export class CalibrationComponent implements AfterViewInit, OnDestroy { }, ] - @ViewChildren('frameListBox') - private readonly frameListBoxes!: QueryList + private readonly frameListBoxes = viewChildren('frameListBox') get groups() { return Array.from(this.frames.keys()).sort(textComparator) @@ -403,7 +402,7 @@ export class CalibrationComponent implements AfterViewInit, OnDestroy { } private markFrameListBoxesForCheck() { - for (const box of this.frameListBoxes) { + for (const box of this.frameListBoxes()) { box.cd.markForCheck() } } diff --git a/desktop/src/app/camera/camera.component.ts b/desktop/src/app/camera/camera.component.ts index f2c81ee27..790e6aa63 100644 --- a/desktop/src/app/camera/camera.component.ts +++ b/desktop/src/app/camera/camera.component.ts @@ -1,4 +1,4 @@ -import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, ViewChild } from '@angular/core' +import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, viewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { MenuItemCommandEvent, SlideMenuItem } from '../../shared/components/menu-item.component' @@ -123,11 +123,10 @@ export class CameraComponent implements AfterContentInit, OnDestroy, Tickable { format: this.request.namingFormat, } - @ViewChild('cameraExposure') - private readonly cameraExposure?: CameraExposureComponent + private readonly cameraExposure = viewChild('cameraExposure') get status() { - return this.cameraExposure?.currentState ?? 'IDLE' + return this.cameraExposure()?.currentState ?? 'IDLE' } get pausingOrPaused() { @@ -219,7 +218,7 @@ export class CameraComponent implements AfterContentInit, OnDestroy, Tickable { this.electronService.on('CAMERA.CAPTURE_ELAPSED', (event) => { if (event.camera.id === this.camera.id) { ngZone.run(() => { - this.running = this.cameraExposure?.handleCameraCaptureEvent(event) ?? false + this.running = this.cameraExposure()?.handleCameraCaptureEvent(event) ?? false }) } }) diff --git a/desktop/src/app/flat-wizard/flat-wizard.component.ts b/desktop/src/app/flat-wizard/flat-wizard.component.ts index e6c1a6cff..f4e20af63 100644 --- a/desktop/src/app/flat-wizard/flat-wizard.component.ts +++ b/desktop/src/app/flat-wizard/flat-wizard.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' +import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, inject, viewChild } from '@angular/core' import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { AngularService } from '../../shared/services/angular.service' import { ApiService } from '../../shared/services/api.service' @@ -34,11 +34,9 @@ export class FlatWizardComponent implements AfterViewInit, OnDestroy, Tickable { protected request = this.preference.request protected filters: Filter[] = [] - protected running = false - @ViewChild('cameraExposure') - private readonly cameraExposure!: CameraExposureComponent + private readonly cameraExposure = viewChild.required('cameraExposure') get meanTargetMin() { return Math.floor(this.request.meanTarget - (this.request.meanTolerance * this.request.meanTarget) / 100) @@ -59,10 +57,10 @@ export class FlatWizardComponent implements AfterViewInit, OnDestroy, Tickable { ngZone.run(() => { if (event.state === 'EXPOSURING' && event.capture && event.camera.id === this.camera?.id) { this.running = true - this.cameraExposure.handleCameraCaptureEvent(event.capture, true) + this.cameraExposure().handleCameraCaptureEvent(event.capture, true) } else { this.running = false - this.cameraExposure.reset() + this.cameraExposure().reset() if (event.state === 'CAPTURED') { this.angularService.message('Flat frame captured') diff --git a/desktop/src/app/guider/guider.component.ts b/desktop/src/app/guider/guider.component.ts index 5fac7586c..d23ee8352 100644 --- a/desktop/src/app/guider/guider.component.ts +++ b/desktop/src/app/guider/guider.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, OnInit, ViewChild, inject } from '@angular/core' +import { AfterViewInit, Component, HostListener, NgZone, OnDestroy, OnInit, inject, viewChild } from '@angular/core' import { Chart, ChartData, ChartOptions } from 'chart.js' import zoomPlugin from 'chartjs-plugin-zoom' import { UIChart } from 'primeng/chart' @@ -26,9 +26,7 @@ export class GuiderComponent implements OnInit, AfterViewInit, OnDestroy, Tickab protected readonly chartInfo = structuredClone(DEFAULT_GUIDER_CHART_INFO) private readonly guideHistory: GuiderHistoryStep[] = [] - - @ViewChild('chart') - private readonly chart!: UIChart + private readonly chart = viewChild.required('chart') get stopped() { return this.guider.state === 'STOPPED' @@ -351,7 +349,7 @@ export class GuiderComponent implements OnInit, AfterViewInit, OnDestroy, Tickab this.chartData.datasets[2].data = this.guideHistory.map((e) => (e.guideStep?.raDuration ?? 0) / durationScale(e.guideStep?.raDirection)) this.chartData.datasets[3].data = this.guideHistory.map((e) => (e.guideStep?.decDuration ?? 0) / durationScale(e.guideStep?.decDirection)) - this.chart.refresh() + this.chart().refresh() } protected async guideOutputChanged() { diff --git a/desktop/src/app/home/home.component.ts b/desktop/src/app/home/home.component.ts index f75082c0b..cde50ffd6 100644 --- a/desktop/src/app/home/home.component.ts +++ b/desktop/src/app/home/home.component.ts @@ -1,4 +1,4 @@ -import { AfterContentInit, Component, inject, NgZone, ViewChild, ViewEncapsulation } from '@angular/core' +import { AfterContentInit, Component, inject, NgZone, viewChild, ViewEncapsulation } from '@angular/core' import packageJson from '../../../package.json' with { type: 'json' } import { DeviceChooserComponent } from '../../shared/components/device-chooser.component' import { DeviceConnectionCommandEvent, DeviceListMenuComponent } from '../../shared/components/device-list-menu.component' @@ -81,8 +81,7 @@ export class HomeComponent implements AfterContentInit { } } - @ViewChild('deviceMenu') - private readonly deviceMenu!: DeviceListMenuComponent + private readonly deviceMenu = viewChild.required('deviceMenu') get connected() { return !!this.connection && this.connection.connected @@ -514,7 +513,7 @@ export class HomeComponent implements AfterContentInit { if (devices.length === 0) return - const device = await this.deviceMenu.show(devices, undefined, type) + const device = await this.deviceMenu().show(devices, undefined, type) if (device && device !== 'NONE') { await this.openDeviceWindow(device) @@ -574,7 +573,7 @@ export class HomeComponent implements AfterContentInit { await this.browserWindowService.openAlignment({ bringToFront: true }) break case 'SEQUENCER': { - const device = await this.deviceMenu.show(this.cameras, undefined, 'CAMERA') + const device = await this.deviceMenu().show(this.cameras, undefined, 'CAMERA') if (device && device !== 'NONE') { await this.browserWindowService.openSequencer(device, { bringToFront: true }) diff --git a/desktop/src/app/image/image.component.ts b/desktop/src/app/image/image.component.ts index cefd6a385..c1ccbb7cb 100644 --- a/desktop/src/app/image/image.component.ts +++ b/desktop/src/app/image/image.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ElementRef, HostListener, NgZone, OnDestroy, ViewChild, inject } from '@angular/core' +import { AfterViewInit, Component, ElementRef, HostListener, NgZone, OnDestroy, inject, viewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' import hotkeys from 'hotkeys-js' import { NgxLegacyMoveableComponent, OnDrag, OnResize, OnRotate } from 'ngx-moveable' @@ -372,26 +372,13 @@ export class ImageComponent implements AfterViewInit, OnDestroy { ], } - @ViewChild('image') - private readonly image!: ElementRef - - @ViewChild('roi') - private readonly roi!: ElementRef - - @ViewChild('menu') - private readonly menu!: ContextMenu - - @ViewChild('deviceMenu') - private readonly deviceMenu!: DeviceListMenuComponent - - @ViewChild('histogram') - private readonly histogram?: HistogramComponent - - @ViewChild('detectedStarCanvas') - private readonly detectedStarCanvas!: ElementRef - - @ViewChild('moveable') - private readonly moveable!: NgxLegacyMoveableComponent + private readonly image = viewChild.required>('image') + private readonly roi = viewChild.required>('roi') + private readonly menu = viewChild.required('menu') + private readonly deviceMenu = viewChild.required('deviceMenu') + private readonly histogram = viewChild('histogram') + private readonly detectedStarCanvas = viewChild.required>('detectedStarCanvas') + private readonly moveable = viewChild.required('moveable') get isMouseCoordinateVisible() { return this.mouseCoordinate.show && !!this.mouseCoordinate.interpolator && !this.transformation.mirrorHorizontal && !this.transformation.mirrorVertical @@ -651,8 +638,9 @@ export class ImageComponent implements AfterViewInit, OnDestroy { } this.calibrationMenuItem.items = menu - this.menu.model = this.contextMenuModel - this.menu.cd.markForCheck() + const menuValue = this.menu() + menuValue.model = this.contextMenuModel + menuValue.cd.markForCheck() if (reloadImage) { await this.loadImage() @@ -686,7 +674,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { const { target, transform } = event target.style.transform = transform - const rect = this.moveable.getRect() + const rect = this.moveable().getRect() this.imageROI.area.x = Math.trunc(rect.left) this.imageROI.area.y = Math.trunc(rect.top) } @@ -695,7 +683,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { const { target, width, height, transform } = event target.style.transform = transform - const rect = this.moveable.getRect() + const rect = this.moveable().getRect() target.style.width = `${width}px` this.imageROI.area.x = Math.trunc(rect.left) @@ -766,7 +754,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { Object.assign(this.solver.solved, DEFAULT_IMAGE_SOLVED) - this.histogram?.update([]) + this.histogram()?.update([]) } protected async computeStatistics(force: boolean = false) { @@ -777,11 +765,12 @@ export class ImageComponent implements AfterViewInit, OnDestroy { const statistics = await this.api.imageStatistics(path, transformation, this.statistics.channel, this.imageData.camera) this.statistics.statistics = statistics - if (this.histogram) { - this.histogram.update(statistics.histogram) + const histogram = this.histogram() + if (histogram) { + histogram.update(statistics.histogram) } else { setTimeout(() => { - this.histogram?.update(statistics.histogram) + this.histogram()?.update(statistics.histogram) }, 1000) } } @@ -850,9 +839,9 @@ export class ImageComponent implements AfterViewInit, OnDestroy { protected drawDetectedStar(star: DetectedStar) { Object.assign(this.starDetector.selected, star) - const canvas = this.detectedStarCanvas.nativeElement + const canvas = this.detectedStarCanvas().nativeElement const ctx = canvas.getContext('2d') - ctx?.drawImage(this.image.nativeElement, star.x - 8, star.y - 8, 16, 16, 0, 0, canvas.width, canvas.height) + ctx?.drawImage(this.image().nativeElement, star.x - 8, star.y - 8, 16, 16, 0, 0, canvas.width, canvas.height) } protected async loadImage() { @@ -896,7 +885,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { } private async loadImageFromPath(path: string) { - const image = this.image.nativeElement + const image = this.image().nativeElement const transformation = this.makeImageTransformation() const { info, blob } = await this.api.openImage(path, transformation, this.imageData.camera) @@ -958,7 +947,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { this.mouseMountCoordinate.y = event.offsetY if (contextMenu) { - this.menu.show(event) + this.menu().show(event) } } @@ -967,7 +956,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { } private imageMouseMovedWithCoordinates(x: number, y: number) { - if (!this.menu.visible() && this.mouseCoordinate.interpolator) { + if (!this.menu().visible() && this.mouseCoordinate.interpolator) { Object.assign(this.mouseCoordinate, this.mouseCoordinate.interpolator.interpolateAsText(x, y, true, true, false)) this.mouseCoordinate.x = x this.mouseCoordinate.y = y @@ -1143,7 +1132,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { private zoomIn() { if (this.zoom.panZoom) { const { innerWidth, innerHeight } = window - const { offsetTop, offsetLeft } = this.image.nativeElement.parentElement!.parentElement! + const { offsetTop, offsetLeft } = this.image().nativeElement.parentElement!.parentElement! this.zoom.panZoom.zoomIn({ clientX: innerWidth / 2 + offsetLeft / 2, clientY: innerHeight / 2 + offsetTop / 2 }) } } @@ -1151,7 +1140,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { private zoomOut() { if (this.zoom.panZoom) { const { innerWidth, innerHeight } = window - const { offsetTop, offsetLeft } = this.image.nativeElement.parentElement!.parentElement! + const { offsetTop, offsetLeft } = this.image().nativeElement.parentElement!.parentElement! this.zoom.panZoom.zoomOut({ clientX: innerWidth / 2 + offsetLeft / 2, clientY: innerHeight / 2 + offsetTop / 2 }) } } @@ -1165,12 +1154,12 @@ export class ImageComponent implements AfterViewInit, OnDestroy { private resetZoom(fitToScreen: boolean = false, center: boolean = true) { if (this.zoom.panZoom) { if (fitToScreen) { - const { width: iw, height: ih } = this.image.nativeElement + const { width: iw, height: ih } = this.image().nativeElement const angle = this.rotation.transformation.angle * (Math.PI / 180.0) const nw = Math.abs(iw * Math.cos(angle)) + Math.abs(ih * Math.sin(angle)) const nh = Math.abs(iw * Math.sin(angle)) + Math.abs(ih * Math.cos(angle)) - const { clientWidth: cw, clientHeight: ch } = this.image.nativeElement.parentElement!.parentElement! - const { offsetTop } = this.image.nativeElement.parentElement!.parentElement! + const { clientWidth: cw, clientHeight: ch } = this.image().nativeElement.parentElement!.parentElement! + const { offsetTop } = this.image().nativeElement.parentElement!.parentElement! const factor = Math.min(cw / nw, (ch - offsetTop) / nh) this.zoom.panZoom.zoom(factor) } else { @@ -1303,7 +1292,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { } protected imageLoaded() { - const image = this.image.nativeElement + const image = this.image().nativeElement const wrapper = image.parentElement const owner = wrapper?.parentElement @@ -1323,7 +1312,7 @@ export class ImageComponent implements AfterViewInit, OnDestroy { if (e.shiftKey) { this.rotateWithWheel(e) } else { - if (e.target === owner || e.target === wrapper || e.target === image || e.target === this.roi.nativeElement || (e.target as HTMLElement).tagName === 'circle') { + if (e.target === owner || e.target === wrapper || e.target === image || e.target === this.roi().nativeElement || (e.target as HTMLElement).tagName === 'circle') { panZoom.zoomWithWheel(e) } } @@ -1488,11 +1477,11 @@ export class ImageComponent implements AfterViewInit, OnDestroy { private async executeCamera(action: (camera: Camera) => void | Promise, showConfirmation: boolean = true) { const cameras = await this.api.cameras() - return this.deviceService.executeAction(this.deviceMenu, cameras, action, showConfirmation) + return this.deviceService.executeAction(this.deviceMenu(), cameras, action, showConfirmation) } private async executeMount(action: (mount: Mount) => void | Promise, showConfirmation: boolean = true) { const mounts = await this.api.mounts() - return this.deviceService.executeAction(this.deviceMenu, mounts, action, showConfirmation) + return this.deviceService.executeAction(this.deviceMenu(), mounts, action, showConfirmation) } } diff --git a/desktop/src/app/indi/indi.component.html b/desktop/src/app/indi/indi.component.html index 12f2207bb..608bc962b 100644 --- a/desktop/src/app/indi/indi.component.html +++ b/desktop/src/app/indi/indi.component.html @@ -37,7 +37,7 @@ @if (showLog) {
('messageBox') constructor() { const app = inject(AppComponent) @@ -66,7 +65,7 @@ export class INDIComponent implements AfterViewInit, OnDestroy { ngZone.run(() => { if (event.message) { this.messages.splice(0, 0, event.message) - this.messageBox.cd.markForCheck() + this.messageBox().cd.markForCheck() } }) } diff --git a/desktop/src/app/sequencer/sequencer.component.ts b/desktop/src/app/sequencer/sequencer.component.ts index 7c00887fa..0f7747c62 100644 --- a/desktop/src/app/sequencer/sequencer.component.ts +++ b/desktop/src/app/sequencer/sequencer.component.ts @@ -1,5 +1,5 @@ import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop' -import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core' +import { AfterContentInit, Component, HostListener, inject, NgZone, OnDestroy, viewChildren, ViewEncapsulation } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { CameraExposureComponent } from '../../shared/components/camera-exposure.component' import { DialogMenuComponent } from '../../shared/components/dialog-menu.component' @@ -167,8 +167,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable }, } - @ViewChildren('cameraExposure') - private readonly cameraExposures!: QueryList + private readonly cameraExposures = viewChildren('cameraExposure') get canStart() { return !!this.plan.camera?.connected && !!this.plan.sequences.find((e) => e.enabled) @@ -274,7 +273,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable if (captureEvent) { const index = event.id - 1 - this.cameraExposures.get(index)?.handleCameraCaptureEvent(captureEvent) + this.cameraExposures().at(index)?.handleCameraCaptureEvent(captureEvent) } }) }) @@ -649,8 +648,8 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable protected async start() { if (this.plan.camera) { - for (let i = 0; i < this.cameraExposures.length; i++) { - this.cameraExposures.get(i)?.reset() + for (let i = 0; i < this.cameraExposures().length; i++) { + this.cameraExposures().at(i)?.reset() } // FOCUS OFFSET From 087b336c9f494ad9c80fcc02272e68029370e1b0 Mon Sep 17 00:00:00 2001 From: tiagohm Date: Sun, 8 Dec 2024 13:57:52 -0300 Subject: [PATCH 30/30] [desktop]: Fix property binding --- desktop/src/app/settings/settings.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/src/app/settings/settings.component.html b/desktop/src/app/settings/settings.component.html index 187bc0892..0e0b8b5a9 100644 --- a/desktop/src/app/settings/settings.component.html +++ b/desktop/src/app/settings/settings.component.html @@ -36,7 +36,7 @@