3838 </select >
3939 </div >
4040
41+ <div class =" filter-group-checkbox" >
42+ <input
43+ id =" show-installed-only"
44+ v-model =" showInstalledOnly"
45+ type =" checkbox"
46+ class =" checkbox"
47+ aria-label =" Show only installed applications"
48+ />
49+ <label for =" show-installed-only" class =" text-label" >{{ t('suseai.apps.showInstalledOnly', 'Installed') }}</label >
50+ </div >
51+
4152 <div class =" view-controls" role =" group" aria-label =" View mode selection" >
4253 <button
4354 :class =" ['btn', 'btn-sm', viewMode === 'tiles' ? 'role-primary' : 'role-secondary']"
@@ -297,6 +308,8 @@ export default defineComponent({
297308 const allRepositoryApps = ref <{ [repoName : string ]: AppCollectionItem [] }>({});
298309 const repositoriesLoaded = ref (false );
299310 const installedMap = ref <Record <string , InstallInfo >>({});
311+ const installationStatusLoading = ref (false );
312+ const showInstalledOnly = ref (false );
300313
301314 const updatedDateFormatter = new Intl .DateTimeFormat (undefined , {
302315 month: ' short' ,
@@ -358,6 +371,10 @@ export default defineComponent({
358371 arr = arr .filter ((app : AppCollectionItem ) => app .packaging_format === selectedCategory .value );
359372 }
360373
374+ // Apply "Installed Only" filter
375+ if (showInstalledOnly .value ) {
376+ arr = arr .filter ((app : AppCollectionItem ) => getInstallationInfo (app .slug_name ).installed );
377+ }
361378
362379 // Apply search filter
363380 if (search .value ) {
@@ -611,6 +628,7 @@ export default defineComponent({
611628 // State
612629 loading ,
613630 repoLoading ,
631+ installationStatusLoading ,
614632 error ,
615633 search ,
616634 selectedRepo ,
@@ -621,6 +639,7 @@ export default defineComponent({
621639 repositories ,
622640 repositoryOptions ,
623641 tableHeaders ,
642+ showInstalledOnly ,
624643
625644 // Feature flags
626645 isAdvancedFilteringEnabled ,
@@ -735,6 +754,20 @@ export default defineComponent({
735754 }
736755 }
737756
757+ .filter-group-checkbox {
758+ display : inline ;
759+ margin-left : 12px ;
760+
761+ .checkbox ,
762+ .text-label {
763+ vertical-align : middle ;
764+ }
765+ .text-label {
766+ color : var (--body-text );
767+ margin-left : 6px ; /* Add space between checkbox and label */
768+ }
769+ }
770+
738771 .view-controls {
739772 display : flex ;
740773 border : 1px solid var (--border );
0 commit comments