From 26a3878faaf2fe89adc21d63e276d98bcf8c47ec Mon Sep 17 00:00:00 2001 From: Steven RYDELL Date: Sat, 1 Aug 2026 22:25:26 +0200 Subject: [PATCH] feat(domains): add Aliases count column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same account-alias-count-column deviation already used on Accounts, Groups, and Mailing Lists, extended to x:Domain: adds a synthetic aliasCount column resolved from the real aliases property (a `set` of alias domain names here, vs. an objectList elsewhere — same id-keyed wire format, so the existing generic COUNT_COLUMN_SOURCES handling needed no changes). Verified in the running dev server: the column renders correctly alongside the domain's existing Enabled/Certificate/DNS columns. --- SCHEMA_DEVIATIONS.md | 4 ++-- src/lib/domainColumns.ts | 29 +++++++++++++++++++++++++++++ src/pages/AdminPanel.tsx | 7 ++++++- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/lib/domainColumns.ts diff --git a/SCHEMA_DEVIATIONS.md b/SCHEMA_DEVIATIONS.md index 3de6095..384867b 100644 --- a/SCHEMA_DEVIATIONS.md +++ b/SCHEMA_DEVIATIONS.md @@ -69,8 +69,8 @@ itself stays byte-for-byte alignable with upstream's version of the file. ### `account-alias-count-column` 🟡 -- **Where**: [`src/lib/accountColumns.ts`](src/lib/accountColumns.ts), [`src/lib/mailingListColumns.ts`](src/lib/mailingListColumns.ts), rendering in [`src/components/lists/DynamicList.tsx`](src/components/lists/DynamicList.tsx) -- **What**: adds a synthetic `aliasCount` column to the `x:Account/User`, `x:Account/Group`, and `x:MailingList` lists — not a real schema property; `DynamicList` resolves it from the real `aliases` objectList property and renders its entry count. +- **Where**: [`src/lib/accountColumns.ts`](src/lib/accountColumns.ts), [`src/lib/mailingListColumns.ts`](src/lib/mailingListColumns.ts), [`src/lib/domainColumns.ts`](src/lib/domainColumns.ts), resolved generically via `COUNT_COLUMN_SOURCES` in [`src/components/lists/DynamicList.tsx`](src/components/lists/DynamicList.tsx) +- **What**: adds a synthetic `aliasCount` column to the `x:Account/User`, `x:Account/Group`, `x:MailingList`, and `x:Domain` lists — not a real schema property; `DynamicList` resolves it from the real `aliases` property (an objectList on Accounts/Groups/Mailing Lists, a `set` of domain names on Domains — same id-keyed wire format either way) and renders its entry count. - **Why**: none of these lists' schemas expose alias count as a column, only the full `aliases` list on the detail view. - **Ideal fix**: the server's list schemas include a computed alias-count column natively; these column definitions are deleted. diff --git a/src/lib/domainColumns.ts b/src/lib/domainColumns.ts new file mode 100644 index 0000000..7618e09 --- /dev/null +++ b/src/lib/domainColumns.ts @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +import type { Schema } from '@/types/schema'; + +/** + * SCHEMA-DEVIATION: account-alias-count-column (see SCHEMA_DEVIATIONS.md) + * + * The Domains list doesn't expose alias-domain count as a column, only + * the full `aliases` set on the detail view. Adds the same synthetic + * `aliasCount` column already used on Accounts/Groups/Mailing Lists — + * DynamicList's generic count-column handling picks it up with no + * further wiring. + */ +export function withDomainColumns(schema: Schema): Schema { + const list = schema.lists['x:Domain']; + if (!list) return schema; + + return { + ...schema, + lists: { + ...schema.lists, + 'x:Domain': { ...list, columns: [...list.columns, { name: 'aliasCount', label: 'Aliases' }] }, + }, + }; +} diff --git a/src/pages/AdminPanel.tsx b/src/pages/AdminPanel.tsx index 68779dc..76faad3 100644 --- a/src/pages/AdminPanel.tsx +++ b/src/pages/AdminPanel.tsx @@ -16,6 +16,7 @@ import { withClientLogFilters } from '@/lib/logFilters'; import { withAccountListColumns } from '@/lib/accountColumns'; import { withMailingListColumns } from '@/lib/mailingListColumns'; import { withRoleListColumns } from '@/lib/roleColumns'; +import { withDomainColumns } from '@/lib/domainColumns'; import { setLocale } from '@/i18n'; import { TopBar } from '@/components/layout/TopBar'; import { Sidebar } from '@/components/layout/Sidebar'; @@ -152,7 +153,11 @@ export default function AdminPanel() { if (cancelled) return; - setSchema(withRoleListColumns(withMailingListColumns(withAccountListColumns(withClientLogFilters(schemaData))))); + setSchema( + withDomainColumns( + withRoleListColumns(withMailingListColumns(withAccountListColumns(withClientLogFilters(schemaData)))), + ), + ); setAccountInfo(accountData.permissions, accountData.edition, accountData.locale); setLocale(accountData.locale);