mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-10-24 20:17:07 +09:00
refactor: simplify publish progress state
This commit is contained in:
1 parent
1b532637a7
commit
3d54f6c775
5 files changed
+104
-196
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { useStore } from "@nanostores/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Flex,
|
||||
Tooltip,
|
||||
@@ -50,35 +50,28 @@ export const DomainCheckbox = (props: DomainCheckboxProps) => {
|
||||
const { allowStagingPublish, canPublishToStagingOnly } =
|
||||
useStore($permissions);
|
||||
const project = useStore($project);
|
||||
const [selection, setSelection] = useState<{
|
||||
buildId: string | undefined;
|
||||
validatedDomains?: readonly string[];
|
||||
checked: boolean;
|
||||
}>({
|
||||
buildId: props.buildId,
|
||||
validatedDomains: props.validatedDomains,
|
||||
checked:
|
||||
props.validatedDomains?.includes(props.domain) ??
|
||||
props.defaultChecked ??
|
||||
false,
|
||||
});
|
||||
const restoredChecked =
|
||||
props.validatedDomains?.includes(props.domain) ??
|
||||
props.defaultChecked ??
|
||||
false;
|
||||
const [selected, setSelected] = useState(restoredChecked);
|
||||
const previous = useRef({
|
||||
buildId: props.buildId,
|
||||
validatedDomains: props.validatedDomains,
|
||||
});
|
||||
const hasNewValidation =
|
||||
props.validatedDomains !== undefined &&
|
||||
selection.validatedDomains !== props.validatedDomains;
|
||||
const hasNewBuild = selection.buildId !== props.buildId;
|
||||
previous.current.validatedDomains !== props.validatedDomains;
|
||||
const hasNewBuild = previous.current.buildId !== props.buildId;
|
||||
|
||||
useEffect(() => {
|
||||
if (hasNewValidation || hasNewBuild) {
|
||||
setSelection({
|
||||
buildId: props.buildId,
|
||||
validatedDomains: props.validatedDomains,
|
||||
checked: restoredChecked,
|
||||
});
|
||||
setSelected(restoredChecked);
|
||||
}
|
||||
previous.current = {
|
||||
buildId: props.buildId,
|
||||
validatedDomains: props.validatedDomains,
|
||||
};
|
||||
}, [
|
||||
hasNewValidation,
|
||||
hasNewBuild,
|
||||
@@ -139,7 +132,7 @@ export const DomainCheckbox = (props: DomainCheckboxProps) => {
|
||||
? false
|
||||
: hasNewValidation || hasNewBuild
|
||||
? restoredChecked
|
||||
: selection.checked;
|
||||
: selected;
|
||||
const disabled = isRestricted ? true : props.disabled;
|
||||
|
||||
const hideDomainCheckbox =
|
||||
@@ -154,13 +147,7 @@ export const DomainCheckbox = (props: DomainCheckboxProps) => {
|
||||
disabled={disabled}
|
||||
key={props.buildId ?? "-"}
|
||||
checked={hideDomainCheckbox || checked}
|
||||
onCheckedChange={(value) =>
|
||||
setSelection({
|
||||
buildId: props.buildId,
|
||||
validatedDomains: props.validatedDomains,
|
||||
checked: value === true,
|
||||
})
|
||||
}
|
||||
onCheckedChange={(value) => setSelected(value === true)}
|
||||
css={{ pointerEvents: "all" }}
|
||||
name={domainToPublishName}
|
||||
value={props.domain}
|
||||
|
||||
@@ -142,11 +142,12 @@ test("clears the validation result when the publish popover closes", async () =>
|
||||
|
||||
test.each([
|
||||
{ destination: "none" as const, expectedToasts: 1 },
|
||||
{ destination: "none" as const, reopen: true, expectedToasts: 0 },
|
||||
{ destination: "export" as const, expectedToasts: 1 },
|
||||
{ destination: "publish" as const, expectedToasts: 0 },
|
||||
])(
|
||||
"reports validation success after switching to $destination",
|
||||
async ({ destination, expectedToasts }) => {
|
||||
"reports validation success after switching to $destination (reopen: $reopen)",
|
||||
async ({ destination, reopen, expectedToasts }) => {
|
||||
const successToast = vi
|
||||
.spyOn(toast, "success")
|
||||
.mockImplementation(() => "");
|
||||
@@ -182,6 +183,9 @@ test.each([
|
||||
<button type="button" onClick={() => setDialog(destination)}>
|
||||
Switch
|
||||
</button>
|
||||
<button type="button" onClick={() => setDialog("publish")}>
|
||||
Reopen
|
||||
</button>
|
||||
<output>{validationState}</output>
|
||||
</TooltipProvider>
|
||||
);
|
||||
@@ -191,9 +195,13 @@ test.each([
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
act(() => root?.render(<Harness />));
|
||||
const [validate, , switchDialog] = container.querySelectorAll("button");
|
||||
const [validate, , switchDialog, reopenDialog] =
|
||||
container.querySelectorAll("button");
|
||||
act(() => validate.click());
|
||||
act(() => switchDialog.click());
|
||||
if (reopen) {
|
||||
act(() => reopenDialog.click());
|
||||
}
|
||||
await act(async () => {
|
||||
finishValidation();
|
||||
await validation;
|
||||
@@ -201,7 +209,7 @@ test.each([
|
||||
|
||||
expect(successToast).toHaveBeenCalledTimes(expectedToasts);
|
||||
expect(container.querySelector("output")?.textContent).toBe(
|
||||
destination === "publish" ? "passed" : "idle"
|
||||
destination === "publish" || reopen ? "passed" : "idle"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -9,33 +9,24 @@ export const usePublishValidationState = (
|
||||
) => {
|
||||
const [validationState, setValidationState] =
|
||||
useState<PublishValidationState>("idle");
|
||||
const session = useRef(0);
|
||||
const sessionAtRender = session.current;
|
||||
const dialogRef = useRef(dialog);
|
||||
dialogRef.current = dialog;
|
||||
|
||||
const reset = useCallback(() => {
|
||||
session.current += 1;
|
||||
setValidationState("idle");
|
||||
}, []);
|
||||
|
||||
const update = useCallback(
|
||||
(state: PublishValidationState) => {
|
||||
if (state === "passed" && dialogRef.current !== "publish") {
|
||||
toast.success("Validation passed. Ready to publish.", {
|
||||
duration: Number.POSITIVE_INFINITY,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (
|
||||
dialogRef.current === "publish" &&
|
||||
session.current === sessionAtRender
|
||||
) {
|
||||
setValidationState(state);
|
||||
}
|
||||
},
|
||||
[sessionAtRender]
|
||||
);
|
||||
const update = useCallback((state: PublishValidationState) => {
|
||||
if (state === "passed" && dialogRef.current !== "publish") {
|
||||
toast.success("Validation passed. Ready to publish.", {
|
||||
duration: Number.POSITIVE_INFINITY,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (dialogRef.current === "publish") {
|
||||
setValidationState(state);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (dialog !== "publish") {
|
||||
|
||||
@@ -13,7 +13,6 @@ import { PublishValidationResults } from "./publish-validation-results";
|
||||
const {
|
||||
usePublishProgress,
|
||||
waitForPublishStatus,
|
||||
waitForOwnedPublishStatus,
|
||||
refreshUntilSuccess,
|
||||
useManualValidationFindings,
|
||||
getRefreshedProject,
|
||||
@@ -378,11 +377,15 @@ test("an old poll cannot update a newly mounted copy of the same project", async
|
||||
const query = new Promise<{ success: true; project: Project }>((resolve) => {
|
||||
finishQuery = resolve;
|
||||
});
|
||||
const polling = waitForOwnedPublishStatus({
|
||||
projectId: "project",
|
||||
isCurrentProject: progress!.isCurrentProject,
|
||||
query: () => query,
|
||||
});
|
||||
const polling = waitForPublishStatus(
|
||||
() =>
|
||||
getRefreshedProject({
|
||||
projectId: "project",
|
||||
isCurrent: progress!.isCurrentProject,
|
||||
query: () => query,
|
||||
}),
|
||||
progress!.isCurrentProject
|
||||
);
|
||||
|
||||
act(() => root?.unmount());
|
||||
$project.set({ id: "another-project" } as Project);
|
||||
@@ -503,7 +506,7 @@ test("a rejected publish request shows an inline error while the dialog is open"
|
||||
>
|
||||
Start
|
||||
</button>
|
||||
<output>{progress.requestError}</output>
|
||||
<output>{progress.publishError}</output>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -538,7 +541,7 @@ test("starting validation clears a previous request failure", async () => {
|
||||
Publish
|
||||
</button>
|
||||
<button onClick={progress.clearErrors}>Validate</button>
|
||||
<output>{progress.publishError ?? progress.requestError}</output>
|
||||
<output>{progress.publishError}</output>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -570,7 +573,7 @@ test("a rejected publish request shows a toast after the dialog closes", async (
|
||||
return (
|
||||
<>
|
||||
<button onClick={() => progress.start(() => publish)}>Start</button>
|
||||
<output>{progress.requestError}</output>
|
||||
<output>{progress.publishError}</output>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -621,7 +624,7 @@ test("a rejected publish request appears in the panel reopened before rejection"
|
||||
>
|
||||
Reopen
|
||||
</button>
|
||||
{isOpen && <output>{progress.requestError}</output>}
|
||||
{isOpen && <output>{progress.publishError}</output>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -868,7 +871,7 @@ test("a newer build clears a recovered transport error", async () => {
|
||||
>
|
||||
Refresh
|
||||
</button>
|
||||
<output>{progress.requestError}</output>
|
||||
<output>{progress.publishError}</output>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -923,7 +926,7 @@ test("a recovered failed build replaces a lost response error", async () => {
|
||||
>
|
||||
Refresh
|
||||
</button>
|
||||
<output>{progress.publishError ?? progress.requestError}</output>
|
||||
<output>{progress.publishError}</output>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -124,11 +124,7 @@ import {
|
||||
PublishValidationResults,
|
||||
type PublishValidationFinding,
|
||||
} from "./publish-validation-results";
|
||||
import {
|
||||
PublishActions,
|
||||
usePublishValidationState,
|
||||
type PublishValidationState,
|
||||
} from "./publish-actions";
|
||||
import { PublishActions, usePublishValidationState } from "./publish-actions";
|
||||
import { flushExternalContentProject } from "~/shared/external-content-roots";
|
||||
import { getPublishValidationErrorMessage } from "./publish-error";
|
||||
import { runPublishAfterBestEffortChecks } from "./publish-preflight";
|
||||
@@ -581,14 +577,13 @@ const usePublishProgress = (projectId: Project["id"]) => {
|
||||
const [startedAt, setStartedAt] = useState<number>();
|
||||
const [showCountdown, setShowCountdown] = useState(false);
|
||||
const [isPublishing, setIsPublishing] = useState(false);
|
||||
const [requestError, setRequestError] = useState<string>();
|
||||
const [publishFindings, setPublishFindings] = useState<
|
||||
PublishValidationFinding[]
|
||||
>([]);
|
||||
const publishDiagnosticsSession = useRef(0);
|
||||
const [publishErrorState, setPublishErrorState] = useState<{
|
||||
value: JSX.Element | string;
|
||||
source: "request" | "status";
|
||||
source: "request" | "transport" | "status";
|
||||
}>();
|
||||
const [now, setNow] = useState(Date.now);
|
||||
const isMounted = useRef(false);
|
||||
@@ -634,7 +629,6 @@ const usePublishProgress = (projectId: Project["id"]) => {
|
||||
}, []);
|
||||
|
||||
const clearErrors = useCallback(() => {
|
||||
setRequestError(undefined);
|
||||
setPublishErrorState(undefined);
|
||||
}, []);
|
||||
|
||||
@@ -665,16 +659,15 @@ const usePublishProgress = (projectId: Project["id"]) => {
|
||||
build.buildId !== requestBaselineBuildId.current;
|
||||
if (status === "FAILED") {
|
||||
if (hasStartedPublishRequest.current && isNewBuild) {
|
||||
setRequestError(undefined);
|
||||
setPublishErrorState({ value: statusText, source: "status" });
|
||||
}
|
||||
} else {
|
||||
setPublishErrorState((current) =>
|
||||
current?.source === "status" ? undefined : current
|
||||
current?.source === "status" ||
|
||||
(isNewBuild && current?.source === "transport")
|
||||
? undefined
|
||||
: current
|
||||
);
|
||||
if (isNewBuild) {
|
||||
setRequestError(undefined);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -734,14 +727,14 @@ const usePublishProgress = (projectId: Project["id"]) => {
|
||||
setNow(startedAt);
|
||||
setShowCountdown(true);
|
||||
setIsPublishing(true);
|
||||
setRequestError(undefined);
|
||||
setPublishErrorState(undefined);
|
||||
publish()
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown error";
|
||||
if (isCurrentProject()) {
|
||||
setRequestError(message);
|
||||
setPublishErrorState({ value: message, source: "transport" });
|
||||
}
|
||||
if ($publishDialog.get() !== "publish" || !isCurrentProject()) {
|
||||
toast.error(message);
|
||||
@@ -753,7 +746,6 @@ const usePublishProgress = (projectId: Project["id"]) => {
|
||||
return {
|
||||
manualValidationFindings,
|
||||
isPublishing,
|
||||
requestError,
|
||||
publishFindings,
|
||||
setPublishFindings,
|
||||
beginPublishDiagnostics,
|
||||
@@ -811,21 +803,6 @@ const waitForPublishStatus = async (
|
||||
}
|
||||
};
|
||||
|
||||
const waitForOwnedPublishStatus = ({
|
||||
projectId,
|
||||
isCurrentProject,
|
||||
query,
|
||||
}: {
|
||||
projectId: Project["id"];
|
||||
isCurrentProject: () => boolean;
|
||||
query?: () => ReturnType<typeof nativeClient.domain.project.query>;
|
||||
}) =>
|
||||
waitForPublishStatus(
|
||||
() =>
|
||||
getRefreshedProject({ projectId, isCurrent: isCurrentProject, query }),
|
||||
isCurrentProject
|
||||
);
|
||||
|
||||
const refreshUntilSuccess = async (
|
||||
refresh: (showError: boolean) => Promise<Project | undefined>,
|
||||
isOpen: () => boolean,
|
||||
@@ -963,45 +940,21 @@ const Publish = ({
|
||||
disabled,
|
||||
refresh,
|
||||
restrictedFeatures,
|
||||
validationState,
|
||||
onValidationStateChange,
|
||||
isPublishing,
|
||||
requestError,
|
||||
manualValidationFindings,
|
||||
publishFindings,
|
||||
beginPublishDiagnostics,
|
||||
publishError,
|
||||
setPublishError,
|
||||
setPublishStatusError,
|
||||
clearErrors,
|
||||
isCurrentProject,
|
||||
countdown,
|
||||
startPublishing,
|
||||
validation,
|
||||
progress,
|
||||
}: {
|
||||
project: Project;
|
||||
timesLeft: number;
|
||||
disabled: boolean;
|
||||
refresh: () => Promise<void>;
|
||||
restrictedFeatures: Map<string, RestrictedFeature>;
|
||||
validationState: PublishValidationState;
|
||||
onValidationStateChange: (state: PublishValidationState) => void;
|
||||
isPublishing: boolean;
|
||||
requestError: string | undefined;
|
||||
manualValidationFindings: ReturnType<typeof useManualValidationFindings>;
|
||||
publishFindings: PublishValidationFinding[];
|
||||
beginPublishDiagnostics: ReturnType<
|
||||
typeof usePublishProgress
|
||||
>["beginPublishDiagnostics"];
|
||||
publishError: JSX.Element | string | undefined;
|
||||
setPublishError: (error: JSX.Element | string | undefined) => void;
|
||||
setPublishStatusError: (error: JSX.Element | string) => void;
|
||||
clearErrors: () => void;
|
||||
isCurrentProject: () => boolean;
|
||||
countdown: number | undefined;
|
||||
startPublishing: (publish: () => Promise<void>) => void;
|
||||
validation: ReturnType<typeof usePublishValidationState>;
|
||||
progress: ReturnType<typeof usePublishProgress>;
|
||||
}) => {
|
||||
const validationFindings = progress.manualValidationFindings;
|
||||
const { countdown, isCurrentProject } = progress;
|
||||
const { validationState, update: onValidationStateChange } = validation;
|
||||
const { userPublishCount, maxDailyPublishesPerUser } = useUserPublishCount();
|
||||
const validationFindings = manualValidationFindings;
|
||||
const { invalidate: invalidateValidationFindings } = validationFindings;
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const [hasSelectedDomains, setHasSelectedDomains] = useState(false);
|
||||
@@ -1011,7 +964,7 @@ const Publish = ({
|
||||
const hasPendingState = project.latestBuildVirtual
|
||||
? getPublishStatusAndText(project.latestBuildVirtual).status === "PENDING"
|
||||
: false;
|
||||
const isPublishInProgress = isPublishing || hasPendingState;
|
||||
const isPublishInProgress = progress.isPublishing || hasPendingState;
|
||||
|
||||
useEffect(() => {
|
||||
const form = buttonRef.current?.closest("form");
|
||||
@@ -1108,11 +1061,13 @@ const Publish = ({
|
||||
</>
|
||||
);
|
||||
}
|
||||
setPublishError(error);
|
||||
if (publishResult.error === "NOT_IMPLEMENTED") {
|
||||
toast.info(error);
|
||||
} else {
|
||||
toast.error(error);
|
||||
progress.setPublishError(error);
|
||||
if ($publishDialog.get() !== "publish" || !isCurrentProject()) {
|
||||
if (publishResult.error === "NOT_IMPLEMENTED") {
|
||||
toast.info(error);
|
||||
} else {
|
||||
toast.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
@@ -1123,15 +1078,19 @@ const Publish = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await waitForOwnedPublishStatus({
|
||||
projectId: project.id,
|
||||
isCurrentProject,
|
||||
});
|
||||
const result = await waitForPublishStatus(
|
||||
() =>
|
||||
getRefreshedProject({
|
||||
projectId: project.id,
|
||||
isCurrent: isCurrentProject,
|
||||
}),
|
||||
isCurrentProject
|
||||
);
|
||||
reportPublishResult({
|
||||
result,
|
||||
timesLeft,
|
||||
maxDailyPublishesPerUser,
|
||||
setPublishError: setPublishStatusError,
|
||||
setPublishError: progress.setPublishStatusError,
|
||||
isCurrentProject,
|
||||
});
|
||||
};
|
||||
@@ -1144,8 +1103,8 @@ const Publish = ({
|
||||
const handleValidate = async (formData: FormData) => {
|
||||
const domains = getDomainsFromForm(formData);
|
||||
const session = validationFindings.begin(domains);
|
||||
clearErrors();
|
||||
beginPublishDiagnostics();
|
||||
progress.clearErrors();
|
||||
progress.beginPublishDiagnostics();
|
||||
if (domains.length === 0) {
|
||||
toast.error("Please select at least one domain to publish");
|
||||
return;
|
||||
@@ -1175,8 +1134,8 @@ const Publish = ({
|
||||
|
||||
const handlePublish = (formData: FormData) => {
|
||||
validationFindings.invalidate();
|
||||
clearErrors();
|
||||
const diagnostics = beginPublishDiagnostics();
|
||||
progress.clearErrors();
|
||||
const diagnostics = progress.beginPublishDiagnostics();
|
||||
|
||||
// Custom domain checkboxes are disabled on free plan so they are never
|
||||
// submitted — only the staging (wstd.io) domain can appear in formData.
|
||||
@@ -1192,7 +1151,7 @@ const Publish = ({
|
||||
return;
|
||||
}
|
||||
|
||||
startPublishing(() =>
|
||||
progress.start(() =>
|
||||
runPublishAfterBestEffortChecks({
|
||||
checks: async () => {
|
||||
const checks = await runPublishDiagnostics(project.id);
|
||||
@@ -1217,10 +1176,10 @@ const Publish = ({
|
||||
return (
|
||||
<Flex gap={2} shrink={false} direction={"column"}>
|
||||
<PublishValidationResults
|
||||
findings={[...validationFindings.findings, ...publishFindings]}
|
||||
findings={[...validationFindings.findings, ...progress.publishFindings]}
|
||||
/>
|
||||
{(publishError ?? requestError) && (
|
||||
<Text color="destructive">{publishError ?? requestError}</Text>
|
||||
{progress.publishError && (
|
||||
<Text color="destructive">{progress.publishError}</Text>
|
||||
)}
|
||||
<PublishActions
|
||||
publishButtonRef={buttonRef}
|
||||
@@ -1612,22 +1571,8 @@ const UpgradeBanner = ({ hasCustomDomains }: { hasCustomDomains: boolean }) => {
|
||||
const Content = (props: {
|
||||
projectId: Project["id"];
|
||||
onExportClick: () => void;
|
||||
validationState: PublishValidationState;
|
||||
onValidationStateChange: (state: PublishValidationState) => void;
|
||||
isPublishing: boolean;
|
||||
requestError: string | undefined;
|
||||
manualValidationFindings: ReturnType<typeof useManualValidationFindings>;
|
||||
publishFindings: PublishValidationFinding[];
|
||||
beginPublishDiagnostics: ReturnType<
|
||||
typeof usePublishProgress
|
||||
>["beginPublishDiagnostics"];
|
||||
publishError: JSX.Element | string | undefined;
|
||||
setPublishError: (error: JSX.Element | string | undefined) => void;
|
||||
setPublishStatusError: (error: JSX.Element | string) => void;
|
||||
clearErrors: () => void;
|
||||
isCurrentProject: () => boolean;
|
||||
countdown: number | undefined;
|
||||
startPublishing: (publish: () => Promise<void>) => void;
|
||||
validation: ReturnType<typeof usePublishValidationState>;
|
||||
progress: ReturnType<typeof usePublishProgress>;
|
||||
}) => {
|
||||
const restrictedFeatures = useStore($restrictedFeatures);
|
||||
const [newDomains, setNewDomains] = useState(new Set<string>());
|
||||
@@ -1700,7 +1645,7 @@ const Content = (props: {
|
||||
refresh={refreshProject}
|
||||
projectState={projectState}
|
||||
project={project}
|
||||
validatedDomains={props.manualValidationFindings.domains}
|
||||
validatedDomains={props.progress.manualValidationFindings.domains}
|
||||
/>
|
||||
|
||||
<Domains
|
||||
@@ -1708,7 +1653,7 @@ const Content = (props: {
|
||||
domains={project.domainsVirtual}
|
||||
refresh={refreshProject}
|
||||
project={project}
|
||||
validatedDomains={props.manualValidationFindings.domains}
|
||||
validatedDomains={props.progress.manualValidationFindings.domains}
|
||||
/>
|
||||
</RadioGroup>
|
||||
</ScrollArea>
|
||||
@@ -1745,20 +1690,8 @@ const Content = (props: {
|
||||
timesLeft={maxDailyPublishesPerUser - userPublishCount}
|
||||
disabled={false}
|
||||
restrictedFeatures={restrictedFeatures}
|
||||
validationState={props.validationState}
|
||||
onValidationStateChange={props.onValidationStateChange}
|
||||
isPublishing={props.isPublishing}
|
||||
requestError={props.requestError}
|
||||
manualValidationFindings={props.manualValidationFindings}
|
||||
publishFindings={props.publishFindings}
|
||||
beginPublishDiagnostics={props.beginPublishDiagnostics}
|
||||
publishError={props.publishError}
|
||||
setPublishError={props.setPublishError}
|
||||
setPublishStatusError={props.setPublishStatusError}
|
||||
clearErrors={props.clearErrors}
|
||||
isCurrentProject={props.isCurrentProject}
|
||||
countdown={props.countdown}
|
||||
startPublishing={props.startPublishing}
|
||||
validation={props.validation}
|
||||
progress={props.progress}
|
||||
/>
|
||||
</PanelContent>
|
||||
</form>
|
||||
@@ -1986,8 +1919,7 @@ type PublishProps = {
|
||||
export const PublishButton = ({ projectId }: PublishProps) => {
|
||||
const publishDialog = useStore($publishDialog);
|
||||
const authTokenPermissions = useStore($authTokenPermissions);
|
||||
const { validationState, update, reset } =
|
||||
usePublishValidationState(publishDialog);
|
||||
const validation = usePublishValidationState(publishDialog);
|
||||
const publishProgress = usePublishProgress(projectId);
|
||||
const {
|
||||
dismissCountdown,
|
||||
@@ -2057,14 +1989,14 @@ export const PublishButton = ({ projectId }: PublishProps) => {
|
||||
: "Only the owner, an admin, or content editors with publish permissions can publish projects";
|
||||
|
||||
const handleExportClick = () => {
|
||||
reset();
|
||||
validation.reset();
|
||||
publishProgress.dismissCountdown();
|
||||
$publishDialog.set("export");
|
||||
};
|
||||
|
||||
const handleOpenChange = (isOpen: boolean) => {
|
||||
if (isOpen === false) {
|
||||
reset();
|
||||
validation.reset();
|
||||
publishProgress.dismissCountdown();
|
||||
}
|
||||
$publishDialog.set(isOpen ? "publish" : "none");
|
||||
@@ -2106,20 +2038,8 @@ export const PublishButton = ({ projectId }: PublishProps) => {
|
||||
<Content
|
||||
projectId={projectId}
|
||||
onExportClick={handleExportClick}
|
||||
validationState={validationState}
|
||||
onValidationStateChange={update}
|
||||
isPublishing={publishProgress.isPublishing}
|
||||
requestError={publishProgress.requestError}
|
||||
manualValidationFindings={publishProgress.manualValidationFindings}
|
||||
publishFindings={publishProgress.publishFindings}
|
||||
beginPublishDiagnostics={publishProgress.beginPublishDiagnostics}
|
||||
publishError={publishProgress.publishError}
|
||||
setPublishError={publishProgress.setPublishError}
|
||||
setPublishStatusError={publishProgress.setPublishStatusError}
|
||||
clearErrors={publishProgress.clearErrors}
|
||||
isCurrentProject={publishProgress.isCurrentProject}
|
||||
countdown={publishProgress.countdown}
|
||||
startPublishing={publishProgress.start}
|
||||
validation={validation}
|
||||
progress={publishProgress}
|
||||
/>
|
||||
)}
|
||||
</PopoverContent>
|
||||
@@ -2131,7 +2051,6 @@ export const __testing__ = {
|
||||
usePublishProgress,
|
||||
useManualValidationFindings,
|
||||
waitForPublishStatus,
|
||||
waitForOwnedPublishStatus,
|
||||
refreshUntilSuccess,
|
||||
getRefreshedProject,
|
||||
reportPublishResult,
|
||||
|
||||
Reference in new issue
Block a user