9494 <h4 >Manage Apps</h4 >
9595 </cv-column >
9696 </cv-row >
97+
98+ <cv-row class =" mg-bottom" >
99+ <cv-column :sm =" 4" >
100+ <h4 >Podman Images</h4 >
101+ </cv-column >
102+ </cv-row >
103+ <cv-row class =" mg-bottom" >
104+ <cv-column >
105+ <cv-tile light >
106+ <div v-if =" error.getPodmanImages" class =" error-section" >
107+ <NsInlineNotification
108+ kind =" error"
109+ :title =" $t('action.get-podman-images')"
110+ :description =" error.getPodmanImages"
111+ :showCloseButton =" false"
112+ />
113+ </div >
114+ <div class =" images-container" >
115+ <div v-if =" loading.getPodmanImages" class =" loading-section" >
116+ <cv-loading >Loading images...</cv-loading >
117+ </div >
118+ <div
119+ v-else-if =" podmanImages.length === 0"
120+ class =" empty-state"
121+ >
122+ <p >No podman images found</p >
123+ </div >
124+ <cv-structured-list v-else >
125+ <template slot="headings">
126+ <cv-structured-list-heading
127+ >Repository</cv-structured-list-heading
128+ >
129+ <cv-structured-list-heading
130+ >Tag</cv-structured-list-heading
131+ >
132+ <cv-structured-list-heading
133+ >Image ID</cv-structured-list-heading
134+ >
135+ <cv-structured-list-heading
136+ >Created</cv-structured-list-heading
137+ >
138+ <cv-structured-list-heading
139+ >Size</cv-structured-list-heading
140+ >
141+ </template >
142+ <template slot="items">
143+ <cv-structured-list-item
144+ v-for =" (image, index) in podmanImages"
145+ :key =" index"
146+ >
147+ <cv-structured-list-data >{{
148+ image.repositories && image.repositories.length > 0
149+ ? image.repositories[0]
150+ : "N/A"
151+ }}</cv-structured-list-data >
152+ <cv-structured-list-data >{{
153+ image.tags && image.tags.length > 0
154+ ? image.tags[0]
155+ : "N/A"
156+ }}</cv-structured-list-data >
157+ <cv-structured-list-data >{{
158+ image.id ? image.id.substring(0, 12) : "N/A"
159+ }}</cv-structured-list-data >
160+ <cv-structured-list-data >{{
161+ image.created || "N/A"
162+ }}</cv-structured-list-data >
163+ <cv-structured-list-data >{{
164+ image.size || "N/A"
165+ }}</cv-structured-list-data >
166+ </cv-structured-list-item >
167+ </template >
168+ </cv-structured-list >
169+ </div >
170+ <div class =" images-actions" >
171+ <cv-button
172+ kind =" tertiary"
173+ :icon =" Refresh20"
174+ @click.prevent =" getPodmanImages"
175+ :disabled =" loading.getPodmanImages"
176+ >
177+ Refresh Images
178+ </cv-button >
179+ </div >
180+ </cv-tile >
181+ </cv-column >
182+ </cv-row >
97183 <cv-row class =" mg-bottom" >
98184 <cv-column :sm =" 12" >
99185 <cv-tile light >
267353<script >
268354import to from " await-to-js" ;
269355import { mapState } from " vuex" ;
356+ import { Refresh20 , TrashCan20 , Save20 , Add20 } from " @carbon/icons-vue" ;
270357import {
271358 QueryParamService ,
272359 UtilService ,
@@ -277,6 +364,12 @@ import {
277364
278365export default {
279366 name: " Settings" ,
367+ components: {
368+ Refresh20,
369+ TrashCan20,
370+ Save20,
371+ Add20,
372+ },
280373
281374 mixins: [
282375 TaskService,
@@ -300,6 +393,7 @@ export default {
300393 hasBackup: false ,
301394
302395 erpSelectedModules: [],
396+ podmanImages: [],
303397 app_json: " " ,
304398 appJsonError: " " ,
305399 frappeVersion: " version-15" ,
@@ -319,13 +413,15 @@ export default {
319413 getConfiguration: false ,
320414 configureModule: false ,
321415 buildDockerImage: false ,
416+ getPodmanImages: false ,
322417 },
323418 error: {
324419 getConfiguration: " " ,
325420 configureModule: " " ,
326421 host: " " ,
327422 lets_encrypt: " " ,
328423 http2https: " " ,
424+ getPodmanImages: " " ,
329425 },
330426 };
331427 },
@@ -376,6 +472,7 @@ export default {
376472 },
377473 created () {
378474 this .getConfiguration ();
475+ this .getPodmanImages ();
379476 },
380477 beforeRouteEnter (to , from , next ) {
381478 next ((vm ) => {
@@ -388,6 +485,56 @@ export default {
388485 next ();
389486 },
390487 methods: {
488+ async getPodmanImages () {
489+ this .loading .getPodmanImages = true ;
490+ this .error .getPodmanImages = " " ;
491+ const taskAction = " podman-images-module" ;
492+ const eventId = this .getUuid ();
493+
494+ // register to task error
495+ this .core .$root .$once (
496+ ` ${ taskAction} -aborted-${ eventId} ` ,
497+ this .getPodmanImagesAborted
498+ );
499+
500+ // register to task completion
501+ this .core .$root .$once (
502+ ` ${ taskAction} -completed-${ eventId} ` ,
503+ this .getPodmanImagesCompleted
504+ );
505+
506+ const res = await to (
507+ this .createModuleTaskForApp (this .instanceName , {
508+ action: taskAction,
509+ extra: {
510+ title: this .$t (" action." + taskAction),
511+ isNotificationHidden: true ,
512+ eventId,
513+ },
514+ })
515+ );
516+ const err = res[0 ];
517+
518+ if (err) {
519+ console .error (` error creating task ${ taskAction} ` , err);
520+ this .error .getPodmanImages = this .getErrorMessage (err);
521+ this .loading .getPodmanImages = false ;
522+ return ;
523+ }
524+ },
525+ getPodmanImagesAborted (taskResult , taskContext ) {
526+ console .error (` ${ taskContext .action } aborted` , taskResult);
527+ this .error .getPodmanImages = this .$t (" error.generic_error" );
528+ this .loading .getPodmanImages = false ;
529+ },
530+ getPodmanImagesCompleted (taskContext , taskResult ) {
531+ const imagesData = taskResult .output ;
532+ this .podmanImages = imagesData .images || [];
533+ if (imagesData .error ) {
534+ this .error .getPodmanImages = imagesData .error ;
535+ }
536+ this .loading .getPodmanImages = false ;
537+ },
391538 openAddAppModal () {
392539 this .newApp = {
393540 app_name: " " ,
@@ -822,4 +969,27 @@ export default {
822969 align-items : center ;
823970 gap : 0.5rem ;
824971}
972+
973+ .images-container {
974+ max-height : 400px ;
975+ overflow-y : auto ;
976+ margin-bottom : $spacing-06 ;
977+ }
978+
979+ .images-actions {
980+ display : flex ;
981+ gap : $spacing-04 ;
982+ align-items : center ;
983+ }
984+
985+ .error-section {
986+ margin-bottom : $spacing-06 ;
987+ }
988+
989+ .loading-section {
990+ display : flex ;
991+ justify-content : center ;
992+ align-items : center ;
993+ padding : $spacing-06 ;
994+ }
825995 </style >
0 commit comments