@drawnagency/primitives 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/sections/register-schemas.d.ts.map +1 -1
- package/dist/components/sections/register.d.ts.map +1 -1
- package/dist/components/shell/BuildStatusIndicator.d.ts +1 -3
- package/dist/components/shell/BuildStatusIndicator.d.ts.map +1 -1
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/hooks/useBuildStatus.d.ts +0 -2
- package/dist/hooks/useBuildStatus.d.ts.map +1 -1
- package/dist/hooks/useEditorPublish.d.ts +2 -1
- package/dist/hooks/useEditorPublish.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/sections/register-schemas.ts +6 -4
- package/src/components/sections/register.ts +6 -4
- package/src/components/shell/BuildStatusIndicator.tsx +30 -38
- package/src/components/shell/EditorShell.tsx +10 -19
- package/src/hooks/useBuildStatus.ts +1 -30
- package/src/hooks/useEditorPublish.ts +13 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-schemas.d.ts","sourceRoot":"","sources":["../../../src/components/sections/register-schemas.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"register-schemas.d.ts","sourceRoot":"","sources":["../../../src/components/sections/register-schemas.ts"],"names":[],"mappings":"AAoBA,wBAAgB,uBAAuB,IAAI,MAAM,CAMhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/components/sections/register.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/components/sections/register.ts"],"names":[],"mappings":"AAoBA,wBAAgB,wBAAwB,IAAI,MAAM,CAMjD"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
interface BuildStatusIndicatorProps {
|
|
2
2
|
state: "idle" | "building" | "ready" | "error";
|
|
3
3
|
deployUrl: string | null;
|
|
4
|
-
visible: boolean;
|
|
5
|
-
onDismiss: () => void;
|
|
6
4
|
}
|
|
7
|
-
export declare function BuildStatusIndicator({ state, deployUrl,
|
|
5
|
+
export declare function BuildStatusIndicator({ state, deployUrl, }: BuildStatusIndicatorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
6
|
export {};
|
|
9
7
|
//# sourceMappingURL=BuildStatusIndicator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BuildStatusIndicator.d.ts","sourceRoot":"","sources":["../../../src/components/shell/BuildStatusIndicator.tsx"],"names":[],"mappings":"AAGA,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"BuildStatusIndicator.d.ts","sourceRoot":"","sources":["../../../src/components/shell/BuildStatusIndicator.tsx"],"names":[],"mappings":"AAGA,UAAU,yBAAyB;IACjC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA6BD,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,SAAS,GACV,EAAE,yBAAyB,kDAoB3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAmC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAYjD,OAAO,sBAAsB,CAAC;AAmC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAcxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAukBP"}
|
|
@@ -2,8 +2,6 @@ type BuildState = "idle" | "building" | "ready" | "error";
|
|
|
2
2
|
interface BuildStatusResult {
|
|
3
3
|
state: BuildState;
|
|
4
4
|
deployUrl: string | null;
|
|
5
|
-
visible: boolean;
|
|
6
|
-
dismiss: () => void;
|
|
7
5
|
startTracking: () => void;
|
|
8
6
|
}
|
|
9
7
|
export declare function useBuildStatus(): BuildStatusResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,
|
|
1
|
+
{"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAS1D,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAID,wBAAgB,cAAc,IAAI,iBAAiB,CA0FlD"}
|
|
@@ -18,8 +18,9 @@ interface PublishDeps {
|
|
|
18
18
|
onShasUpdated: (savedSha: string | null, mainSha: string | null) => void;
|
|
19
19
|
onPublishComplete?: () => void;
|
|
20
20
|
}
|
|
21
|
+
export type PublishAction = "idle" | "saving" | "publishing";
|
|
21
22
|
export declare function useEditorPublish({ flushNow, cancelPendingFlush, isConfigDirty, clearConfigDirty, siteIndexRef, siteConfig, sections, deletedSectionIds, onSuccess, mediaManifest, pendingMediaItems, pendingMediaDeletions, onMediaPublished, onShasUpdated, onPublishComplete, }: PublishDeps): {
|
|
22
|
-
|
|
23
|
+
publishAction: PublishAction;
|
|
23
24
|
publishFeedback: string | null;
|
|
24
25
|
handleSave: () => Promise<void>;
|
|
25
26
|
handlePublish: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditorPublish.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorPublish.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAe/D,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtF,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC;AASD,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,EAAE,WAAW;;;;;;EAuSb"}
|
|
1
|
+
{"version":3,"file":"useEditorPublish.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorPublish.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAe/D,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtF,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC;AASD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE7D,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,EAAE,WAAW;;;;;;EAuSb"}
|
package/package.json
CHANGED
|
@@ -15,11 +15,13 @@ const allDefs = [linkHeading, subHeading, subSubHeading, prose, mediaGrid,
|
|
|
15
15
|
splitContent, button, colors, doDontList, doDontImageGrid, iconList,
|
|
16
16
|
];
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
allDefs.forEach((def) => registerSchema(def.type, def.schema));
|
|
19
19
|
|
|
20
|
+
let _ensured = false;
|
|
20
21
|
export function ensureSchemasRegistered(): number {
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if (!_ensured) {
|
|
23
|
+
allDefs.forEach((def) => registerSchema(def.type, def.schema));
|
|
24
|
+
_ensured = true;
|
|
25
|
+
}
|
|
24
26
|
return allDefs.length;
|
|
25
27
|
}
|
|
@@ -15,11 +15,13 @@ const allDefs = [linkHeading, subHeading, subSubHeading, prose, mediaGrid,
|
|
|
15
15
|
splitContent, button, colors, doDontList, doDontImageGrid, iconList,
|
|
16
16
|
];
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
allDefs.forEach(registerSection);
|
|
19
19
|
|
|
20
|
+
let _ensured = false;
|
|
20
21
|
export function ensureSectionsRegistered(): number {
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if (!_ensured) {
|
|
23
|
+
allDefs.forEach(registerSection);
|
|
24
|
+
_ensured = true;
|
|
25
|
+
}
|
|
24
26
|
return allDefs.length;
|
|
25
27
|
}
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
3
|
|
|
4
4
|
interface BuildStatusIndicatorProps {
|
|
5
5
|
state: "idle" | "building" | "ready" | "error";
|
|
6
6
|
deployUrl: string | null;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function LoadingEllipsis() {
|
|
10
|
+
const [dots, setDots] = useState(0);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const id = setInterval(() => setDots((d) => (d + 1) % 4), 400);
|
|
13
|
+
return () => clearInterval(id);
|
|
14
|
+
}, []);
|
|
15
|
+
return <>{".".repeat(dots)}</>;
|
|
9
16
|
}
|
|
10
17
|
|
|
11
18
|
const stateConfig = {
|
|
12
19
|
building: {
|
|
13
|
-
label: "
|
|
14
|
-
className: "border-orange-500 text-orange-600
|
|
20
|
+
label: "Publishing",
|
|
21
|
+
className: "border-orange-500 text-orange-600",
|
|
15
22
|
dotClassName: "bg-orange-500 animate-pulse",
|
|
16
23
|
},
|
|
17
24
|
ready: {
|
|
18
|
-
label: "
|
|
19
|
-
className: "border-green-600 text-green-600
|
|
25
|
+
label: "Published",
|
|
26
|
+
className: "border-green-600 text-green-600",
|
|
20
27
|
dotClassName: "bg-green-600",
|
|
21
28
|
},
|
|
22
29
|
error: {
|
|
23
|
-
label: "
|
|
24
|
-
className: "border-red-600 text-red-600
|
|
30
|
+
label: "Publish failed",
|
|
31
|
+
className: "border-red-600 text-red-600",
|
|
25
32
|
dotClassName: "bg-red-600",
|
|
26
33
|
},
|
|
27
34
|
} as const;
|
|
@@ -29,39 +36,24 @@ const stateConfig = {
|
|
|
29
36
|
export function BuildStatusIndicator({
|
|
30
37
|
state,
|
|
31
38
|
deployUrl,
|
|
32
|
-
visible,
|
|
33
|
-
onDismiss,
|
|
34
39
|
}: BuildStatusIndicatorProps) {
|
|
35
|
-
if (
|
|
40
|
+
if (state === "idle") return null;
|
|
36
41
|
|
|
37
42
|
const config = stateConfig[state];
|
|
38
43
|
|
|
39
44
|
return (
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</a>
|
|
54
|
-
<button
|
|
55
|
-
type="button"
|
|
56
|
-
onClick={onDismiss}
|
|
57
|
-
aria-label="Dismiss build status"
|
|
58
|
-
className={cn(
|
|
59
|
-
"inline-flex items-center rounded-r border border-l-0 px-1.5 py-1.5 transition-colors cursor-pointer",
|
|
60
|
-
config.className,
|
|
61
|
-
)}
|
|
62
|
-
>
|
|
63
|
-
<X size={12} />
|
|
64
|
-
</button>
|
|
65
|
-
</span>
|
|
45
|
+
<a
|
|
46
|
+
href={deployUrl ?? "#"}
|
|
47
|
+
target="_blank"
|
|
48
|
+
rel="noopener noreferrer"
|
|
49
|
+
aria-label={config.label}
|
|
50
|
+
className={cn(
|
|
51
|
+
"inline-flex items-center gap-1.5 rounded px-3 py-1.5 text-xs font-medium border transition-colors",
|
|
52
|
+
config.className,
|
|
53
|
+
)}
|
|
54
|
+
>
|
|
55
|
+
<span className={cn("h-1.5 w-1.5 rounded-full", config.dotClassName)} />
|
|
56
|
+
{config.label}{state === "building" && <LoadingEllipsis />}
|
|
57
|
+
</a>
|
|
66
58
|
);
|
|
67
59
|
}
|
|
@@ -127,7 +127,7 @@ export default function EditorShell({
|
|
|
127
127
|
|
|
128
128
|
const buildStatus = useBuildStatus();
|
|
129
129
|
|
|
130
|
-
const {
|
|
130
|
+
const { publishAction, publishFeedback, handleSave, handlePublish, handleSaveAndPublish } = useEditorPublish({
|
|
131
131
|
flushNow: persistence.flushNow,
|
|
132
132
|
cancelPendingFlush: persistence.cancelPendingFlush,
|
|
133
133
|
isConfigDirty: persistence.isConfigDirty,
|
|
@@ -574,7 +574,7 @@ export default function EditorShell({
|
|
|
574
574
|
<EditorToolbar
|
|
575
575
|
buttonState={buttonState}
|
|
576
576
|
localChangesExist={localChangesExist}
|
|
577
|
-
|
|
577
|
+
publishAction={publishAction}
|
|
578
578
|
publishFeedback={publishFeedback}
|
|
579
579
|
onSave={handleSave}
|
|
580
580
|
onPublish={handlePublish}
|
|
@@ -588,8 +588,6 @@ export default function EditorShell({
|
|
|
588
588
|
processingItems={mediaPipeline.processingItems}
|
|
589
589
|
buildState={buildStatus.state}
|
|
590
590
|
buildDeployUrl={buildStatus.deployUrl}
|
|
591
|
-
buildVisible={buildStatus.visible}
|
|
592
|
-
onBuildDismiss={buildStatus.dismiss}
|
|
593
591
|
/>
|
|
594
592
|
|
|
595
593
|
<EditorContent
|
|
@@ -597,7 +595,7 @@ export default function EditorShell({
|
|
|
597
595
|
audiences={audiences}
|
|
598
596
|
dirtySectionIds={dirtySectionIds}
|
|
599
597
|
deletedSections={deletedSections}
|
|
600
|
-
isPublishing={
|
|
598
|
+
isPublishing={publishAction !== "idle"}
|
|
601
599
|
onSectionChange={onSectionChange}
|
|
602
600
|
onAddSection={onAddSection}
|
|
603
601
|
onDeleteSection={onDeleteSection}
|
|
@@ -879,7 +877,7 @@ function GlobalModal() {
|
|
|
879
877
|
function EditorToolbar({
|
|
880
878
|
buttonState,
|
|
881
879
|
localChangesExist,
|
|
882
|
-
|
|
880
|
+
publishAction,
|
|
883
881
|
publishFeedback,
|
|
884
882
|
onSave,
|
|
885
883
|
onPublish,
|
|
@@ -890,12 +888,10 @@ function EditorToolbar({
|
|
|
890
888
|
processingItems,
|
|
891
889
|
buildState,
|
|
892
890
|
buildDeployUrl,
|
|
893
|
-
buildVisible,
|
|
894
|
-
onBuildDismiss,
|
|
895
891
|
}: {
|
|
896
892
|
buttonState: "synced" | "publish" | "saveAndPublish";
|
|
897
893
|
localChangesExist: boolean;
|
|
898
|
-
|
|
894
|
+
publishAction: "idle" | "saving" | "publishing";
|
|
899
895
|
publishFeedback: string | null;
|
|
900
896
|
onSave: () => void;
|
|
901
897
|
onPublish: () => void;
|
|
@@ -906,8 +902,6 @@ function EditorToolbar({
|
|
|
906
902
|
processingItems: QueueItem[];
|
|
907
903
|
buildState: "idle" | "building" | "ready" | "error";
|
|
908
904
|
buildDeployUrl: string | null;
|
|
909
|
-
buildVisible: boolean;
|
|
910
|
-
onBuildDismiss: () => void;
|
|
911
905
|
}) {
|
|
912
906
|
const { isEditMode, viewBranch, setViewBranch, toggleEditMode } = useEditorContext();
|
|
913
907
|
|
|
@@ -919,7 +913,7 @@ function EditorToolbar({
|
|
|
919
913
|
{publishFeedback && (
|
|
920
914
|
<span className={cn(
|
|
921
915
|
"text-xs font-medium",
|
|
922
|
-
publishFeedback === "
|
|
916
|
+
publishFeedback === "Saved"
|
|
923
917
|
? "text-green-600"
|
|
924
918
|
: "text-red-600",
|
|
925
919
|
)}>
|
|
@@ -930,8 +924,8 @@ function EditorToolbar({
|
|
|
930
924
|
<SplitButton
|
|
931
925
|
label="Save & Publish"
|
|
932
926
|
onClick={onSaveAndPublish}
|
|
933
|
-
isLoading={
|
|
934
|
-
loadingLabel="Publishing..."
|
|
927
|
+
isLoading={publishAction !== "idle"}
|
|
928
|
+
loadingLabel={publishAction === "saving" ? "Saving..." : "Publishing..."}
|
|
935
929
|
options={[{ label: "Save", onClick: onSave }]}
|
|
936
930
|
/>
|
|
937
931
|
)}
|
|
@@ -939,7 +933,7 @@ function EditorToolbar({
|
|
|
939
933
|
<SplitButton
|
|
940
934
|
label="Publish"
|
|
941
935
|
onClick={onPublish}
|
|
942
|
-
isLoading={
|
|
936
|
+
isLoading={publishAction !== "idle"}
|
|
943
937
|
loadingLabel="Publishing..."
|
|
944
938
|
options={[]}
|
|
945
939
|
/>
|
|
@@ -952,12 +946,11 @@ function EditorToolbar({
|
|
|
952
946
|
options={[]}
|
|
953
947
|
/>
|
|
954
948
|
)}
|
|
955
|
-
{localChangesExist &&
|
|
949
|
+
{localChangesExist && publishAction === "idle" && (
|
|
956
950
|
<Button
|
|
957
951
|
type="button"
|
|
958
952
|
variant="destructive"
|
|
959
953
|
onClick={onDiscardClick}
|
|
960
|
-
disabled={isPublishing}
|
|
961
954
|
>
|
|
962
955
|
Discard Changes
|
|
963
956
|
</Button>
|
|
@@ -965,8 +958,6 @@ function EditorToolbar({
|
|
|
965
958
|
<BuildStatusIndicator
|
|
966
959
|
state={buildState}
|
|
967
960
|
deployUrl={buildDeployUrl}
|
|
968
|
-
visible={buildVisible}
|
|
969
|
-
onDismiss={onBuildDismiss}
|
|
970
961
|
/>
|
|
971
962
|
</div>
|
|
972
963
|
<div className="flex items-center gap-2">
|
|
@@ -12,20 +12,15 @@ interface BuildStatusResponse {
|
|
|
12
12
|
interface BuildStatusResult {
|
|
13
13
|
state: BuildState;
|
|
14
14
|
deployUrl: string | null;
|
|
15
|
-
visible: boolean;
|
|
16
|
-
dismiss: () => void;
|
|
17
15
|
startTracking: () => void;
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
const POLL_INTERVAL = 5000;
|
|
21
|
-
const AUTO_DISMISS_DELAY = 10000;
|
|
22
19
|
|
|
23
20
|
export function useBuildStatus(): BuildStatusResult {
|
|
24
21
|
const [state, setState] = useState<BuildState>("idle");
|
|
25
22
|
const [deployUrl, setDeployUrl] = useState<string | null>(null);
|
|
26
|
-
const [dismissed, setDismissed] = useState(false);
|
|
27
23
|
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
28
|
-
const dismissRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
29
24
|
const isPolling = useRef(false);
|
|
30
25
|
|
|
31
26
|
const stopPolling = useCallback(() => {
|
|
@@ -65,16 +60,9 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
65
60
|
|
|
66
61
|
setState(data.state);
|
|
67
62
|
setDeployUrl(data.deployUrl);
|
|
68
|
-
setDismissed(false);
|
|
69
63
|
|
|
70
64
|
if (data.state === "ready" || data.state === "error") {
|
|
71
65
|
stopPolling();
|
|
72
|
-
|
|
73
|
-
if (data.state === "ready") {
|
|
74
|
-
dismissRef.current = setTimeout(() => {
|
|
75
|
-
setDismissed(true);
|
|
76
|
-
}, AUTO_DISMISS_DELAY);
|
|
77
|
-
}
|
|
78
66
|
}
|
|
79
67
|
},
|
|
80
68
|
[stopPolling],
|
|
@@ -109,31 +97,14 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
109
97
|
return () => {
|
|
110
98
|
cancelled = true;
|
|
111
99
|
stopPolling();
|
|
112
|
-
if (dismissRef.current) clearTimeout(dismissRef.current);
|
|
113
100
|
};
|
|
114
101
|
}, [fetchStatus, handleStatusUpdate, startPolling, stopPolling]);
|
|
115
102
|
|
|
116
|
-
const dismiss = useCallback(() => {
|
|
117
|
-
setDismissed(true);
|
|
118
|
-
stopPolling();
|
|
119
|
-
if (dismissRef.current) {
|
|
120
|
-
clearTimeout(dismissRef.current);
|
|
121
|
-
dismissRef.current = null;
|
|
122
|
-
}
|
|
123
|
-
}, [stopPolling]);
|
|
124
|
-
|
|
125
103
|
const startTracking = useCallback(() => {
|
|
126
104
|
setState("building");
|
|
127
105
|
setDeployUrl(null);
|
|
128
|
-
setDismissed(false);
|
|
129
|
-
if (dismissRef.current) {
|
|
130
|
-
clearTimeout(dismissRef.current);
|
|
131
|
-
dismissRef.current = null;
|
|
132
|
-
}
|
|
133
106
|
startPolling();
|
|
134
107
|
}, [startPolling]);
|
|
135
108
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return { state, deployUrl, visible, dismiss, startTracking };
|
|
109
|
+
return { state, deployUrl, startTracking };
|
|
139
110
|
}
|
|
@@ -41,6 +41,8 @@ interface GatheredMedia {
|
|
|
41
41
|
hasMediaChanges: boolean;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export type PublishAction = "idle" | "saving" | "publishing";
|
|
45
|
+
|
|
44
46
|
export function useEditorPublish({
|
|
45
47
|
flushNow,
|
|
46
48
|
cancelPendingFlush,
|
|
@@ -58,7 +60,7 @@ export function useEditorPublish({
|
|
|
58
60
|
onShasUpdated,
|
|
59
61
|
onPublishComplete,
|
|
60
62
|
}: PublishDeps) {
|
|
61
|
-
const [
|
|
63
|
+
const [publishAction, setPublishAction] = useState<PublishAction>("idle");
|
|
62
64
|
const [publishFeedback, setPublishFeedback] = useState<string | null>(null);
|
|
63
65
|
const feedbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
64
66
|
|
|
@@ -136,7 +138,7 @@ export function useEditorPublish({
|
|
|
136
138
|
const handleSave = useCallback(async () => {
|
|
137
139
|
if (!siteConfig) return;
|
|
138
140
|
|
|
139
|
-
|
|
141
|
+
setPublishAction("saving");
|
|
140
142
|
setPublishFeedback(null);
|
|
141
143
|
|
|
142
144
|
try {
|
|
@@ -147,7 +149,7 @@ export function useEditorPublish({
|
|
|
147
149
|
const hasMediaChanges = pendingMediaItems.length > 0 || pendingMediaDeletions.length > 0;
|
|
148
150
|
const hasDeletedSections = (deletedSectionIds?.length ?? 0) > 0;
|
|
149
151
|
if (!hasChanges && !isConfigDirty() && !hasMediaChanges && !hasDeletedSections) {
|
|
150
|
-
|
|
152
|
+
setPublishAction("idle");
|
|
151
153
|
return;
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -216,12 +218,12 @@ export function useEditorPublish({
|
|
|
216
218
|
console.error("Save failed:", error);
|
|
217
219
|
showFeedback("Save failed", 5000);
|
|
218
220
|
} finally {
|
|
219
|
-
|
|
221
|
+
setPublishAction("idle");
|
|
220
222
|
}
|
|
221
223
|
}, [flushNow, cancelPendingFlush, isConfigDirty, clearConfigDirty, siteIndexRef, siteConfig, sections, deletedSectionIds, onSuccess, mediaManifest, pendingMediaItems, pendingMediaDeletions, onMediaPublished, onShasUpdated, showFeedback]);
|
|
222
224
|
|
|
223
225
|
const handlePublish = useCallback(async () => {
|
|
224
|
-
|
|
226
|
+
setPublishAction("publishing");
|
|
225
227
|
setPublishFeedback(null);
|
|
226
228
|
|
|
227
229
|
try {
|
|
@@ -238,20 +240,19 @@ export function useEditorPublish({
|
|
|
238
240
|
const { sha } = await response.json();
|
|
239
241
|
|
|
240
242
|
onShasUpdated(null, sha);
|
|
241
|
-
showFeedback("Published", 3000);
|
|
242
243
|
onPublishComplete?.();
|
|
243
244
|
} catch (error) {
|
|
244
245
|
console.error("Publish failed:", error);
|
|
245
246
|
showFeedback("Publish failed", 5000);
|
|
246
247
|
} finally {
|
|
247
|
-
|
|
248
|
+
setPublishAction("idle");
|
|
248
249
|
}
|
|
249
250
|
}, [onShasUpdated, showFeedback, onPublishComplete]);
|
|
250
251
|
|
|
251
252
|
const handleSaveAndPublish = useCallback(async () => {
|
|
252
253
|
if (!siteConfig) return;
|
|
253
254
|
|
|
254
|
-
|
|
255
|
+
setPublishAction("saving");
|
|
255
256
|
setPublishFeedback(null);
|
|
256
257
|
|
|
257
258
|
try {
|
|
@@ -316,6 +317,8 @@ export function useEditorPublish({
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
|
|
320
|
+
setPublishAction("publishing");
|
|
321
|
+
|
|
319
322
|
const publishResponse = await fetch("/api/publish", {
|
|
320
323
|
method: "POST",
|
|
321
324
|
headers: { "Content-Type": "application/json" },
|
|
@@ -341,15 +344,14 @@ export function useEditorPublish({
|
|
|
341
344
|
}
|
|
342
345
|
|
|
343
346
|
onShasUpdated(null, sha);
|
|
344
|
-
showFeedback("Published", 3000);
|
|
345
347
|
onPublishComplete?.();
|
|
346
348
|
} catch (error) {
|
|
347
349
|
console.error("Publish failed:", error);
|
|
348
350
|
showFeedback("Publish failed", 5000);
|
|
349
351
|
} finally {
|
|
350
|
-
|
|
352
|
+
setPublishAction("idle");
|
|
351
353
|
}
|
|
352
354
|
}, [flushNow, cancelPendingFlush, isConfigDirty, clearConfigDirty, siteIndexRef, siteConfig, sections, deletedSectionIds, onSuccess, mediaManifest, pendingMediaItems, pendingMediaDeletions, onMediaPublished, onShasUpdated, showFeedback, onPublishComplete]);
|
|
353
355
|
|
|
354
|
-
return {
|
|
356
|
+
return { publishAction, publishFeedback, handleSave, handlePublish, handleSaveAndPublish };
|
|
355
357
|
}
|