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']"
@@ -305,6 +316,8 @@ export default defineComponent({
305316 const allRepositoryApps = ref <{ [repoName : string ]: AppCollectionItem [] }>({});
306317 const repositoriesLoaded = ref (false );
307318 const installedMap = ref <Record <string , InstallInfo >>({});
319+ const installationStatusLoading = ref (false );
320+ const showInstalledOnly = ref (false );
308321
309322 const updatedDateFormatter = new Intl .DateTimeFormat (undefined , {
310323 month: ' short' ,
@@ -366,6 +379,10 @@ export default defineComponent({
366379 arr = arr .filter ((app : AppCollectionItem ) => app .packaging_format === selectedCategory .value );
367380 }
368381
382+ // Apply "Installed Only" filter
383+ if (showInstalledOnly .value ) {
384+ arr = arr .filter ((app : AppCollectionItem ) => getInstallationInfo (app .slug_name ).installed );
385+ }
369386
370387 // Apply search filter
371388 if (search .value ) {
@@ -619,6 +636,7 @@ export default defineComponent({
619636 // State
620637 loading ,
621638 repoLoading ,
639+ installationStatusLoading ,
622640 error ,
623641 search ,
624642 selectedRepo ,
@@ -629,6 +647,7 @@ export default defineComponent({
629647 repositories ,
630648 repositoryOptions ,
631649 tableHeaders ,
650+ showInstalledOnly ,
632651
633652 // Feature flags
634653 isAdvancedFilteringEnabled ,
@@ -743,6 +762,20 @@ export default defineComponent({
743762 }
744763 }
745764
765+ .filter-group-checkbox {
766+ display : inline ;
767+ margin-left : 12px ;
768+
769+ .checkbox ,
770+ .text-label {
771+ vertical-align : middle ;
772+ }
773+ .text-label {
774+ color : var (--body-text );
775+ margin-left : 6px ; /* Add space between checkbox and label */
776+ }
777+ }
778+
746779 .view-controls {
747780 display : flex ;
748781 border : 1px solid var (--border );
0 commit comments