diff --git a/ui/src/pages/AppsTab/AppDeploymentPage/PrimaryActionButton.tsx b/ui/src/pages/AppsTab/AppDeploymentPage/PrimaryActionButton.tsx
new file mode 100644
index 00000000..ef4e9ac7
--- /dev/null
+++ b/ui/src/pages/AppsTab/AppDeploymentPage/PrimaryActionButton.tsx
@@ -0,0 +1,34 @@
+import { Button } from '@cameleer/design-system';
+
+export type PrimaryActionMode = 'save' | 'redeploy' | 'deploying';
+
+interface Props {
+ mode: PrimaryActionMode;
+ enabled: boolean;
+ onClick: () => void;
+}
+
+export function PrimaryActionButton({ mode, enabled, onClick }: Props) {
+ if (mode === 'deploying') {
+ return ;
+ }
+ if (mode === 'redeploy') {
+ return ;
+ }
+ return ;
+}
+
+export function computeMode({
+ deploymentInProgress,
+ hasLocalEdits,
+ serverDirtyAgainstDeploy,
+}: {
+ deploymentInProgress: boolean;
+ hasLocalEdits: boolean;
+ serverDirtyAgainstDeploy: boolean;
+}): PrimaryActionMode {
+ if (deploymentInProgress) return 'deploying';
+ if (hasLocalEdits) return 'save';
+ if (serverDirtyAgainstDeploy) return 'redeploy';
+ return 'save';
+}