Show invited people the Rule, let them copy its cards for their community, and replace an expired invitation link.
This commit is contained in:
1 parent
727a92a9ac
commit
3c984e00c5
37 files changed
+1962
-19
No files matched your search
@@ -561,6 +561,119 @@ export type DuplicateRuleResult =
|
||||
| { ok: true; id: string; title: string }
|
||||
| { ok: false; error: string; status: number };
|
||||
|
||||
export type MakeCopyRuleResult =
|
||||
| {
|
||||
ok: true;
|
||||
id: string;
|
||||
title: string;
|
||||
summary: string | null;
|
||||
document: Record<string, unknown>;
|
||||
copiedFromTitle: string;
|
||||
copiedNameHit: {
|
||||
categoryName: string;
|
||||
entryTitle: string;
|
||||
} | null;
|
||||
}
|
||||
| { ok: false; error: string; status: number };
|
||||
|
||||
export async function makeCopyPublishedRule(
|
||||
id: string,
|
||||
title: string,
|
||||
): Promise<MakeCopyRuleResult> {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`/api/rules/${encodeURIComponent(id)}/make-copy`,
|
||||
{
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: jsonHeaders,
|
||||
body: JSON.stringify({ title }),
|
||||
},
|
||||
);
|
||||
const data = (await safeParseJsonResponse(res)) as {
|
||||
rule?: {
|
||||
id: string;
|
||||
title: string;
|
||||
summary?: string | null;
|
||||
document?: Record<string, unknown>;
|
||||
copiedFromTitle?: string;
|
||||
copiedNameHit?: {
|
||||
categoryName: string;
|
||||
entryTitle: string;
|
||||
} | null;
|
||||
};
|
||||
} | null;
|
||||
const rule = data && typeof data === "object" ? data.rule : undefined;
|
||||
const document = rule?.document;
|
||||
if (
|
||||
!res.ok ||
|
||||
!rule ||
|
||||
typeof rule.id !== "string" ||
|
||||
typeof rule.title !== "string" ||
|
||||
!document ||
|
||||
typeof document !== "object" ||
|
||||
Array.isArray(document)
|
||||
) {
|
||||
const fromBody =
|
||||
data && typeof data === "object" ? readApiErrorMessage(data) : null;
|
||||
const msg =
|
||||
fromBody && fromBody !== "Request failed"
|
||||
? fromBody
|
||||
: PUBLISH_FAILED_FALLBACK;
|
||||
return {
|
||||
ok: false as const,
|
||||
error: msg,
|
||||
status: res.status,
|
||||
};
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
id: rule.id,
|
||||
title: rule.title,
|
||||
summary: typeof rule.summary === "string" ? rule.summary : null,
|
||||
document,
|
||||
copiedFromTitle:
|
||||
typeof rule.copiedFromTitle === "string" ? rule.copiedFromTitle : "",
|
||||
copiedNameHit: rule.copiedNameHit ?? null,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
ok: false as const,
|
||||
error: DRAFT_SAVE_NETWORK_ERROR,
|
||||
status: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function resendExpiredStakeholderInvite(
|
||||
token: string,
|
||||
email: string,
|
||||
): Promise<{ ok: true } | { ok: false; error: string; retryAfterMs?: number }> {
|
||||
try {
|
||||
const res = await fetch("/api/invites/rule-stakeholder/resend", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: jsonHeaders,
|
||||
body: JSON.stringify({ token, email }),
|
||||
});
|
||||
const data = await safeParseJsonResponse(res);
|
||||
if (!res.ok) {
|
||||
const fromBody =
|
||||
data && typeof data === "object" ? readApiErrorMessage(data) : null;
|
||||
return {
|
||||
ok: false as const,
|
||||
error: fromBody && fromBody !== "Request failed"
|
||||
? fromBody
|
||||
: DRAFT_SAVE_NETWORK_ERROR,
|
||||
retryAfterMs: retryAfterFromResponse(res, data),
|
||||
};
|
||||
}
|
||||
return { ok: true };
|
||||
} catch {
|
||||
return { ok: false as const, error: DRAFT_SAVE_NETWORK_ERROR };
|
||||
}
|
||||
}
|
||||
|
||||
export async function duplicatePublishedRule(
|
||||
id: string,
|
||||
): Promise<DuplicateRuleResult> {
|
||||
|
||||
Reference in new issue
Block a user