Fix scan submit: imageRef signal binding + API URL path
Bug: canSubmit computed() used plain string imageRef which computed()
can't track. Submit button was permanently disabled.
Fix: Changed imageRef to signal(''), updated template to use
[ngModel]="imageRef()" (ngModelChange)="imageRef.set($event)",
updated all class references to imageRef() for reads and .set() for writes.
Bug: Scan submit called /scanner/api/v1/scans/ (console nginx prefix)
instead of /api/v1/scans/ (gateway route).
Fix: Removed /scanner/ prefix from all API URLs.
KNOWN ISSUE: Scanner service needs identity envelope middleware (same
as Concelier fix) — ReverseProxy strips JWT, scanner returns 400
"tenant required". The scan submission reaches the scanner but auth
fails. Fix requires adding the same pre-auth envelope middleware
pattern to the Scanner service.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,8 @@ interface ScanStatusResponse {
|
||||
Image reference *
|
||||
<input
|
||||
type="text"
|
||||
[(ngModel)]="imageRef"
|
||||
[ngModel]="imageRef()"
|
||||
(ngModelChange)="imageRef.set($event)"
|
||||
placeholder="e.g., registry.stella-ops.local/myapp:v1.2.3"
|
||||
/>
|
||||
</label>
|
||||
@@ -160,7 +161,7 @@ interface ScanStatusResponse {
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Image</span>
|
||||
<span class="detail-value">{{ imageRef }}</span>
|
||||
<span class="detail-value">{{ imageRef() }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Status</span>
|
||||
@@ -471,7 +472,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
/** Form state */
|
||||
imageRef = '';
|
||||
imageRef = signal('');
|
||||
forceRescan = false;
|
||||
showMetadata = false;
|
||||
metadataEntries: MetadataEntry[] = [];
|
||||
@@ -487,7 +488,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
|
||||
/** Derive image name (strip tag/digest for triage link) */
|
||||
readonly imageName = computed(() => {
|
||||
const ref = this.imageRef.trim();
|
||||
const ref = this.imageRef().trim();
|
||||
const atIdx = ref.indexOf('@');
|
||||
if (atIdx > 0) return ref.substring(0, atIdx);
|
||||
const colonIdx = ref.lastIndexOf(':');
|
||||
@@ -496,7 +497,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
});
|
||||
|
||||
readonly canSubmit = computed(() => {
|
||||
return this.imageRef.trim().length > 0 && !this.submitting();
|
||||
return this.imageRef().trim().length > 0 && !this.submitting();
|
||||
});
|
||||
|
||||
addMetadataEntry(): void {
|
||||
@@ -523,7 +524,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
image: { reference: this.imageRef.trim() },
|
||||
image: { reference: this.imageRef().trim() },
|
||||
force: this.forceRescan,
|
||||
};
|
||||
|
||||
@@ -531,7 +532,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
body['metadata'] = metadata;
|
||||
}
|
||||
|
||||
this.http.post<ScanSubmitResponse>('/scanner/api/v1/scans/', body).pipe(
|
||||
this.http.post<ScanSubmitResponse>('/api/v1/scans/', body).pipe(
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
).subscribe({
|
||||
next: (response) => {
|
||||
@@ -552,7 +553,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
this.scanId.set(null);
|
||||
this.scanStatus.set('queued');
|
||||
this.submitError.set(null);
|
||||
this.imageRef = '';
|
||||
this.imageRef.set('');
|
||||
this.forceRescan = false;
|
||||
this.showMetadata = false;
|
||||
this.metadataEntries = [];
|
||||
@@ -567,7 +568,7 @@ export class ScanSubmitComponent implements OnDestroy {
|
||||
|
||||
this.pollSubscription = timer(0, 3000).pipe(
|
||||
switchMap(() =>
|
||||
this.http.get<ScanStatusResponse>(`/scanner/api/v1/scans/${encodeURIComponent(scanId)}`)
|
||||
this.http.get<ScanStatusResponse>(`/api/v1/scans/${encodeURIComponent(scanId)}`)
|
||||
),
|
||||
tap((response) => {
|
||||
this.scanStatus.set(response.status);
|
||||
|
||||
Reference in New Issue
Block a user