xuang7 commented on code in PR #5675:
URL: https://github.com/apache/texera/pull/5675#discussion_r3487423681


##########
frontend/src/app/workspace/component/result-panel/result-panel-modal.component.ts:
##########
@@ -42,29 +47,79 @@ import { NgxJsonViewerModule } from "ngx-json-viewer";
   selector: "texera-row-modal-content",
   templateUrl: "./result-panel-modal.component.html",
   styleUrls: ["./result-panel-model.component.scss"],
-  imports: [NgxJsonViewerModule],
+  imports: [CommonModule, NzButtonModule, NzIconModule],
 })
 export class RowModalComponent implements OnChanges {
+  rowEntries: { key: string; value: string; mediaSrc: string; isVideo: 
boolean; isImage: boolean; isAudio: boolean }[] =
+    [];
   // Index of current displayed row in currentResult
-  readonly operatorId: string = inject(NZ_MODAL_DATA).operatorId;
-  rowIndex: number = inject(NZ_MODAL_DATA).rowIndex;
+  private readonly modalData: { operatorId: string; rowIndex: number; 
rowData?: Record<string, unknown> } =
+    inject(NZ_MODAL_DATA);
+  readonly operatorId: string = this.modalData.operatorId;
+  rowIndex: number = this.modalData.rowIndex;
   currentDisplayRowData: Record<string, unknown> = {};
 
   constructor(
     public modal: NzModalRef<any, number>,
     private workflowResultService: WorkflowResultService,
-    private resizeService: PanelResizeService
+    private resizeService: PanelResizeService,
+    private notificationService: NotificationService
   ) {
+    if (this.modalData.rowData) {
+      this.currentDisplayRowData = this.modalData.rowData;
+      this.rowEntries = this.buildRowEntries(this.currentDisplayRowData);
+    }
     this.ngOnChanges();
   }
 
+  get prettyRowJson(): string {
+    return JSON.stringify(this.currentDisplayRowData, null, 2);
+  }
+
+  copyText(text: string): void {
+    navigator.clipboard.writeText(text).then(
+      () => this.notificationService.success("Copied to clipboard"),
+      () => this.notificationService.error("Failed to copy")
+    );
+  }
+
   ngOnChanges(): void {
     this.workflowResultService
       .getPaginatedResultService(this.operatorId)
       ?.selectTuple(this.rowIndex, this.resizeService.pageSize)
       .pipe(untilDestroyed(this))
       .subscribe(res => {
-        this.currentDisplayRowData = res.tuple;
+        if (res?.tuple) {
+          this.currentDisplayRowData = res.tuple;
+          this.rowEntries = this.buildRowEntries(this.currentDisplayRowData);
+        }
       });
   }
+
+  trackByEntryKey(_index: number, entry: { key: string }): string {
+    return entry.key;
+  }
+
+  private resolveMediaSrc(value: string): string {
+    if (!value.startsWith("http://";) && !value.startsWith("https://";)) {
+      return value;
+    }
+    return 
`${AppSettings.getApiEndpoint()}/huggingface/media-proxy?url=${encodeURIComponent(value)}`;

Review Comment:
   Remote (http/https) media is routed through /huggingface/media-proxy and 
loaded via a native video, img, audio src. Since that endpoint inherits 
class-level @ RolesAllowed(REGULAR/ADMIN) and native tags don't carry the 
angular-jwt token, those requests will likely 401.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to