feat: make catalog-pages dedup a choosable step in Fix alles
The maintenance "Fix alles" now has a checkbox to include or skip the duplicate catalog_pages merge, so admins can choose whether to run it. removeDuplicates takes an includePages flag and fixEverything threads it through to the action.
This commit is contained in:
1 parent
6dced0fb54
commit
3a292a44f1
3 files changed
+45
-11
No files matched your search
@@ -99,12 +99,12 @@ export async function applyAlignIdsAction(): Promise<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fixEverythingAction(): Promise<
|
export async function fixEverythingAction(input?: {
|
||||||
ActionResult<maintenance.FixAllResult>
|
dedupePages?: boolean;
|
||||||
> {
|
}): Promise<ActionResult<maintenance.FixAllResult>> {
|
||||||
try {
|
try {
|
||||||
await guard();
|
await guard();
|
||||||
return actionOk(await maintenance.fixEverything());
|
return actionOk(await maintenance.fixEverything(input ?? {}));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return handleActionError(e);
|
return handleActionError(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
|
||||||
interface Health {
|
interface Health {
|
||||||
itemsBaseTotal: number;
|
itemsBaseTotal: number;
|
||||||
@@ -38,6 +39,7 @@ export function CatalogMaintenancePanel() {
|
|||||||
const [health, setHealth] = useState<Health | null>(null);
|
const [health, setHealth] = useState<Health | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [busy, setBusy] = useState<string | null>(null);
|
const [busy, setBusy] = useState<string | null>(null);
|
||||||
|
const [dedupePages, setDedupePages] = useState(true);
|
||||||
const [alignPreview, setAlignPreview] = useState<{
|
const [alignPreview, setAlignPreview] = useState<{
|
||||||
moves: number;
|
moves: number;
|
||||||
inserted: number;
|
inserted: number;
|
||||||
@@ -286,12 +288,38 @@ export function CatalogMaintenancePanel() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
<div className="mb-3 flex items-center gap-2 rounded-md border p-2">
|
||||||
|
<Checkbox
|
||||||
|
id="dedupe-pages"
|
||||||
|
checked={dedupePages}
|
||||||
|
onCheckedChange={(v) => setDedupePages(v === true)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="dedupe-pages"
|
||||||
|
className="text-sm text-muted-foreground"
|
||||||
|
>
|
||||||
|
Also merge duplicate catalog pages (double links)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<Button
|
<Button
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
disabled={busy !== null}
|
disabled={busy !== null}
|
||||||
onClick={() =>
|
onClick={async () => {
|
||||||
void run("all", fixEverythingAction, "All repairs applied")
|
setBusy("all");
|
||||||
}
|
try {
|
||||||
|
const res = await fixEverythingAction({ dedupePages });
|
||||||
|
if (res.ok) {
|
||||||
|
toast.success("All repairs applied");
|
||||||
|
await refresh();
|
||||||
|
} else {
|
||||||
|
toast.error(res.error ?? "Failed");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
toast.error(String(e));
|
||||||
|
} finally {
|
||||||
|
setBusy(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Fix everything now
|
Fix everything now
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -388,9 +388,13 @@ async function dedupCatalogTable(table: string): Promise<number> {
|
|||||||
* product on the same page). The page merge runs before the row dedup so items
|
* product on the same page). The page merge runs before the row dedup so items
|
||||||
* moved onto the survivor are still de-duplicated within the page afterwards.
|
* moved onto the survivor are still de-duplicated within the page afterwards.
|
||||||
*/
|
*/
|
||||||
export async function removeDuplicates(): Promise<DedupResult> {
|
export async function removeDuplicates(
|
||||||
|
includePages = true,
|
||||||
|
): Promise<DedupResult> {
|
||||||
const ib = await removeDuplicateItemsBase();
|
const ib = await removeDuplicateItemsBase();
|
||||||
const pageDedup = await dedupeCatalogPages();
|
const pageDedup = includePages
|
||||||
|
? await dedupeCatalogPages()
|
||||||
|
: { groups: 0, removed: 0, remapped: 0 };
|
||||||
const catalogRemoved = await dedupCatalogTable("catalog_items");
|
const catalogRemoved = await dedupCatalogTable("catalog_items");
|
||||||
const catalogBcRemoved = await dedupCatalogTable("catalog_items_bc");
|
const catalogBcRemoved = await dedupCatalogTable("catalog_items_bc");
|
||||||
return {
|
return {
|
||||||
@@ -630,12 +634,14 @@ export interface FixAllResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Run every repair in a sensible order, then return before/after health. */
|
/** Run every repair in a sensible order, then return before/after health. */
|
||||||
export async function fixEverything(): Promise<FixAllResult> {
|
export async function fixEverything(
|
||||||
|
opts: { dedupePages?: boolean } = {},
|
||||||
|
): Promise<FixAllResult> {
|
||||||
const healthBefore = await getFurniHealth();
|
const healthBefore = await getFurniHealth();
|
||||||
const sprite = await fixSpriteIds();
|
const sprite = await fixSpriteIds();
|
||||||
const offers = await fixCatalogOffers();
|
const offers = await fixCatalogOffers();
|
||||||
const reconcile = await reconcileIds();
|
const reconcile = await reconcileIds();
|
||||||
const dedup = await removeDuplicates();
|
const dedup = await removeDuplicates(opts.dedupePages ?? true);
|
||||||
const align = await forceItemsBaseIdsToFurnidata(true);
|
const align = await forceItemsBaseIdsToFurnidata(true);
|
||||||
const healthAfter = await getFurniHealth();
|
const healthAfter = await getFurniHealth();
|
||||||
return { healthBefore, sprite, offers, reconcile, dedup, align, healthAfter };
|
return { healthBefore, sprite, offers, reconcile, dedup, align, healthAfter };
|
||||||
|
|||||||
Reference in new issue
Block a user