@@ -1149,6 +1149,33 @@ export function Table({
11491149 [ filterOpen , effectiveFilter , handleToggleFilter ]
11501150 )
11511151
1152+ const runStatus =
1153+ embedded && ( selection . totalRunning > 0 || selection . hasActiveDispatch ) ? (
1154+ < RunStatusControl
1155+ running = { selection . totalRunning }
1156+ queueing = { ! selection . hasRunningCell }
1157+ onStopAll = { onStopAll }
1158+ isStopping = { cancelRunsMutation . isPending }
1159+ />
1160+ ) : null
1161+
1162+ const saveViewChip =
1163+ viewsEnabled && isViewDirty && userPermissions . canEdit ? (
1164+ < Chip onClick = { handleSaveView } disabled = { updateViewMutation . isPending } >
1165+ { activeView ? 'Save' : 'Save as view' }
1166+ </ Chip >
1167+ ) : null
1168+
1169+ /** Right-aligned slot. Left `undefined` when both are absent so the options bar
1170+ * doesn't render an empty flex row — a fragment would always read as truthy. */
1171+ const optionsTrailing =
1172+ runStatus || saveViewChip ? (
1173+ < >
1174+ { runStatus }
1175+ { saveViewChip }
1176+ </ >
1177+ ) : undefined
1178+
11521179 return (
11531180 < Resource >
11541181 { ! embedded && (
@@ -1182,33 +1209,23 @@ export function Table({
11821209 />
11831210 ) }
11841211 { /* Sort + filter render in both modes. In embedded (mothership) mode there's no
1185- Resource.Header, so the run/stop control rides in the options bar's `aside`
1186- slot, just left of filter/sort . */ }
1212+ Resource.Header, so the run/stop control rides in the options bar — pinned
1213+ right, opposite the menu cluster, next to Save . */ }
11871214 < Resource . Options
11881215 sort = { sortConfig }
11891216 filter = { filterConfig }
11901217 aside = {
1191- < >
1192- { viewsEnabled && (
1193- < ViewsMenu
1194- views = { views }
1195- activeViewId = { activeView ?. id ?? null }
1196- onSelect = { handleSelectView }
1197- onRename = { handleRenameView }
1198- onDelete = { handleDeleteView }
1199- onNewView = { handleNewView }
1200- canEdit = { userPermissions . canEdit }
1201- />
1202- ) }
1203- { embedded && ( selection . totalRunning > 0 || selection . hasActiveDispatch ) ? (
1204- < RunStatusControl
1205- running = { selection . totalRunning }
1206- queueing = { ! selection . hasRunningCell }
1207- onStopAll = { onStopAll }
1208- isStopping = { cancelRunsMutation . isPending }
1209- />
1210- ) : null }
1211- </ >
1218+ viewsEnabled ? (
1219+ < ViewsMenu
1220+ views = { views }
1221+ activeViewId = { activeView ?. id ?? null }
1222+ onSelect = { handleSelectView }
1223+ onRename = { handleRenameView }
1224+ onDelete = { handleDeleteView }
1225+ onNewView = { handleNewView }
1226+ canEdit = { userPermissions . canEdit }
1227+ />
1228+ ) : undefined
12121229 }
12131230 asideEnd = {
12141231 viewsEnabled ? (
@@ -1220,13 +1237,7 @@ export function Table({
12201237 />
12211238 ) : undefined
12221239 }
1223- trailing = {
1224- viewsEnabled && isViewDirty && userPermissions . canEdit ? (
1225- < Chip onClick = { handleSaveView } disabled = { updateViewMutation . isPending } >
1226- { activeView ? 'Save' : 'Save as view' }
1227- </ Chip >
1228- ) : undefined
1229- }
1240+ trailing = { optionsTrailing }
12301241 />
12311242 { filterOpen && (
12321243 < TableFilter
0 commit comments