Regroup settings into collapsible sections

Restructure the flat settingsCategories list into five top-level groups
(General, Appearance, Screens, Productivity, Add-ons), each a collapsible
nav section with persisted open/closed state. Consolidate the six
single-toggle modern_* categories (posts/pages/media/users/comments/
plugins) into one "Content tables" screen. Search now matches on group +
category + subtitle and hides empty groups. Field definitions, save flow,
and setting keys are unchanged.

settingsConfig.js exports settingsGroups plus a flattened settingsCategories
for default-seeding and deep-link lookups.

(package-lock.json: version field synced 2.16.0 -> 3.1.0 to match package.json.)

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
NixReaper
2026-07-12 09:27:09 -05:00
co-authored by Claude Opus 4.8
parent ce8fcc8fdd
commit 1c8c351654
3 changed files with 451 additions and 369 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "aurora-admin-app", "name": "aurora-admin-app",
"version": "2.16.0", "version": "3.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "aurora-admin-app", "name": "aurora-admin-app",
"version": "2.16.0", "version": "3.1.0",
"dependencies": { "dependencies": {
"@codemirror/lang-css": "^6.3.1", "@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11", "@codemirror/lang-html": "^6.4.11",
+101 -31
View File
@@ -1,6 +1,6 @@
<script setup> <script setup>
import { ref, reactive, computed, watch, nextTick } from 'vue'; import { ref, reactive, computed, watch, nextTick } from 'vue';
import { settingsCategories } from './settingsConfig.js'; import { settingsGroups, settingsCategories } from './settingsConfig.js';
import SettingsField from './components/SettingsField.vue'; import SettingsField from './components/SettingsField.vue';
import { applyThemePalette, applyFontFamily } from './applyLiveTheme.js'; import { applyThemePalette, applyFontFamily } from './applyLiveTheme.js';
@@ -45,6 +45,29 @@ const activeCategory = computed(
() => visibleCategories.find((c) => c.id === activeId.value) || visibleCategories[0] () => visibleCategories.find((c) => c.id === activeId.value) || visibleCategories[0]
); );
const groupOfCategory = (catId) =>
settingsGroups.find((g) => g.categories.some((c) => c.id === catId));
// Collapsible nav groups. Default open; collapse state persisted per group.
const OPEN_KEY = 'aurora-settings-groups-open';
const loadOpen = () => {
try {
return JSON.parse(localStorage.getItem(OPEN_KEY)) || {};
} catch {
return {};
}
};
const openState = reactive(loadOpen());
// Keep the active category's group open so its item is always reachable.
const activeGroup = groupOfCategory(activeId.value);
if (activeGroup) openState[activeGroup.id] = true;
const isGroupOpen = (id) => openState[id] !== false;
const toggleGroup = (id) => {
openState[id] = !isGroupOpen(id);
localStorage.setItem(OPEN_KEY, JSON.stringify(openState));
};
// The content panel scrolls independently of the nav (see .settings__content // The content panel scrolls independently of the nav (see .settings__content
// below) so picking a category from a scrolled-down spot in the nav doesn't // below) so picking a category from a scrolled-down spot in the nav doesn't
// require scrolling the whole page back up to see it. But the panel is one // require scrolling the whole page back up to see it. But the panel is one
@@ -56,6 +79,8 @@ const activeCategory = computed(
const contentEl = ref(null); const contentEl = ref(null);
const selectCategory = (id) => { const selectCategory = (id) => {
activeId.value = id; activeId.value = id;
const g = groupOfCategory(id);
if (g) openState[g.id] = true;
const url = new URL(window.location.href); const url = new URL(window.location.href);
url.searchParams.set('category', id); url.searchParams.set('category', id);
window.history.replaceState({}, '', url); window.history.replaceState({}, '', url);
@@ -64,15 +89,25 @@ const selectCategory = (id) => {
}); });
}; };
// Search filter over the nav. // Search filter over the nav — matches on group title, category title, or
// subtitle; groups with no surviving categories drop out entirely.
const query = ref(''); const query = ref('');
const filteredCategories = computed(() => { const searching = computed(() => query.value.trim().length > 0);
const filteredGroups = computed(() => {
const q = query.value.trim().toLowerCase(); const q = query.value.trim().toLowerCase();
if (!q) return visibleCategories; if (!q) return settingsGroups;
return visibleCategories.filter( return settingsGroups
(c) => .map((g) => {
c.title.toLowerCase().includes(q) || c.subtitle.toLowerCase().includes(q) const groupMatch = g.title.toLowerCase().includes(q);
); const categories = g.categories.filter(
(c) =>
groupMatch ||
c.title.toLowerCase().includes(q) ||
c.subtitle.toLowerCase().includes(q)
);
return { ...g, categories };
})
.filter((g) => g.categories.length > 0);
}); });
// Options for multiselect fields, resolved from server-provided lists. // Options for multiselect fields, resolved from server-provided lists.
@@ -172,20 +207,37 @@ const importSettings = (e) => {
<input v-model="query" type="text" placeholder="Search settings…" /> <input v-model="query" type="text" placeholder="Search settings…" />
</div> </div>
<ul class="settings__list"> <ul class="settings__groups">
<li v-for="cat in filteredCategories" :key="cat.id"> <li v-for="group in filteredGroups" :key="group.id" class="settings__group">
<button <button
type="button" type="button"
class="settings__cat" class="settings__group-head"
:class="{ 'settings__cat--active': cat.id === activeId }" :aria-expanded="isGroupOpen(group.id) || searching"
@click="selectCategory(cat.id)" @click="toggleGroup(group.id)"
> >
<span class="settings__cat-icon"><span class="dashicons" :class="cat.icon" /></span> <span class="settings__group-icon dashicons" :class="group.icon" />
<span class="settings__cat-text"> <span class="settings__group-title">{{ group.title }}</span>
<span class="settings__cat-title">{{ cat.title }}</span> <span
<span class="settings__cat-sub">{{ cat.subtitle }}</span> class="settings__group-caret dashicons dashicons-arrow-down-alt2"
</span> :class="{ 'is-collapsed': !isGroupOpen(group.id) && !searching }"
/>
</button> </button>
<ul v-show="isGroupOpen(group.id) || searching" class="settings__list">
<li v-for="cat in group.categories" :key="cat.id">
<button
type="button"
class="settings__cat"
:class="{ 'settings__cat--active': cat.id === activeId }"
@click="selectCategory(cat.id)"
>
<span class="settings__cat-icon dashicons" :class="cat.icon" />
<span class="settings__cat-title">{{ cat.title }}</span>
</button>
</li>
</ul>
</li>
<li v-if="!filteredGroups.length" class="settings__empty">
No settings match “{{ query }}”.
</li> </li>
</ul> </ul>
</aside> </aside>
@@ -280,27 +332,45 @@ const importSettings = (e) => {
font-size: 0.8125rem; width: 100%; font-size: 0.8125rem; width: 100%;
} }
.settings__list { list-style: none; margin: 0; padding: 0; } .settings__groups { list-style: none; margin: 0; padding: 0; }
.settings__group { margin-bottom: 4px; }
.settings__group-head {
display: flex; align-items: center; gap: 8px; width: 100%;
padding: 6px 8px; border: none; background: none; cursor: pointer;
border-radius: 8px; color: var(--aurora-text-muted);
}
.settings__group-head:hover { color: var(--aurora-text); }
.settings__group-icon { font-size: 15px; width: 16px; height: 16px; }
.settings__group-title {
font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em;
text-transform: uppercase;
}
.settings__group-caret {
margin-left: auto; font-size: 16px; width: 16px; height: 16px;
transition: transform 0.15s ease;
}
.settings__group-caret.is-collapsed { transform: rotate(-90deg); }
.settings__list { list-style: none; margin: 2px 0 8px; padding: 0; }
.settings__cat { .settings__cat {
display: flex; align-items: center; gap: 12px; width: 100%; display: flex; align-items: center; gap: 10px; width: 100%;
padding: 10px; border: none; background: none; cursor: pointer; padding: 8px 10px; border: none; background: none; cursor: pointer;
border-radius: 12px; text-align: left; margin-bottom: 2px; border-radius: 10px; text-align: left; margin-bottom: 1px;
color: var(--aurora-text);
} }
.settings__cat:hover { background: var(--aurora-bg-subtle); } .settings__cat:hover { background: var(--aurora-bg-subtle); }
.settings__cat--active { background: var(--aurora-accent-soft); } .settings__cat--active { background: var(--aurora-accent-soft); }
.settings__cat-icon { .settings__cat-icon {
width: 34px; height: 34px; flex-shrink: 0; font-size: 16px; width: 18px; height: 18px; flex-shrink: 0;
border-radius: 9px; background: var(--aurora-bg-subtle);
display: flex; align-items: center; justify-content: center;
color: var(--aurora-text-muted); color: var(--aurora-text-muted);
} }
.settings__cat--active .settings__cat-icon { color: var(--aurora-accent); } .settings__cat--active .settings__cat-icon { color: var(--aurora-accent); }
.settings__cat-text { display: flex; flex-direction: column; min-width: 0; } .settings__cat-title { font-size: 0.8125rem; font-weight: 500; }
.settings__cat-title { font-size: 0.875rem; font-weight: 600; color: var(--aurora-text); } .settings__cat--active .settings__cat-title { color: var(--aurora-accent); font-weight: 600; }
.settings__cat--active .settings__cat-title { color: var(--aurora-accent); }
.settings__cat-sub { .settings__empty {
font-size: 0.75rem; color: var(--aurora-text-muted); padding: 12px 10px; font-size: 0.8125rem; color: var(--aurora-text-muted);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
} }
/* Right content — no background/border of its own, same reasoning. /* Right content — no background/border of its own, same reasoning.
+348 -336
View File
@@ -1,359 +1,371 @@
/** /**
* Declarative settings schema for the Aurora Admin settings page. * Declarative settings schema for the Aurora Admin settings page.
* Each category renders as an item in the left nav; its fields render in *
* the right panel. Field `key`s map directly into the aurora_admin_settings * Categories are organized into top-level groups. Each group renders as a
* option, saved via the wp/v2/settings REST route. * collapsible section in the left nav; each category within it renders as a
* nav item, and its fields render in the right panel. Field `key`s map
* directly into the aurora_admin_settings option, saved via the
* wp/v2/settings REST route.
*/ */
export const settingsCategories = [ export const settingsGroups = [
{ {
id: 'general', id: 'general',
title: 'General', title: 'General',
subtitle: 'Core plugin settings',
icon: 'dashicons-admin-settings', icon: 'dashicons-admin-settings',
fields: [ categories: [
{ {
key: 'logo', id: 'general',
type: 'image', title: 'General',
label: 'Logo', subtitle: 'Core plugin settings',
description: 'Optional logo to be displayed in the menu.', icon: 'dashicons-admin-settings',
}, fields: [
{ {
key: 'dark_logo', key: 'logo',
type: 'image', type: 'image',
label: 'Dark mode logo', label: 'Logo',
description: description: 'Optional logo to be displayed in the menu.',
"Set an alternative logo to use in dark mode. If one isn't set it will fall back to the standard logo.", },
}, {
{ key: 'dark_logo',
key: 'disable_theme', type: 'image',
type: 'multiselect', label: 'Dark mode logo',
label: 'Disable theme', description:
description: 'Choose roles to disable the theme for.', "Set an alternative logo to use in dark mode. If one isn't set it will fall back to the standard logo.",
optionsSource: 'roles', },
}, {
{ key: 'disable_theme',
key: 'search_post_types', type: 'multiselect',
type: 'multiselect', label: 'Disable theme',
label: 'Search post types', description: 'Choose roles to disable the theme for.',
description: 'Choose which post types are available in the global search.', optionsSource: 'roles',
optionsSource: 'postTypes', },
}, {
{ key: 'search_post_types',
key: 'disable_global_search', type: 'multiselect',
type: 'segmented', label: 'Search post types',
label: 'Disable global search', description: 'Choose which post types are available in the global search.',
description: 'Disable global search for all users.', optionsSource: 'postTypes',
}, },
], {
}, key: 'disable_global_search',
{ type: 'segmented',
id: 'login', label: 'Disable global search',
title: 'Login', description: 'Disable global search for all users.',
subtitle: 'Customize login page appearance and security', },
icon: 'dashicons-lock',
fields: [
{
key: 'style_login',
type: 'toggle',
label: 'Style login page',
description: 'Apply the Aurora theme to the WordPress login screen.',
},
{
key: 'login_logo',
type: 'image',
label: 'Login logo',
description: 'Replace the WordPress logo on the login screen.',
},
],
},
{
id: 'theme',
title: 'Theme',
subtitle: 'Colors, styling, and visual customization',
icon: 'dashicons-admin-appearance',
fields: [
{
key: 'theme_preset',
type: 'theme-picker',
label: 'Theme',
description: 'Pick a color for the whole admin interface.',
default: 'indigo',
},
{
key: 'font_family',
type: 'font-picker',
label: 'Font family',
description: 'Google Font used across the Aurora interface.',
},
],
},
{
id: 'whitelabel',
title: 'White Label',
subtitle: 'Rebrand and customize interface text and icons',
icon: 'dashicons-tag',
fields: [
{
key: 'admin_favicon',
type: 'image',
label: 'Admin favicon',
description: 'Optional favicon to replace the WordPress favicon in the admin.',
},
{
key: 'plugin_name',
type: 'text',
label: 'Rename Aurora Admin',
description:
"This will rename Aurora Admin in the plugins list as well as renaming its settings link.",
placeholder: 'Aurora Admin',
},
{
key: 'text_replacements',
type: 'repeater',
label: 'Text Replacement',
description:
'Customize the text displayed in the WordPress admin area. Enter original words or phrases and their replacements to white-label the interface.',
columns: ['Find', 'Replace with'],
},
],
},
{
id: 'menu',
title: 'Menu',
subtitle: 'Admin menu behavior and interaction settings',
icon: 'dashicons-menu',
fields: [
{
key: 'menu_search',
type: 'toggle',
label: 'Menu search',
description: 'Show a search box at the top of the admin menu.',
},
],
},
{
id: 'posts',
title: 'Posts',
subtitle: 'Post management and display preferences',
icon: 'dashicons-admin-post',
fields: [
{
key: 'modern_posts',
type: 'toggle',
label: 'Modern posts table',
description: 'Use the Aurora posts management interface.',
default: true,
},
],
},
{
id: 'pages',
title: 'Pages',
subtitle: 'Page management and display preferences',
icon: 'dashicons-admin-page',
fields: [
{
key: 'modern_pages',
type: 'toggle',
label: 'Modern pages table',
description: 'Use the Aurora pages management interface.',
default: true,
},
],
},
{
id: 'plugins',
title: 'Plugins',
subtitle: 'Plugin management interface options',
icon: 'dashicons-admin-plugins',
fields: [
{
key: 'modern_plugins',
type: 'toggle',
label: 'Modern plugins page',
description: 'Use the Aurora plugins management interface.',
default: true,
},
],
},
{
id: 'dashboard',
title: 'Dashboard',
subtitle: 'Custom dashboard and admin interface settings',
icon: 'dashicons-dashboard',
fields: [
{
key: 'use_custom_dashboard',
type: 'toggle',
label: 'Custom dashboard',
description: "Replace the WordPress dashboard with Aurora's dashboard.",
default: true,
},
],
},
{
id: 'analytics',
title: 'Analytics',
subtitle: 'Built-in analytics and tracking settings',
icon: 'dashicons-chart-bar',
fields: [
{
key: 'enable_analytics',
type: 'toggle',
label: 'Enable analytics',
description: 'Track first-party visitor analytics for the dashboard.',
default: true,
},
{
key: 'track_admins',
type: 'toggle',
label: 'Track logged-in admins',
description: 'Include administrator visits in analytics (off by default).',
},
],
},
{
id: 'media',
title: 'Media',
subtitle: 'Media library and upload management settings',
icon: 'dashicons-admin-media',
fields: [
{
key: 'modern_media',
type: 'toggle',
label: 'Modern media library',
description: 'Use the Aurora media library interface.',
default: true,
},
{
key: 'enable_svg',
type: 'toggle',
label: 'Allow SVG uploads',
description: 'Permit SVG files to be uploaded to the media library.',
},
],
},
{
id: 'users',
title: 'Users',
subtitle: 'User management and administration settings',
icon: 'dashicons-admin-users',
fields: [
{
key: 'modern_users',
type: 'toggle',
label: 'Modern users page',
description: 'Use the Aurora users management interface.',
default: true,
},
],
},
{
id: 'comments',
title: 'Comments',
subtitle: 'Comment management and administration',
icon: 'dashicons-admin-comments',
fields: [
{
key: 'modern_comments',
type: 'toggle',
label: 'Modern comments page',
description: 'Use the Aurora comments management interface.',
default: true,
},
],
},
{
id: 'image-formats',
title: 'Modern Image Formats',
subtitle: 'Automatically generate WebP/AVIF versions of uploaded images',
icon: 'dashicons-format-image',
fields: [
{
key: 'image_formats_enabled',
type: 'toggle',
label: 'Enable modern image formats',
description:
'Automatically generate a WebP or AVIF copy of every size of a newly uploaded JPEG or PNG image, and serve it to browsers that support it. Only affects new uploads — existing library images are unaffected until re-uploaded or regenerated with a tool like Regenerate Thumbnails.',
default: true,
},
{
key: 'image_formats_format',
type: 'select',
label: 'Output format',
description:
'Automatic prefers AVIF (smaller files, wider quality range) when the server supports it, falling back to WebP. If your server supports neither, generation is silently skipped — ask your host about enabling GD or Imagick WebP/AVIF support.',
dependsOn: 'image_formats_enabled',
default: 'auto',
options: [
{ value: 'auto', label: 'Automatic (AVIF, falling back to WebP)' },
{ value: 'webp', label: 'WebP only' },
{ value: 'avif', label: 'AVIF only' },
], ],
}, },
{ {
key: 'image_formats_picture_element', id: 'analytics',
type: 'toggle', title: 'Analytics',
label: 'Serve via <picture> element', subtitle: 'Built-in analytics and tracking settings',
description: icon: 'dashicons-chart-bar',
'Rewrite <img> tags (post content and post thumbnails) into a <picture> element offering the modern format with the original JPEG/PNG as a fallback. Turn this off if it conflicts with your theme’s image styling, while still generating the files for other tools to use.', fields: [
dependsOn: 'image_formats_enabled', {
default: true, key: 'enable_analytics',
type: 'toggle',
label: 'Enable analytics',
description: 'Track first-party visitor analytics for the dashboard.',
default: true,
},
{
key: 'track_admins',
type: 'toggle',
label: 'Track logged-in admins',
description: 'Include administrator visits in analytics (off by default).',
},
],
},
],
},
{
id: 'appearance',
title: 'Appearance',
icon: 'dashicons-admin-appearance',
categories: [
{
id: 'theme',
title: 'Theme',
subtitle: 'Colors, styling, and visual customization',
icon: 'dashicons-admin-appearance',
fields: [
{
key: 'theme_preset',
type: 'theme-picker',
label: 'Theme',
description: 'Pick a color for the whole admin interface.',
default: 'indigo',
},
{
key: 'font_family',
type: 'font-picker',
label: 'Font family',
description: 'Google Font used across the Aurora interface.',
},
],
},
{
id: 'whitelabel',
title: 'White Label',
subtitle: 'Rebrand and customize interface text and icons',
icon: 'dashicons-tag',
fields: [
{
key: 'admin_favicon',
type: 'image',
label: 'Admin favicon',
description: 'Optional favicon to replace the WordPress favicon in the admin.',
},
{
key: 'plugin_name',
type: 'text',
label: 'Rename Aurora Admin',
description:
'This will rename Aurora Admin in the plugins list as well as renaming its settings link.',
placeholder: 'Aurora Admin',
},
{
key: 'text_replacements',
type: 'repeater',
label: 'Text Replacement',
description:
'Customize the text displayed in the WordPress admin area. Enter original words or phrases and their replacements to white-label the interface.',
columns: ['Find', 'Replace with'],
},
],
},
{
id: 'login',
title: 'Login',
subtitle: 'Customize login page appearance and security',
icon: 'dashicons-lock',
fields: [
{
key: 'style_login',
type: 'toggle',
label: 'Style login page',
description: 'Apply the Aurora theme to the WordPress login screen.',
},
{
key: 'login_logo',
type: 'image',
label: 'Login logo',
description: 'Replace the WordPress logo on the login screen.',
},
],
},
{
id: 'menu',
title: 'Menu',
subtitle: 'Admin menu behavior and interaction settings',
icon: 'dashicons-menu',
fields: [
{
key: 'menu_search',
type: 'toggle',
label: 'Menu search',
description: 'Show a search box at the top of the admin menu.',
},
],
},
],
},
{
id: 'screens',
title: 'Screens',
icon: 'dashicons-desktop',
categories: [
{
id: 'dashboard',
title: 'Dashboard',
subtitle: 'Custom dashboard and admin interface settings',
icon: 'dashicons-dashboard',
fields: [
{
key: 'use_custom_dashboard',
type: 'toggle',
label: 'Custom dashboard',
description: "Replace the WordPress dashboard with Aurora's dashboard.",
default: true,
},
],
},
{
id: 'content-tables',
title: 'Content tables',
subtitle: 'Choose which admin list screens use the Aurora interface',
icon: 'dashicons-editor-table',
fields: [
{
key: 'modern_posts',
type: 'toggle',
label: 'Posts',
description: 'Use the Aurora posts management interface.',
default: true,
},
{
key: 'modern_pages',
type: 'toggle',
label: 'Pages',
description: 'Use the Aurora pages management interface.',
default: true,
},
{
key: 'modern_media',
type: 'toggle',
label: 'Media library',
description: 'Use the Aurora media library interface.',
default: true,
},
{
key: 'modern_users',
type: 'toggle',
label: 'Users',
description: 'Use the Aurora users management interface.',
default: true,
},
{
key: 'modern_comments',
type: 'toggle',
label: 'Comments',
description: 'Use the Aurora comments management interface.',
default: true,
},
{
key: 'modern_plugins',
type: 'toggle',
label: 'Plugins',
description: 'Use the Aurora plugins management interface.',
default: true,
},
],
},
{
id: 'admin-takeover',
title: 'Admin Takeover',
subtitle: 'Replace the remaining native WordPress admin screens with Aurora',
icon: 'dashicons-shield',
fields: [
{
key: 'full_admin_takeover',
type: 'toggle',
label: 'Full admin takeover',
description:
'Replace Media Upload, Add User, Profile, Appearance, Tools, and native Settings screens with Aurora equivalents. Off by default — these cover more ground than Posts/Pages/Media/Users/Comments, so it’s opt-in rather than on by default.',
default: false,
},
],
},
],
},
{
id: 'productivity',
title: 'Productivity',
icon: 'dashicons-superhero-alt',
categories: [
{
id: 'image-formats',
title: 'Modern Image Formats',
subtitle: 'Automatically generate WebP/AVIF versions of uploaded images',
icon: 'dashicons-format-image',
fields: [
{
key: 'image_formats_enabled',
type: 'toggle',
label: 'Enable modern image formats',
description:
'Automatically generate a WebP or AVIF copy of every size of a newly uploaded JPEG or PNG image, and serve it to browsers that support it. Only affects new uploads — existing library images are unaffected until re-uploaded or regenerated with a tool like Regenerate Thumbnails.',
default: true,
},
{
key: 'image_formats_format',
type: 'select',
label: 'Output format',
description:
'Automatic prefers AVIF (smaller files, wider quality range) when the server supports it, falling back to WebP. If your server supports neither, generation is silently skipped — ask your host about enabling GD or Imagick WebP/AVIF support.',
dependsOn: 'image_formats_enabled',
default: 'auto',
options: [
{ value: 'auto', label: 'Automatic (AVIF, falling back to WebP)' },
{ value: 'webp', label: 'WebP only' },
{ value: 'avif', label: 'AVIF only' },
],
},
{
key: 'image_formats_picture_element',
type: 'toggle',
label: 'Serve via <picture> element',
description:
'Rewrite <img> tags (post content and post thumbnails) into a <picture> element offering the modern format with the original JPEG/PNG as a fallback. Turn this off if it conflicts with your theme’s image styling, while still generating the files for other tools to use.',
dependsOn: 'image_formats_enabled',
default: true,
},
],
},
{
id: 'media',
title: 'Media',
subtitle: 'Media library and upload options',
icon: 'dashicons-admin-media',
fields: [
{
key: 'enable_svg',
type: 'toggle',
label: 'Allow SVG uploads',
description: 'Permit SVG files to be uploaded to the media library.',
},
],
}, },
], ],
}, },
{ {
id: 'add-ons', id: 'add-ons',
title: 'Add-ons', title: 'Add-ons',
subtitle: 'Standalone companion plugins',
icon: 'dashicons-admin-plugins', icon: 'dashicons-admin-plugins',
fields: [ categories: [
{ {
key: 'file_manager_addon', id: 'add-ons',
type: 'companion-plugin', title: 'Add-ons',
label: 'Aurora File Manager', subtitle: 'Standalone companion plugins',
description: icon: 'dashicons-admin-plugins',
'Browse, edit, and manage your site’s files (themes, plugins, uploads, and more) directly from wp-admin. Distributed as a separate plugin rather than bundled here, since WordPress.org’s Plugin Directory policy doesn’t allow this category of functionality in a directory-listed plugin — restrictions or not.', fields: [
statusEndpoint: '/companion-plugins/file-manager/status', {
installEndpoint: '/companion-plugins/file-manager/install', key: 'file_manager_addon',
manageUrl: 'admin.php?page=aurora-file-manager', type: 'companion-plugin',
}, label: 'Aurora File Manager',
{ description:
key: 'database_explorer_addon', 'Browse, edit, and manage your site’s files (themes, plugins, uploads, and more) directly from wp-admin. Distributed as a separate plugin rather than bundled here, since WordPress.org’s Plugin Directory policy doesn’t allow this category of functionality in a directory-listed plugin — restrictions or not.',
type: 'companion-plugin', statusEndpoint: '/companion-plugins/file-manager/status',
label: 'Aurora Database Explorer', installEndpoint: '/companion-plugins/file-manager/install',
description: manageUrl: 'admin.php?page=aurora-file-manager',
'A Supabase-style database browser inside wp-admin — see every table with row counts and sizes, browse paginated data, and run your own read-only SELECT/SHOW/DESCRIBE/EXPLAIN queries. Distributed as a separate plugin rather than bundled here, since WordPress.org’s Plugin Directory review treats direct database-query tooling the same way it treats file-management functionality.', },
statusEndpoint: '/companion-plugins/database-explorer/status', {
installEndpoint: '/companion-plugins/database-explorer/install', key: 'database_explorer_addon',
manageUrl: 'admin.php?page=aurora-database-explorer', type: 'companion-plugin',
}, label: 'Aurora Database Explorer',
{ description:
key: 'site_backup_addon', 'A Supabase-style database browser inside wp-admin — see every table with row counts and sizes, browse paginated data, and run your own read-only SELECT/SHOW/DESCRIBE/EXPLAIN queries. Distributed as a separate plugin rather than bundled here, since WordPress.org’s Plugin Directory review treats direct database-query tooling the same way it treats file-management functionality.',
type: 'companion-plugin', statusEndpoint: '/companion-plugins/database-explorer/status',
label: 'Aurora Site Backup', installEndpoint: '/companion-plugins/database-explorer/install',
description: manageUrl: 'admin.php?page=aurora-database-explorer',
'Full site backup (database + files) and restore-in-place, on demand or on a recurring schedule, stored locally or on your own S3-compatible or Google Drive remote storage. Distributed as a separate plugin rather than bundled here, to keep Aurora Admin’s own footprint away from arbitrary file-write functionality.', },
statusEndpoint: '/companion-plugins/site-backup/status', {
installEndpoint: '/companion-plugins/site-backup/install', key: 'site_backup_addon',
manageUrl: 'admin.php?page=aurora-site-backup', type: 'companion-plugin',
}, label: 'Aurora Site Backup',
], description:
}, 'Full site backup (database + files) and restore-in-place, on demand or on a recurring schedule, stored locally or on your own S3-compatible or Google Drive remote storage. Distributed as a separate plugin rather than bundled here, to keep Aurora Admin’s own footprint away from arbitrary file-write functionality.',
{ statusEndpoint: '/companion-plugins/site-backup/status',
id: 'admin-takeover', installEndpoint: '/companion-plugins/site-backup/install',
title: 'Admin Takeover', manageUrl: 'admin.php?page=aurora-site-backup',
subtitle: 'Replace the remaining native WordPress admin screens with Aurora', },
icon: 'dashicons-shield', ],
fields: [
{
key: 'full_admin_takeover',
type: 'toggle',
label: 'Full admin takeover',
description:
'Replace Media Upload, Add User, Profile, Appearance, Tools, and native Settings screens with Aurora equivalents. Off by default — these cover more ground than Posts/Pages/Media/Users/Comments, so it’s opt-in rather than on by default.',
default: false,
}, },
], ],
}, },
]; ];
/**
* Flattened category list — every category across all groups, in order.
* Used for default-seeding, active-category lookup, and URL deep-links.
*/
export const settingsCategories = settingsGroups.flatMap((g) => g.categories);