소스 검색

improved vector search dialog

Dr-Swopt 5 일 전
부모
커밋
72e0977775

+ 47 - 45
src/app/components/ffb-vector-search-dialog/ffb-vector-search-dialog.component.css

@@ -1,79 +1,81 @@
 .dialog-content {
     display: flex;
     flex-direction: column;
-    gap: 24px;
-    /* more space between rows */
-    width: 100%;
-    max-width: 1140px;
+    height: 100%;
+    max-height: 80vh;
+    padding: 0;
+}
+
+h2 {
+    margin: 0;
     padding: 16px 24px;
-    /* padding inside the dialog */
 }
 
-.search-row {
+.search-row-with-close {
     display: flex;
-    flex-wrap: wrap;
-    align-items: center;
+    justify-content: space-between;
+    align-items: flex-start;
+    padding: 0 24px;
     gap: 16px;
-    /* space between items */
-}
-
-.search-row mat-form-field {
-    flex: 1 1 auto;
-    min-width: 200px;
-    /* ensures small screens are okay */
+    margin-bottom: 8px;
 }
 
-.search-row-with-close {
+.search-row {
     display: flex;
-    align-items: flex-start;
-    /* align search row and close button */
     gap: 16px;
-    /* space between search and close */
+    align-items: center;
     flex-wrap: wrap;
-    /* wrap on smaller screens */
-    margin-bottom: 16px;
+    flex: 1;
+}
+
+mat-form-field {
+    flex: 1;
+    min-width: 200px;
+    /* Ensure input doesn't shrink too much */
 }
 
 .top-k-field {
-    width: 100px;
+    flex: 0 0 100px;
+    /* Fixed width for K input */
+    min-width: 80px;
 }
 
 .search-button {
     display: flex;
     align-items: center;
-    gap: 12px;
-    /* more spacing between search button and spinner */
-    margin-bottom: 30px;
+    gap: 8px;
+    height: 56px;
+    /* Match form field height essentially */
 }
 
 .results-table {
+    flex: 1;
+    overflow: auto;
     width: 100%;
-    margin-top: 16px;
-    border-collapse: separate;
-    border-spacing: 0 4px;
-    /* subtle row spacing */
 }
 
-.results-table th {
-    background-color: #f5f5f5;
-    text-align: left;
-    padding: 10px 12px;
-}
-
-.results-table td {
-    padding: 10px 12px;
-    background-color: #fff;
-    border-bottom: 1px solid #e0e0e0;
-}
 
 .no-results {
     text-align: center;
-    color: rgba(0, 0, 0, 0.6);
+    color: #666;
+    margin-top: 32px;
     font-style: italic;
-    margin-top: 16px;
 }
 
-mat-dialog-actions {
-    margin-top: 24px;
-    gap: 12px;
+/* Spinner adjustment */
+mat-progress-spinner {
+    margin-left: 8px;
+}
+
+mat-table {
+    width: 100%;
+}
+
+.clickable-row {
+    cursor: pointer;
+    transition: background-color 0.2s;
+}
+
+.clickable-row:hover {
+    background-color: whitesmoke;
 }

+ 1 - 1
src/app/components/ffb-vector-search-dialog/ffb-vector-search-dialog.component.html

@@ -61,7 +61,7 @@
     </ng-container>
 
     <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+    <tr mat-row *matRowDef="let row; columns: displayedColumns;" class="clickable-row" (click)="openDetails(row)"></tr>
   </table>
 
   <p class="no-results" *ngIf="!loading && results.length === 0 && queryControl.value">

+ 28 - 3
src/app/components/ffb-vector-search-dialog/ffb-vector-search-dialog.component.ts

@@ -1,5 +1,5 @@
 import { Component, Inject, inject } from '@angular/core';
-import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
 import { HttpClient } from '@angular/common/http';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
@@ -12,6 +12,8 @@ import { webConfig } from '../../config';
 import { MatIconModule } from '@angular/material/icon';
 import { FFBProduction } from '../../ffb/ffb-production.interface';
 
+import { CreateFfbProductionDialogComponent } from '../../components/ffb-production-dialog/create-ffb-production-dialog.component';
+
 @Component({
   selector: 'app-ffb-vector-search-dialog',
   templateUrl: './ffb-vector-search-dialog.component.html',
@@ -25,11 +27,13 @@ import { FFBProduction } from '../../ffb/ffb-production.interface';
     MatButtonModule,
     MatProgressSpinnerModule,
     MatTableModule,
-    MatIconModule
+    MatIconModule,
+    MatDialogModule
   ],
 })
 export class FfbVectorSearchDialogComponent {
   private http = inject(HttpClient);
+  private dialog = inject(MatDialog);
   dialogRef = inject(MatDialogRef<FfbVectorSearchDialogComponent>);
 
   queryControl = new FormControl('');
@@ -40,7 +44,7 @@ export class FfbVectorSearchDialogComponent {
 
   displayedColumns: string[] = ['productionDate', 'site', 'phase', 'block', 'weight', 'quantity', 'score'];
 
-  constructor(@Inject(MAT_DIALOG_DATA) public data: any) {}
+  constructor(@Inject(MAT_DIALOG_DATA) public data: any) { }
 
   search() {
     const q = this.queryControl.value?.trim();
@@ -79,4 +83,25 @@ export class FfbVectorSearchDialogComponent {
     const d = new Date(date);
     return d.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: '2-digit' });
   }
+
+  openDetails(harvest: FFBProduction) {
+    const dialogRef = this.dialog.open(CreateFfbProductionDialogComponent, {
+      width: '800px',
+      data: {
+        harvest,
+        allSites: this.data.allSites || [],
+        allPhases: this.data.allPhases || [],
+        allBlocks: this.data.allBlocks || [],
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(result => {
+      // Ideally we might want to refresh the search results if edited, 
+      // but for now we just let them close it.
+      if (result === 'refresh') {
+        // We could re-trigger search if we want to reflect changes immediately
+        this.search();
+      }
+    });
+  }
 }

+ 5 - 1
src/app/ffb/ffb-production.component.ts

@@ -264,7 +264,11 @@ export class FfbProductionComponent implements OnInit {
       maxWidth: '95vw', // makes it responsive
       minWidth: '800px', // optional: ensures it doesn’t get too small
       height: '80vh',    // optional: taller dialog for table
-      data: {}
+      data: {
+        allSites: this.uniqueSites,
+        allPhases: this.uniquePhases,
+        allBlocks: this.uniqueBlocks,
+      }
     });
 
     dialogRef.afterClosed().subscribe((results: FFBProduction[] | undefined) => {