11<script setup lang="ts">
22import { ref , computed , watch , onMounted , nextTick } from ' vue'
3- import type { Ref } from ' vue'
43import Dialog from ' primevue/dialog'
54import Button from ' primevue/button'
65import Textarea from ' primevue/textarea'
6+ import Select from ' primevue/select'
77import SrJsonDiffViewer from ' ./SrJsonDiffViewer.vue'
8- import hljs from ' highlight.js/lib/core'
9- import json from ' highlight.js/lib/languages/json'
10- import ' highlight.js/styles/atom-one-dark.css'
8+ import SrParmsFormatTabs from ' ./SrParmsFormatTabs.vue'
9+ import { missionItems , iceSat2APIsItems , gediAPIsItems } from ' @/types/SrStaticOptions'
1110import type { ZodTypeAny } from ' zod'
1211import { useJsonImporter } from ' @/composables/SrJsonImporter'
1312import { importRequestJsonToStore } from ' @/utils/importRequestToStore'
@@ -27,8 +26,6 @@ const mapStore = useMapStore()
2726
2827const toast = useToast ()
2928
30- hljs .registerLanguage (' json' , json )
31-
3229function showToast(summary : string , detail : string , severity = ' warn' ) {
3330 toast .add ({
3431 severity ,
@@ -41,19 +38,16 @@ const props = withDefaults(
4138 defineProps <{
4239 zodSchema: ZodTypeAny
4340 width? : string
44- title? : string
4541 }>(),
4642 {
47- width: ' 60vw' ,
48- title: ' JSON Viewer'
43+ width: ' 60vw'
4944 }
5045)
5146
5247const emit = defineEmits <{
5348 (_e : ' json-valid' , _value : unknown ): void
5449}>()
5550
56- const jsonBlock = ref <HTMLElement | null >(null )
5751const editableReqJson = ref (' ' )
5852const parsedEditableReqJson = computed (() => {
5953 try {
@@ -94,12 +88,70 @@ const hasChangesToApply = computed(() => {
9488 return JSON .stringify (parsedEditableReqJson .value ) !== JSON .stringify (parsedCurrentReqJson .value )
9589})
9690
97- const readonlyHighlightedJson = computed (() => {
98- return hljs .highlight (currentReqJson .value , { language: ' json' }).value
91+ // Compute automatic fields based on selected API
92+ // These fields are auto-populated by the system and shouldn't show force checkboxes
93+ const computedAutomaticFields = computed (() => {
94+ const baseFields = [' asset' , ' output' , ' cmr' ]
95+ const api = reqParamsStore .iceSat2SelectedAPI
96+
97+ // Add API-specific automatic fields
98+ if (api === ' atl03x-surface' || api === ' atl06p' ) {
99+ baseFields .push (' fit' )
100+ } else if (api === ' atl03x-phoreal' || api === ' atl08p' ) {
101+ baseFields .push (' phoreal' )
102+ } else if (api === ' atl24x' ) {
103+ baseFields .push (' atl24' )
104+ } else if (api === ' atl13x' ) {
105+ baseFields .push (' atl13' )
106+ }
107+
108+ return new Set (baseFields )
99109})
100110
101111const fileInputRef = ref <HTMLInputElement | null >(null )
102112
113+ // Endpoint selector state (used in header)
114+ const selectedMission = ref (reqParamsStore .missionValue )
115+ const selectedAPI = ref (reqParamsStore .getCurAPIStr ())
116+
117+ // Computed API options based on selected mission
118+ const apiOptions = computed (() => {
119+ return selectedMission .value === ' ICESat-2' ? iceSat2APIsItems : gediAPIsItems
120+ })
121+
122+ // Update selected API when mission changes
123+ watch (selectedMission , (newMission ) => {
124+ const options = newMission === ' ICESat-2' ? iceSat2APIsItems : gediAPIsItems
125+ // If current API is not in new mission's options, reset to first option
126+ if (! options .includes (selectedAPI .value )) {
127+ selectedAPI .value = options [0 ]
128+ }
129+ })
130+
131+ // Handle mission change from header selector
132+ function handleMissionChange() {
133+ reqParamsStore .setMissionValue (selectedMission .value )
134+ // Update API in store based on new mission
135+ if (selectedMission .value === ' ICESat-2' ) {
136+ reqParamsStore .setIceSat2API (selectedAPI .value )
137+ } else {
138+ reqParamsStore .setGediAPI (selectedAPI .value )
139+ }
140+ // Refresh the request parameters display
141+ updateEditableJsonFromStore ()
142+ }
143+
144+ // Handle API change from header selector
145+ function handleAPIChange() {
146+ if (selectedMission .value === ' ICESat-2' ) {
147+ reqParamsStore .setIceSat2API (selectedAPI .value )
148+ } else {
149+ reqParamsStore .setGediAPI (selectedAPI .value )
150+ }
151+ // Refresh the request parameters display
152+ updateEditableJsonFromStore ()
153+ }
154+
103155const { data : importedData, error : importError, importJson } = useJsonImporter (props .zodSchema )
104156
105157const importFromFile = () => {
@@ -194,27 +246,17 @@ const copyEditableReqJsonToClipboard = async () => {
194246}
195247
196248watch (computedShowParamsDialog , (newVal ) => {
197- // console.log('SrJsonEditDialog watch showParamsDialog changed:', newVal);
198249 if (newVal ) {
199- // console.log('SrJsonEditDialog watch showParamsDialog Dialog opened, highlighting JSON.');
250+ // Initialize endpoint selectors with current store values
251+ selectedMission .value = reqParamsStore .missionValue
252+ selectedAPI .value = reqParamsStore .getCurAPIStr ()
200253 updateEditableJsonFromStore ()
201- void nextTick (() => highlightJson ())
202254 } else {
203- // console.log('SrJsonEditDialog watch showParamsDialog Dialog closed.');
204255 // Zoom to poly if it exists
205256 zoomToPoly ()
206257 }
207258})
208259
209- const highlightJson = () => {
210- logger .debug (' Highlighting JSON in readonly panel' )
211- if (jsonBlock .value ) {
212- jsonBlock .value .removeAttribute (' data-highlighted' ) // allow re-highlighting
213- jsonBlock .value .innerHTML = readonlyHighlightedJson .value // replace with fresh content
214- hljs .highlightElement (jsonBlock .value )
215- }
216- }
217-
218260function updateEditableJsonFromStore() {
219261 currentReqObj .value = reqParamsStore .getAtlxxReqParams (0 )
220262 editableReqJson .value = JSON .stringify (currentReqObj .value , null , 2 )
@@ -243,24 +285,6 @@ const importToStore = () => {
243285 isValidJson .value = false
244286 }
245287}
246- function exportToFile(json : string | Ref <string >) {
247- const jsonString = typeof json === ' string' ? json : json .value
248-
249- const defaultName = ` sliderule-request-${new Date ().toISOString ().replace (/ [:. ] / g , ' -' )}.json `
250- const filename = prompt (' Enter file name to save:' , defaultName )
251-
252- if (! filename ) return // user cancelled
253-
254- const blob = new Blob ([jsonString ], { type: ' application/json' })
255- const url = URL .createObjectURL (blob )
256-
257- const a = document .createElement (' a' )
258- a .href = url
259- a .download = filename .endsWith (' .json' ) ? filename : ` ${filename }.json `
260- a .click ()
261-
262- URL .revokeObjectURL (url )
263- }
264288
265289function handleParamsAccessed(index : number ) {
266290 logger .debug (' Params accessed at index (pre-flush)' , { index })
@@ -365,8 +389,24 @@ function zoomToPoly() {
365389 :modal =" true"
366390 :closable =" true"
367391 :style =" { width: props.width }"
368- :header =" props.title"
369392 >
393+ <template #header >
394+ <div class =" endpoint-header" >
395+ <span class =" endpoint-label" >endpoint =</span >
396+ <Select
397+ v-model =" selectedMission"
398+ :options =" missionItems"
399+ class =" endpoint-mission-select"
400+ @change =" handleMissionChange"
401+ />
402+ <Select
403+ v-model =" selectedAPI"
404+ :options =" apiOptions"
405+ class =" endpoint-api-select"
406+ @change =" handleAPIChange"
407+ />
408+ </div >
409+ </template >
370410 <div class =" sr-dialog-container" >
371411 <div class =" json-dual-panel" >
372412 <!-- Editable panel -->
@@ -416,34 +456,17 @@ function zoomToPoly() {
416456 />
417457 </div >
418458 </div >
419- <!-- Readonly panel -->
459+ <!-- Current Request State panel with format tabs -->
420460 <div class =" json-pane" >
421461 <h3 class =" pane-title" >Current Request State</h3 >
422- <!-- eslint-disable-next-line vue/no-v-html -->
423- <pre ref =" jsonBlock" v-html =" readonlyHighlightedJson" ></pre >
424- <div class =" copy-btn-container" >
425- <Button
426- label =" Copy to clipboard"
427- size =" small"
428- icon =" pi pi-copy"
429- @click =" copyEditableReqJsonToClipboard"
430- class =" copy-btn"
431- />
432- <Button
433- label =" Output to File"
434- size =" small"
435- icon =" pi pi-file-export"
436- @click =" exportToFile(editableReqJson)"
437- class =" copy-btn"
438- />
439- </div >
462+ <SrParmsFormatTabs :rcvdParms =" currentReqObj" :endpoint =" selectedAPI" mode =" sending" />
440463 </div >
441464 </div >
442465 <div class =" sr-diff-footer" >
443466 <SrJsonDiffViewer
444467 :before =" parsedEditableReqJson"
445468 :after =" parsedCurrentReqJson"
446- :automaticFields =" new Set(['asset', 'output', 'cmr']) "
469+ :automaticFields =" computedAutomaticFields "
447470 beforeLabel =" Editable Request"
448471 afterLabel =" Current Request State"
449472 @forced-req_params =" handleParamsAccessed"
@@ -492,12 +515,44 @@ pre {
492515.json-dual-panel {
493516 display : flex ;
494517 gap : 1rem ;
518+ align-items : stretch ;
495519}
496520
497521.json-pane {
498522 flex : 1 ;
499523 display : flex ;
500524 flex-direction : column ;
525+ min-width : 0 ;
526+ }
527+
528+ /* Make the right pane's tabs component stretch to fill available height */
529+ .json-pane :deep(.p-tabs ) {
530+ display : flex ;
531+ flex-direction : column ;
532+ flex : 1 ;
533+ }
534+
535+ .json-pane :deep(.p-tabpanels ) {
536+ flex : 1 ;
537+ display : flex ;
538+ flex-direction : column ;
539+ }
540+
541+ .json-pane :deep(.p-tabpanel ) {
542+ flex : 1 ;
543+ display : flex ;
544+ flex-direction : column ;
545+ }
546+
547+ .json-pane :deep(.tab-content ) {
548+ flex : 1 ;
549+ display : flex ;
550+ flex-direction : column ;
551+ }
552+
553+ .json-pane :deep(.tab-content pre ) {
554+ flex : 1 ;
555+ max-height : none ;
501556}
502557
503558.pane-title {
@@ -546,4 +601,25 @@ pre {
546601 font-weight : bold ;
547602 padding : 0.5rem 1rem ;
548603}
604+
605+ /* Endpoint header selector styles */
606+ .endpoint-header {
607+ display : flex ;
608+ align-items : center ;
609+ gap : 0.5rem ;
610+ font-size : 1.1rem ;
611+ }
612+
613+ .endpoint-label {
614+ font-weight : 600 ;
615+ color : var (--text-color );
616+ }
617+
618+ .endpoint-mission-select {
619+ min-width : 120px ;
620+ }
621+
622+ .endpoint-api-select {
623+ min-width : 150px ;
624+ }
549625 </style >
0 commit comments