99 />
1010
1111 <div v-if =" file" class =" q-my-lg" >
12+ <!-- YAML/Text Preview -->
1213 <div v-if =" isYaml" class =" q-mb-lg" >
1314 <h2 class =" text-h4 q-mb-md" >Content Preview</h2 >
1415 <div
2021 }}</pre >
2122 </div >
2223 <div v-else class =" row items-center q-gutter-sm text-grey-7" >
23- <q-spinner-dots size =" 1.5em" />
24- <span >Loading content...</span >
24+ <q-spinner-dots size =" 1.5em" /> <span >Loading content...</span >
2525 </div >
2626 </div >
2727
28+ <!-- Binary/ROS Preview -->
2829 <div v-else-if =" displayTopics && preview.isReaderReady.value" >
29- <FileTopicList
30- :file =" file "
30+ <FileTopicTable
31+ :topics =" file . topics "
3132 :is-loading =" isLoading "
32- :reader-ready =" preview .isReaderReady .value "
3333 :previews =" preview .topicPreviews "
3434 :loading-state =" preview .topicLoadingState "
3535 :topic-errors =" preview .topicErrors "
36- :format-payload =" preview .formatPayload "
3736 @load-preview =" preview .fetchTopicMessages "
38- @redirect-related =" redirectToRelated "
3937 />
4038 </div >
4139
40+ <!-- Fallback / Unsupported -->
4241 <div
4342 v-else-if =" !displayTopics && !isLoading"
4443 class =" text-center q-pa-xl bg-grey-1 rounded-borders border-dashed text-grey-7"
4544 >
4645 <q-icon name =" sym_o_description" size =" 4em" class =" q-mb-md" />
4746 <div class =" text-h6" >No Preview Available</div >
4847 <div class =" text-caption q-mt-xs" >
49- Preview is not yet ready or currently not supported for
48+ Preview not supported for
5049 <span class =" text-weight-bold" >.{{ fileExtension }}</span >
51- files.
5250 </div >
53- <q-btn
54- label =" Download File"
55- color =" primary"
56- flat
57- icon =" sym_o_download"
58- class =" q-mt-md"
59- @click =" handleDownload"
60- />
6151 </div >
6252
6353 <FileHistory :events =" events " />
6454
6555 <div
66- v-if =" preview.readerError.value && displayTopics "
56+ v-if =" preview.readerError.value"
6757 class =" q-my-md text-negative text-center"
6858 >
69- <q-icon name =" sym_o_warning" />
70- {{ preview.readerError.value }}
59+ <q-icon name =" warning" /> {{ preview.readerError.value }}
7160 </div >
7261 </div >
7362
7463 <div v-else class =" text-center q-pa-md" >
7564 <q-spinner size =" 3em" color =" primary" />
76- <div class =" text-grey q-mt-sm" >Loading file details ...</div >
65+ <div class =" text-grey q-mt-sm" >Loading file...</div >
7766 </div >
7867</template >
7968
8069<script setup lang="ts">
8170import { FileState , FileType } from ' @common/enum' ;
8271import { copyToClipboard , Notify } from ' quasar' ;
83- import { useRosmsgPreview } from ' src/composables/use-rosmsg-preview' ;
8472import {
8573 registerNoPermissionErrorHandler ,
8674 useFile ,
8775 useFileEvents ,
8876} from ' src/hooks/query-hooks' ;
8977import { useFileUUID } from ' src/hooks/router-hooks' ;
90- import ROUTES from ' src/router/routes' ;
9178import { _downloadFile } from ' src/services/generic' ;
9279import { downloadFile } from ' src/services/queries/file' ;
9380import { computed , ref , watch } from ' vue' ;
94- import { useRouter } from ' vue-router' ;
9581import FileHeader from ' ./file-header.vue' ;
9682import FileHistory from ' ./file-history.vue' ;
97- import FileTopicList from ' ./file-topic-list.vue' ;
9883
99- const $router = useRouter () ;
100- const fileUuid = useFileUUID () ;
84+ import { useRosmsgPreview } from ' ../../composables/use-rosmsg-preview ' ;
85+ import FileTopicTable from ' ./file-topic-table.vue ' ;
10186
102- // --- Data Fetching ---
87+ const fileUuid = useFileUUID ();
10388const { isLoading, data : file, error, isLoadingError } = useFile (fileUuid );
10489registerNoPermissionErrorHandler (isLoadingError , fileUuid , ' file' , error );
10590const { data : events } = useFileEvents (fileUuid );
10691
10792const preview = useRosmsgPreview ();
10893const yamlContent = ref <string | undefined >(undefined );
10994
110- const fileExtension = computed (() => {
111- const name = file .value ?.filename ?? ' ' ;
112- return name .split (' .' ).pop ()?.toLowerCase () ?? ' ' ;
113- });
114-
115- const isYaml = computed (() => {
116- return [' yml' , ' yaml' ].includes (fileExtension .value );
117- });
118-
95+ const fileExtension = computed (
96+ () => file .value ?.filename ?.split (' .' ).pop ()?.toLowerCase () ?? ' ' ,
97+ );
98+ const isYaml = computed (() => [' yml' , ' yaml' ].includes (fileExtension .value ));
11999const isSupportedBinary = computed (() => {
120100 if (! file .value ) return false ;
121- const isBagType = file .value .type === FileType .BAG ;
122- const isMcapType = file .value .type === FileType .MCAP ;
123- const isDatabase3 = file .value .type === FileType .DB3 ;
124- return (isBagType || isMcapType ) && ! isDatabase3 ;
101+ return (
102+ (file .value .type === FileType .BAG ||
103+ file .value .type === FileType .MCAP ) &&
104+ file .value .type !== FileType .DB3
105+ );
125106});
126-
127107const displayTopics = computed (
128108 () => file .value ?.state === FileState .OK && isSupportedBinary .value ,
129109);
130110
131- // --- Initialization Logic ---
111+ // --- Init ---
132112watch (
133113 () => file .value ,
134114 async (currentFile ) => {
135- // Guard clauses
136115 if (
137116 ! currentFile ||
138117 currentFile .state !== FileState .OK ||
139118 preview .isReaderReady .value
140- ) {
119+ )
141120 return ;
142- }
143121
144122 try {
145- const dynamicUrl = await downloadFile (
146- currentFile .uuid ,
147- false ,
148- true ,
149- );
123+ const url = await downloadFile (currentFile .uuid , false , true );
150124
151- // 1. Handle Text Files (YAML)
152125 if (isYaml .value ) {
153- console .log (' Loading YAML content...' );
154- const response = await fetch (dynamicUrl );
155- yamlContent .value = response .ok
156- ? await response .text ()
157- : ` Error loading content: ${response .statusText } ` ;
158- return ;
159- }
160-
161- // 2. Handle Supported Binaries
162- if (isSupportedBinary .value ) {
163- console .log (` Initializing preview for ${currentFile .type }... ` );
164- const strategyType =
126+ const results = await fetch (url );
127+ yamlContent .value = results .ok
128+ ? await results .text ()
129+ : ' Error loading content' ;
130+ } else if (isSupportedBinary .value ) {
131+ const type =
165132 currentFile .type === FileType .BAG ? ' rosbag' : ' mcap' ;
166- await preview .init (dynamicUrl , strategyType );
167- return ;
133+ await preview .init (url , type );
168134 }
169-
170- // 3. Unsupported files: Do nothing (Template renders placeholder)
171- console .log (` No preview strategy for .${fileExtension .value } ` );
172- } catch (init_error : unknown ) {
173- console .error (' Error setting up preview:' , init_error );
135+ } catch (error_ ) {
136+ console .error (error_ );
174137 }
175138 },
176139 { immediate: true },
177140);
178141
179142// --- Actions ---
180- const handleDownload = (): Promise < void > =>
143+ const handleDownload = (): void =>
181144 _downloadFile (file .value ?.uuid ?? ' ' , file .value ?.filename ?? ' ' );
182145const copyHash = (): Promise <void > => copyToClipboard (file .value ?.hash ?? ' ' );
183146const copyUuid = (): Promise <void > => copyToClipboard (file .value ?.uuid ?? ' ' );
184-
185147async function copyPublicLink(): Promise <void > {
186148 if (! fileUuid .value ) return ;
187149 const link = await downloadFile (fileUuid .value , false );
188150 await copyToClipboard (link );
189151 Notify .create ({
190152 message: ' Copied: Link valid for 7 days' ,
191153 color: ' positive' ,
192- timeout: 2000 ,
193- });
194- }
195-
196- async function redirectToRelated(): Promise <void > {
197- if (! file .value ?.relatedFileUuid ) return ;
198- await $router .push ({
199- name: ROUTES .FILE .routeName ,
200- params: {
201- projectUuid: file .value .mission .project .uuid ,
202- missionUuid: file .value .mission .uuid ,
203- file_uuid: file .value .relatedFileUuid ,
204- },
205154 });
206155}
207156 </script >
@@ -210,8 +159,6 @@ async function redirectToRelated(): Promise<void> {
210159.text-code {
211160 font-family : monospace ;
212161 font-size : 13px ;
213- line-height : 1.5 ;
214- color : #333 ;
215162}
216163.border-solid {
217164 border : 1px solid #e0e0e0 ;
0 commit comments