11<script setup lang="ts">
2- import { ref , Ref } from " vue" ;
2+ import { ref , Ref , onMounted , onBeforeUnmount , nextTick } from " vue" ;
33import { getDirectoryInfo } from " ../api/rest" ;
44import { selectedDirectories } from " ../store/directoryStore" ;
55import { useRedactionPlan } from " ../store/imageStore" ;
66import { redactionStateFlags } from " ../store/redactionStore" ;
7- import { DirectoryData } from " ../store/types" ;
7+ import { DirectoryData , Path } from " ../store/types" ;
88
99const props = defineProps ({
1010 modalId: {
@@ -29,25 +29,34 @@ const directoryData: Ref<DirectoryData> = ref({
2929 childrenYaml: [],
3030});
3131
32+ const loadingData = ref (false );
33+
3234const updateDirectories = async (currentDirectory ? : string ) => {
35+ directoryData .value .children = [];
36+ directoryData .value .childrenImages = [];
37+ directoryData .value .childrenYaml = [];
38+ const timeout = setTimeout (() => {
39+ loadingData .value = true ;
40+ }, 100 );
41+
3342 const data = await getDirectoryInfo (currentDirectory );
43+ clearTimeout (timeout );
44+ loadingData .value = false ;
3445 directoryData .value = await {
3546 ... data ,
3647 children: data .child_directories ,
3748 childrenImages: data .child_images ,
3849 childrenYaml: data .child_yaml_files ,
3950 };
51+ loadingData .value = false ;
52+ calculateVisibleItems ();
4053};
4154updateDirectories ();
4255
4356const closeModal = () => {
4457 modal .value .close ();
4558};
4659
47- const updateSelectedDirectories = (path : string ) => {
48- selectedDirectories .value [props .modalId ] = path ;
49- };
50-
5160const updateTableData = () => {
5261 redactionStateFlags .value .redactionSnackbar = false ;
5362 useRedactionPlan .updateImageData ({
@@ -58,19 +67,66 @@ const updateTableData = () => {
5867 update: false ,
5968 });
6069};
70+ const updateSelectedDirectories = async (path : string ) => {
71+ selectedDirectories .value [props .modalId ] = path ;
72+ };
73+
74+ const visibleImages: Ref <Path []> = ref ([]);
75+ const remainingImages = ref (0 );
76+
77+ const calculateVisibleItems = () => {
78+ const menuTop = document .querySelector (" .menu-top" );
79+ const listContainer = document .querySelector (" .list-container" );
80+ // Determine and set the height of the list container
81+ listContainer ?.setAttribute (
82+ " style" ,
83+ ` height: calc(100% - (${menuTop ?.clientHeight }px + 3.5rem)) ` ,
84+ );
85+
86+ nextTick (() => {
87+ const listItems = listContainer ?.querySelectorAll (" li" );
88+ const containerHeight = listContainer ?.clientHeight ;
89+ const listHeight = ref (0 );
90+ const visibleItems = ref (0 );
91+ // Determine the height of each list item
92+ const listItemHeight = listItems ? listItems [0 ].clientHeight : 0 ;
93+
94+ directoryData .value .childrenImages .forEach (() => {
95+ listHeight .value += listItemHeight ;
96+ if (containerHeight && listHeight .value < containerHeight ) {
97+ visibleItems .value += 1 ;
98+ }
99+ });
100+
101+ visibleImages .value = directoryData .value .childrenImages .slice (
102+ 0 ,
103+ visibleItems .value ,
104+ );
105+ remainingImages .value =
106+ directoryData .value .childrenImages .length - visibleItems .value ;
107+ });
108+ };
109+ onMounted (() => {
110+ calculateVisibleItems ();
111+ window .addEventListener (" resize" , calculateVisibleItems );
112+ });
113+
114+ onBeforeUnmount (() => {
115+ window .removeEventListener (" resize" , calculateVisibleItems );
116+ });
61117 </script >
62118
63119<template >
64120 <dialog :id =" modalId" ref =" modal" class =" modal" >
65121 <div class =" w-full max-w-4xl h-4/5 rounded-xl overflow-hidden" >
66- <div class =" modal-box w-full max-w-4xl h-full overflow-auto pt-0" >
67- <div class =" sticky top-0 pt-6 bg-white" >
122+ <div class =" modal-box w-full max-w-4xl h-4/5 overflow-auto pt-0" >
123+ <div class =" sticky top-0 pt-6 bg-white menu-top " >
68124 <div class =" flex justify-between" >
69125 <h2 class =" text-lg font-semibold" >
70126 {{ title }}
71127 </h2 >
72128 <button
73- class =" btn bg -primary float-right text-white uppercase"
129+ class =" btn btn -primary float-right text-white uppercase"
74130 type =" button"
75131 @click ="
76132 $emit('update-image-list'),
@@ -107,56 +163,72 @@ const updateTableData = () => {
107163 </ul >
108164 </div >
109165 </div >
110- <ul class =" text-blue-700" >
111- <li
112- v-for =" child in directoryData.children.sort((a, b) => {
113- const folder1 = a.name.toLowerCase();
114- const folder2 = b.name.toLowerCase();
115- if (folder1 < folder2) {
116- return -1;
117- }
118- if (folder1 > folder2) {
119- return 1;
120- }
121- return 0;
122- })"
123- :key =" child.path"
124- class =" hover:bg-base-300 cursor-default py-0.5"
125- @click ="
126- updateDirectories(child.path),
127- updateSelectedDirectories(child.path)
128- "
166+ <div
167+ v-if =" loadingData"
168+ class =" text-center"
169+ >
170+ <span class =" loading loading-spinner text-primary" ></span >
171+ <span class =" ml-2 italic font-light align-top"
172+ >Collecting Directory Data</span
129173 >
130- <i class =" ri-folder-3-fill text-neutral" ></i >
131- {{ child.name }}
132- </li >
133- </ul >
134- <ul class =" pl-2" >
135- <template v-if =" modalId !== ' rulesetDirectory' " >
136- <li
137- v-for =" child_image in directoryData.childrenImages.slice(0, 10)"
138- :key =" child_image.path"
139- class =" py-0.5"
140- >
141- <i class =" ri-image-fill text-sky-800" ></i >
142- {{ child_image.name }}
143- </li >
144- <li v-if =" directoryData.childrenImages.length > 10" class =" italic" >
145- {{ directoryData.childrenImages.length - 10 }} More Images
146- </li >
147- </template >
148- <template v-if =" modalId === ' rulesetDirectory' " >
174+ </div >
175+ <div class =" list-container" >
176+ <ul class =" text-blue-700" >
149177 <li
150- v-for =" ruleset in directoryData.childrenYaml"
151- :key =" ruleset.path"
178+ v-for =" child in directoryData.children.sort((a, b) => {
179+ const folder1 = a.name.toLowerCase();
180+ const folder2 = b.name.toLowerCase();
181+ if (folder1 < folder2) {
182+ return -1;
183+ }
184+ if (folder1 > folder2) {
185+ return 1;
186+ }
187+ return 0;
188+ })"
189+ :key =" child.path"
152190 class =" hover:bg-base-300 cursor-default py-0.5"
153- @click =" updateSelectedDirectories(ruleset.path)"
191+ @click ="
192+ updateDirectories(child.path),
193+ updateSelectedDirectories(child.path)
194+ "
154195 >
155- <i class =" ri-file-text-line text-neutral" ></i >
156- {{ ruleset .name }}
196+ <i class =" ri-folder-3-fill text-neutral" ></i >
197+ {{ child .name }}
157198 </li >
158- </template >
159- </ul >
199+ </ul >
200+ <div class =" list-container" >
201+ <ul class =" pl-2" >
202+ <template v-if =" modalId !== ' rulesetDirectory' " >
203+ <li
204+ v-for =" child_image in visibleImages"
205+ :key =" child_image.path"
206+ class =" py-0.5"
207+ >
208+ <i class =" ri-image-fill text-sky-800" ></i >
209+ {{ child_image.name }}
210+ </li >
211+ <li
212+ v-if =" directoryData.childrenImages.length > 10"
213+ class =" italic"
214+ >
215+ {{ remainingImages }} More Images
216+ </li >
217+ </template >
218+ <template v-if =" modalId === ' rulesetDirectory' " >
219+ <li
220+ v-for =" ruleset in directoryData.childrenYaml"
221+ :key =" ruleset.path"
222+ class =" hover:bg-base-300 cursor-default py-0.5"
223+ @click =" updateSelectedDirectories(ruleset.path)"
224+ >
225+ <i class =" ri-file-text-line text-neutral" ></i >
226+ {{ ruleset.name }}
227+ </li >
228+ </template >
229+ </ul >
230+ </div >
231+ </div >
160232 </div >
161233 </div >
162234 <form method =" dialog" class =" modal-backdrop w-screen h-screen absolute" >
0 commit comments