mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-19 23:06:49 +00:00
feat(fleet): reapply Compose configuration without a version update (#1716)
* feat(fleet): reapply Compose configuration without a version update Add a distinct Fleet Reapply configuration path so Compose-managed nodes can recreate Sencho from the current on-disk project when already up to date, without pulling or rewriting the image reference. * fix(fleet): confirm remote reapply and close concurrent tracker race Require confirmation for remote compose reapply, and lock dispatch before the remote POST so a second request cannot overwrite a successful in-flight tracker. * fix(ui): icon-only Reapply control so Up to date badge can breathe Collapse the Node updates Reapply label into a tooltip so the status pill no longer wraps in the Status column. * feat(editor): Save & Reapply self-stack via fleet compose reapply (#1726) * feat(editor): Save & Reapply self-stack via fleet compose reapply Eligible admins can apply on-disk Compose edits to Sencho's own stack from the editor using the same confirm, dispatch, and reconnect path as Fleet Node Updates. * fix(editor): gate Save & Reapply label to self-stack only Ordinary stacks were labeled Save & Reapply whenever the node was reapply-eligible. Require the selected file to be the self-stack for the toolbar label and diff confirm CTA. * fix(ui): move compose diff action label helper out of dialog module Keep ComposeDiffPreviewDialog component-only so react-refresh Fast Refresh lint passes after the Save and reapply stacked merge.
This commit is contained in:
@@ -23,6 +23,9 @@ import { ThemeQuickSwitch } from './theme/ThemeQuickSwitch';
|
||||
import { useNotifications } from './EditorLayout/hooks/useNotifications';
|
||||
import { useContainerStats } from './EditorLayout/hooks/useContainerStats';
|
||||
import { useSidebarContextMenu } from './EditorLayout/hooks/useSidebarContextMenu';
|
||||
import { useActiveNodeReapplyEligibility } from './EditorLayout/hooks/useActiveNodeReapplyEligibility';
|
||||
import { resolveCanSaveAndReapply } from './EditorLayout/resolveCanSaveAndReapply';
|
||||
import { useComposeReapplyAction } from './FleetView/hooks/useComposeReapplyAction';
|
||||
import { NodeSwitcher } from './NodeSwitcher';
|
||||
import {
|
||||
GlobalCommandPalette,
|
||||
@@ -186,6 +189,12 @@ export default function EditorLayout() {
|
||||
createDialogOpen, setCreateDialogOpen,
|
||||
} = overlayState;
|
||||
|
||||
const { canReapply: canReapplyCompose } = useActiveNodeReapplyEligibility(activeNode?.id);
|
||||
const composeReapply = useComposeReapplyAction();
|
||||
const isSelfStackSelected = selectedFile ? stackSelfFlags[selectedFile] === true : false;
|
||||
// Ordinary stacks keep Save & Deploy even when the node supports compose reapply.
|
||||
const canSaveAndReapply = resolveCanSaveAndReapply(isAdmin, canReapplyCompose, isSelfStackSelected);
|
||||
|
||||
// Which mode the create dialog opens on (always empty after import tab removal).
|
||||
const [createDialogInitialMode, setCreateDialogInitialMode] = useState<CreateMode>('empty');
|
||||
const [adoptDialogOpen, setAdoptDialogOpen] = useState(false);
|
||||
@@ -292,6 +301,8 @@ export default function EditorLayout() {
|
||||
canOfferVolumeRemoval,
|
||||
onDeletedOpenStack: () => onDeletedOpenStackRef.current(),
|
||||
removeNotificationsForStack,
|
||||
isAdmin,
|
||||
canReapplyCompose,
|
||||
});
|
||||
|
||||
// Wire the ref now that stackActions is available
|
||||
@@ -692,7 +703,8 @@ export default function EditorLayout() {
|
||||
requestDeleteStack={stackActions.requestDeleteStack}
|
||||
requestTakeDownStack={stackActions.requestTakeDownStack}
|
||||
showTakeDown={selectedFile ? stackActions.getStackMenuVisibility(selectedFile).showTakeDown : false}
|
||||
isSelfStack={selectedFile ? stackSelfFlags[selectedFile] === true : false}
|
||||
isSelfStack={isSelfStackSelected}
|
||||
canSaveAndReapply={canSaveAndReapply}
|
||||
recoveryResult={selectedFile ? lastActionResult[selectedFile] : undefined}
|
||||
onRefreshState={async () => {
|
||||
if (!selectedFile) return;
|
||||
@@ -1050,6 +1062,8 @@ export default function EditorLayout() {
|
||||
gitSourceOpen={gitSourceOpen}
|
||||
setGitSourceOpen={setGitSourceOpen}
|
||||
canSelfUpdate={hasCapability('self-update')}
|
||||
composeReapply={composeReapply}
|
||||
canSaveAndReapply={canSaveAndReapply}
|
||||
canOfferVolumeRemoval={canOfferVolumeRemoval}
|
||||
onOpenFleetNodeUpdates={() => {
|
||||
if (isMobile) {
|
||||
|
||||
Reference in New Issue
Block a user