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:
co-authored by
Claude Opus 4.8
parent
ce8fcc8fdd
commit
1c8c351654
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "aurora-admin-app",
|
||||
"version": "2.16.0",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "aurora-admin-app",
|
||||
"version": "2.16.0",
|
||||
"version": "3.1.0",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "^6.3.1",
|
||||
"@codemirror/lang-html": "^6.4.11",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
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 { applyThemePalette, applyFontFamily } from './applyLiveTheme.js';
|
||||
|
||||
@@ -45,6 +45,29 @@ const activeCategory = computed(
|
||||
() => 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
|
||||
// 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
|
||||
@@ -56,6 +79,8 @@ const activeCategory = computed(
|
||||
const contentEl = ref(null);
|
||||
const selectCategory = (id) => {
|
||||
activeId.value = id;
|
||||
const g = groupOfCategory(id);
|
||||
if (g) openState[g.id] = true;
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('category', id);
|
||||
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 filteredCategories = computed(() => {
|
||||
const searching = computed(() => query.value.trim().length > 0);
|
||||
const filteredGroups = computed(() => {
|
||||
const q = query.value.trim().toLowerCase();
|
||||
if (!q) return visibleCategories;
|
||||
return visibleCategories.filter(
|
||||
if (!q) return settingsGroups;
|
||||
return settingsGroups
|
||||
.map((g) => {
|
||||
const groupMatch = g.title.toLowerCase().includes(q);
|
||||
const categories = g.categories.filter(
|
||||
(c) =>
|
||||
c.title.toLowerCase().includes(q) || c.subtitle.toLowerCase().includes(q)
|
||||
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.
|
||||
@@ -172,22 +207,39 @@ const importSettings = (e) => {
|
||||
<input v-model="query" type="text" placeholder="Search settings…" />
|
||||
</div>
|
||||
|
||||
<ul class="settings__list">
|
||||
<li v-for="cat in filteredCategories" :key="cat.id">
|
||||
<ul class="settings__groups">
|
||||
<li v-for="group in filteredGroups" :key="group.id" class="settings__group">
|
||||
<button
|
||||
type="button"
|
||||
class="settings__group-head"
|
||||
:aria-expanded="isGroupOpen(group.id) || searching"
|
||||
@click="toggleGroup(group.id)"
|
||||
>
|
||||
<span class="settings__group-icon dashicons" :class="group.icon" />
|
||||
<span class="settings__group-title">{{ group.title }}</span>
|
||||
<span
|
||||
class="settings__group-caret dashicons dashicons-arrow-down-alt2"
|
||||
:class="{ 'is-collapsed': !isGroupOpen(group.id) && !searching }"
|
||||
/>
|
||||
</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"><span class="dashicons" :class="cat.icon" /></span>
|
||||
<span class="settings__cat-text">
|
||||
<span class="settings__cat-icon dashicons" :class="cat.icon" />
|
||||
<span class="settings__cat-title">{{ cat.title }}</span>
|
||||
<span class="settings__cat-sub">{{ cat.subtitle }}</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li v-if="!filteredGroups.length" class="settings__empty">
|
||||
No settings match “{{ query }}”.
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- Right content panel -->
|
||||
@@ -280,27 +332,45 @@ const importSettings = (e) => {
|
||||
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 {
|
||||
display: flex; align-items: center; gap: 12px; width: 100%;
|
||||
padding: 10px; border: none; background: none; cursor: pointer;
|
||||
border-radius: 12px; text-align: left; margin-bottom: 2px;
|
||||
display: flex; align-items: center; gap: 10px; width: 100%;
|
||||
padding: 8px 10px; border: none; background: none; cursor: pointer;
|
||||
border-radius: 10px; text-align: left; margin-bottom: 1px;
|
||||
color: var(--aurora-text);
|
||||
}
|
||||
.settings__cat:hover { background: var(--aurora-bg-subtle); }
|
||||
.settings__cat--active { background: var(--aurora-accent-soft); }
|
||||
.settings__cat-icon {
|
||||
width: 34px; height: 34px; flex-shrink: 0;
|
||||
border-radius: 9px; background: var(--aurora-bg-subtle);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 16px; width: 18px; height: 18px; flex-shrink: 0;
|
||||
color: var(--aurora-text-muted);
|
||||
}
|
||||
.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.875rem; font-weight: 600; color: var(--aurora-text); }
|
||||
.settings__cat--active .settings__cat-title { color: var(--aurora-accent); }
|
||||
.settings__cat-sub {
|
||||
font-size: 0.75rem; color: var(--aurora-text-muted);
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
.settings__cat-title { font-size: 0.8125rem; font-weight: 500; }
|
||||
.settings__cat--active .settings__cat-title { color: var(--aurora-accent); font-weight: 600; }
|
||||
|
||||
.settings__empty {
|
||||
padding: 12px 10px; font-size: 0.8125rem; color: var(--aurora-text-muted);
|
||||
}
|
||||
|
||||
/* Right content — no background/border of its own, same reasoning.
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
/**
|
||||
* 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
|
||||
* option, saved via the wp/v2/settings REST route.
|
||||
*
|
||||
* Categories are organized into top-level groups. Each group renders as a
|
||||
* 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',
|
||||
title: 'General',
|
||||
icon: 'dashicons-admin-settings',
|
||||
categories: [
|
||||
{
|
||||
id: 'general',
|
||||
title: 'General',
|
||||
@@ -47,25 +55,33 @@ export const settingsCategories = [
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'login',
|
||||
title: 'Login',
|
||||
subtitle: 'Customize login page appearance and security',
|
||||
icon: 'dashicons-lock',
|
||||
id: 'analytics',
|
||||
title: 'Analytics',
|
||||
subtitle: 'Built-in analytics and tracking settings',
|
||||
icon: 'dashicons-chart-bar',
|
||||
fields: [
|
||||
{
|
||||
key: 'style_login',
|
||||
key: 'enable_analytics',
|
||||
type: 'toggle',
|
||||
label: 'Style login page',
|
||||
description: 'Apply the Aurora theme to the WordPress login screen.',
|
||||
label: 'Enable analytics',
|
||||
description: 'Track first-party visitor analytics for the dashboard.',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'login_logo',
|
||||
type: 'image',
|
||||
label: 'Login logo',
|
||||
description: 'Replace the WordPress logo on the login screen.',
|
||||
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',
|
||||
@@ -104,7 +120,7 @@ export const settingsCategories = [
|
||||
type: 'text',
|
||||
label: 'Rename Aurora Admin',
|
||||
description:
|
||||
"This will rename Aurora Admin in the plugins list as well as renaming its settings link.",
|
||||
'This will rename Aurora Admin in the plugins list as well as renaming its settings link.',
|
||||
placeholder: 'Aurora Admin',
|
||||
},
|
||||
{
|
||||
@@ -117,6 +133,26 @@ export const settingsCategories = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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',
|
||||
@@ -131,51 +167,13 @@ export const settingsCategories = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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: 'screens',
|
||||
title: 'Screens',
|
||||
icon: 'dashicons-desktop',
|
||||
categories: [
|
||||
{
|
||||
id: 'dashboard',
|
||||
title: 'Dashboard',
|
||||
@@ -192,77 +190,78 @@ export const settingsCategories = [
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'analytics',
|
||||
title: 'Analytics',
|
||||
subtitle: 'Built-in analytics and tracking settings',
|
||||
icon: 'dashicons-chart-bar',
|
||||
id: 'content-tables',
|
||||
title: 'Content tables',
|
||||
subtitle: 'Choose which admin list screens use the Aurora interface',
|
||||
icon: 'dashicons-editor-table',
|
||||
fields: [
|
||||
{
|
||||
key: 'enable_analytics',
|
||||
key: 'modern_posts',
|
||||
type: 'toggle',
|
||||
label: 'Enable analytics',
|
||||
description: 'Track first-party visitor analytics for the dashboard.',
|
||||
label: 'Posts',
|
||||
description: 'Use the Aurora posts management interface.',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'track_admins',
|
||||
key: 'modern_pages',
|
||||
type: 'toggle',
|
||||
label: 'Track logged-in admins',
|
||||
description: 'Include administrator visits in analytics (off by default).',
|
||||
label: 'Pages',
|
||||
description: 'Use the Aurora pages management interface.',
|
||||
default: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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',
|
||||
label: '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',
|
||||
label: 'Users',
|
||||
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',
|
||||
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',
|
||||
@@ -302,6 +301,27 @@ export const settingsCategories = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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',
|
||||
title: 'Add-ons',
|
||||
icon: 'dashicons-admin-plugins',
|
||||
categories: [
|
||||
{
|
||||
id: 'add-ons',
|
||||
title: 'Add-ons',
|
||||
@@ -340,20 +360,12 @@ export const settingsCategories = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
Reference in New Issue
Block a user