fixes
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
STAFF_ROLE_OPTIONS,
|
||||
assignAdminPlan,
|
||||
cloneAdminCompanyCatalog,
|
||||
fixAdminCompanyCatalog,
|
||||
companyPlanBadge,
|
||||
isStaffRoleApiUnavailable,
|
||||
listAdminCompanies,
|
||||
@@ -54,7 +55,7 @@
|
||||
TabsList,
|
||||
TabsTrigger
|
||||
} from "$lib/components/ui";
|
||||
import { Building2, Copy, KeyRound, Search, Shield, UserPlus, Users } from "@lucide/svelte";
|
||||
import { Building2, Copy, KeyRound, Search, Shield, UserPlus, Users, Wrench } from "@lucide/svelte";
|
||||
|
||||
type TabKey = "users" | "companies";
|
||||
|
||||
@@ -93,6 +94,9 @@
|
||||
let cloneOpen = $state(false);
|
||||
let cloneCompany = $state<AdminOrgCompany | null>(null);
|
||||
|
||||
let fixOpen = $state(false);
|
||||
let fixCompany = $state<AdminOrgCompany | null>(null);
|
||||
|
||||
const usersPage = $derived(Math.floor(usersOffset / PAGE_SIZE) + 1);
|
||||
const usersPages = $derived(Math.max(1, Math.ceil(usersTotal / PAGE_SIZE)));
|
||||
const companiesPage = $derived(Math.floor(companiesOffset / PAGE_SIZE) + 1);
|
||||
@@ -362,6 +366,39 @@
|
||||
success = "";
|
||||
}
|
||||
|
||||
function openFixDialog(company: AdminOrgCompany) {
|
||||
fixCompany = company;
|
||||
fixOpen = true;
|
||||
error = "";
|
||||
success = "";
|
||||
}
|
||||
|
||||
async function confirmFixCatalog() {
|
||||
if (!fixCompany) return;
|
||||
busy = true;
|
||||
error = "";
|
||||
success = "";
|
||||
const targetName = fixCompany.name;
|
||||
try {
|
||||
const res = await fixAdminCompanyCatalog(fixCompany.id, {
|
||||
reprocessSampleLimit: 25
|
||||
});
|
||||
const r = res.result;
|
||||
success = i18n.t("flash.admin.fixA1Success", {
|
||||
name: targetName,
|
||||
prompts: String(r.prompts ?? r.category_prompts_updated ?? 0),
|
||||
hashes: String(r.hashes ?? r.weak_hashes_cleared ?? 0),
|
||||
categories: String(r.categories ?? r.categories_backfilled ?? 0)
|
||||
});
|
||||
fixOpen = false;
|
||||
fixCompany = null;
|
||||
} catch (err) {
|
||||
error = failureMessage(err, i18n.t("flash.admin.fixA1Error", { name: targetName }));
|
||||
} finally {
|
||||
busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmCloneCatalog() {
|
||||
if (!cloneCompany) return;
|
||||
busy = true;
|
||||
@@ -776,28 +813,40 @@
|
||||
</TableCell>
|
||||
<TableCell class="hidden text-muted-foreground lg:table-cell">{company.language || "—"}</TableCell>
|
||||
<TableCell stickyRight>
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onclick={() => openCloneDialog(company)}
|
||||
aria-label={i18n.t("admin.users.cloneCatalogAria", {
|
||||
name: company.name
|
||||
})}
|
||||
data-testid="admin-clone-catalog"
|
||||
>
|
||||
<Copy class="h-3.5 w-3.5 lg:mr-1" aria-hidden="true" />
|
||||
<span class="hidden lg:inline">{i18n.t("admin.users.cloneCatalog")}</span>
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
onclick={() => openAssignDialog(company)}
|
||||
aria-label={`Assign plan to ${company.name}`}
|
||||
>
|
||||
<UserPlus class="h-3.5 w-3.5 lg:mr-1" aria-hidden="true" />
|
||||
<span class="hidden lg:inline">{i18n.t("admin.users.assignPlan")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-end gap-1">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onclick={() => openFixDialog(company)}
|
||||
aria-label={i18n.t("admin.users.fixA1Aria", {
|
||||
name: company.name
|
||||
})}
|
||||
data-testid="admin-fix-catalog"
|
||||
>
|
||||
<Wrench class="h-3.5 w-3.5 lg:mr-1" aria-hidden="true" />
|
||||
<span class="hidden lg:inline">{i18n.t("admin.users.fixA1")}</span>
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onclick={() => openCloneDialog(company)}
|
||||
aria-label={i18n.t("admin.users.cloneCatalogAria", {
|
||||
name: company.name
|
||||
})}
|
||||
data-testid="admin-clone-catalog"
|
||||
>
|
||||
<Copy class="h-3.5 w-3.5 lg:mr-1" aria-hidden="true" />
|
||||
<span class="hidden lg:inline">{i18n.t("admin.users.cloneCatalog")}</span>
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
onclick={() => openAssignDialog(company)}
|
||||
aria-label={`Assign plan to ${company.name}`}
|
||||
>
|
||||
<UserPlus class="h-3.5 w-3.5 lg:mr-1" aria-hidden="true" />
|
||||
<span class="hidden lg:inline">{i18n.t("admin.users.assignPlan")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{/each}
|
||||
@@ -957,3 +1006,39 @@
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
bind:open={fixOpen}
|
||||
title={i18n.t("admin.users.fixA1Title")}
|
||||
description={i18n.t("admin.users.fixA1Desc")}
|
||||
>
|
||||
<div class="space-y-4">
|
||||
{#if error}
|
||||
<p class="text-sm text-destructive" role="alert">{error}</p>
|
||||
{/if}
|
||||
{#if fixCompany}
|
||||
<p class="text-sm text-foreground">
|
||||
{i18n.t("admin.users.fixA1Company", { name: fixCompany.name })}
|
||||
</p>
|
||||
{/if}
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{i18n.t("admin.users.fixA1Warning")}
|
||||
</p>
|
||||
<div class="flex flex-wrap justify-end gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={busy}
|
||||
onclick={() => {
|
||||
fixOpen = false;
|
||||
fixCompany = null;
|
||||
}}
|
||||
>
|
||||
{i18n.t("admin.users.fixA1Cancel")}
|
||||
</Button>
|
||||
<Button type="button" loading={busy} onclick={() => confirmFixCatalog()}>
|
||||
{i18n.t("admin.users.fixA1Confirm")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user