@@ -19,6 +19,8 @@ const {
1919 confirmDelete,
2020 actionInProgress,
2121 isContainerUpdateInProgress,
22+ isContainerUpdateQueued,
23+ getContainerUpdateSequenceLabel,
2224 error,
2325 registryColorBg,
2426 registryColorText,
@@ -28,23 +30,47 @@ const {
2830 activeDetailTab,
2931} = useContainersViewTemplateContext ();
3032
33+ function isActionQueued(container : { id? : unknown ; name? : unknown }) {
34+ return isContainerUpdateQueued (container );
35+ }
36+
3137function isActionInProgress(container : { id? : unknown ; name? : unknown }) {
3238 return (
3339 hasTrackedContainerAction (actionInProgress .value , container ) ||
3440 isContainerUpdateInProgress (container )
3541 );
3642}
3743
44+ function isActionBlocked(container : { id? : unknown ; name? : unknown }) {
45+ return isActionInProgress (container ) || isActionQueued (container );
46+ }
47+
48+ function formatUpdateStateLabel(
49+ container : { id? : unknown ; name? : unknown },
50+ baseLabel : ' Updating' | ' Queued' ,
51+ ) {
52+ const sequence = getContainerUpdateSequenceLabel (container );
53+ return sequence ? ` ${baseLabel } ${sequence } ` : baseLabel ;
54+ }
55+
3856function getStatusLabel(container : { id? : unknown ; name? : unknown ; status? : string }) {
39- return isActionInProgress (container ) ? ' Updating' : (container .status ?? ' unknown' );
57+ if (isActionInProgress (container )) {
58+ return formatUpdateStateLabel (container , ' Updating' );
59+ }
60+ if (isActionQueued (container )) {
61+ return formatUpdateStateLabel (container , ' Queued' );
62+ }
63+ return container .status ?? ' unknown' ;
4064}
4165
4266function getStatusTone(container : { id? : unknown ; name? : unknown ; status? : string }) {
43- return isActionInProgress (container )
44- ? ' warning'
45- : container .status === ' running'
46- ? ' success'
47- : ' danger' ;
67+ if (isActionInProgress (container )) {
68+ return ' warning' ;
69+ }
70+ if (isActionQueued (container )) {
71+ return ' neutral' ;
72+ }
73+ return container .status === ' running' ? ' success' : ' danger' ;
4874}
4975 </script >
5076
@@ -65,7 +91,7 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
6591 </AppButton >
6692 <div class =" flex items-center gap-3 min-w-0" >
6793 <StatusDot
68- :status =" isActionInProgress (selectedContainer) ? 'warning' : selectedContainer.status === 'running' ? 'running' : 'stopped'"
94+ :status =" isActionBlocked (selectedContainer) ? 'warning' : selectedContainer.status === 'running' ? 'running' : 'stopped'"
6995 :pulse =" isActionInProgress(selectedContainer)"
7096 v-tooltip.top =" getStatusLabel(selectedContainer)"
7197 size =" lg" />
@@ -85,6 +111,11 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
85111 name =" spinner"
86112 :size =" 12"
87113 class =" mr-1 dd-spin" />
114+ <AppIcon
115+ v-else-if =" isActionQueued(selectedContainer)"
116+ name =" clock"
117+ :size =" 12"
118+ class =" mr-1" />
88119 {{ getStatusLabel(selectedContainer) }}
89120 </AppBadge >
90121 <AppBadge
@@ -120,9 +151,9 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
120151 <AppButton size =" none" variant =" plain" weight =" none"
121152 v-if =" selectedContainer.status === 'running'"
122153 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-semibold transition-colors"
123- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
154+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
124155 :style =" { backgroundColor: 'var(--dd-danger-muted)', color: 'var(--dd-danger)', border: '1px solid var(--dd-danger)' }"
125- :disabled =" isActionInProgress (selectedContainer)"
156+ :disabled =" isActionBlocked (selectedContainer)"
126157 aria-label =" Stop container"
127158 @click =" confirmStop(selectedContainer)" >
128159 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'stop'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
@@ -131,27 +162,27 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
131162 <AppButton size =" none" variant =" plain" weight =" none"
132163 v-else
133164 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-semibold transition-colors"
134- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
165+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
135166 :style =" { backgroundColor: 'var(--dd-success-muted)', color: 'var(--dd-success)', border: '1px solid var(--dd-success)' }"
136- :disabled =" isActionInProgress (selectedContainer)"
167+ :disabled =" isActionBlocked (selectedContainer)"
137168 aria-label =" Start container"
138169 @click =" startContainer(selectedContainer)" >
139170 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'play'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
140171 Start
141172 </AppButton >
142173 <AppButton size =" none" variant =" plain" weight =" none"
143174 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-semibold transition-colors"
144- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : 'dd-text-muted hover:dd-text'"
145- :disabled =" isActionInProgress (selectedContainer)"
175+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : 'dd-text-muted hover:dd-text'"
176+ :disabled =" isActionBlocked (selectedContainer)"
146177 aria-label =" Restart container"
147178 @click =" confirmRestart(selectedContainer)" >
148179 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'restart'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
149180 Restart
150181 </AppButton >
151182 <AppButton size =" none" variant =" plain" weight =" none"
152183 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-semibold transition-colors"
153- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : 'dd-text-muted hover:dd-text'"
154- :disabled =" isActionInProgress (selectedContainer)"
184+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : 'dd-text-muted hover:dd-text'"
185+ :disabled =" isActionBlocked (selectedContainer)"
155186 aria-label =" Scan container"
156187 @click =" scanContainer(selectedContainer)" >
157188 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'security'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
@@ -160,9 +191,9 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
160191 <AppButton size =" none" variant =" plain" weight =" none"
161192 v-if =" selectedContainer.newTag && selectedContainer.bouncer === 'blocked'"
162193 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-bold transition-colors"
163- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
194+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
164195 :style =" { backgroundColor: 'var(--dd-danger-muted)', color: 'var(--dd-danger)', border: '1px solid var(--dd-danger)' }"
165- :disabled =" isActionInProgress (selectedContainer)"
196+ :disabled =" isActionBlocked (selectedContainer)"
166197 aria-label =" Update blocked by security scan"
167198 @click =" confirmForceUpdate(selectedContainer)" >
168199 <AppIcon name =" lock" :size =" 12" />
@@ -171,19 +202,19 @@ function getStatusTone(container: { id?: unknown; name?: unknown; status?: strin
171202 <AppButton size =" none" variant =" plain" weight =" none"
172203 v-else-if =" selectedContainer.newTag"
173204 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-bold transition-colors"
174- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
205+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
175206 :style =" { backgroundColor: 'var(--dd-success-muted)', color: 'var(--dd-success)', border: '1px solid var(--dd-success)' }"
176- :disabled =" isActionInProgress (selectedContainer)"
207+ :disabled =" isActionBlocked (selectedContainer)"
177208 aria-label =" Update container"
178209 @click =" confirmUpdate(selectedContainer)" >
179210 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'cloud-download'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
180211 Update
181212 </AppButton >
182213 <AppButton size =" none" variant =" plain" weight =" none"
183214 class =" flex items-center gap-1.5 px-3 py-1.5 dd-rounded text-2xs-plus font-semibold transition-colors"
184- :class =" isActionInProgress (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
215+ :class =" isActionBlocked (selectedContainer) ? 'opacity-50 cursor-not-allowed' : ''"
185216 :style =" { backgroundColor: 'var(--dd-danger-muted)', color: 'var(--dd-danger)', border: '1px solid var(--dd-danger)' }"
186- :disabled =" isActionInProgress (selectedContainer)"
217+ :disabled =" isActionBlocked (selectedContainer)"
187218 aria-label =" Delete container"
188219 @click =" confirmDelete(selectedContainer)" >
189220 <AppIcon :name =" isActionInProgress(selectedContainer) ? 'spinner' : 'trash'" :size =" 12" :class =" isActionInProgress(selectedContainer) ? 'dd-spin' : ''" />
0 commit comments