Advance full admin takeover from v1.1 to v1.12
Batches everything built since the 1.0 WP.org submission reset: Login Redirect, the Tools/Export/Import screen takeovers, Modules rebuilt as an addon marketplace, Menu Creator's reorder fix, Activity Log redesigned into a filterable table with Admin/User tabs, dark-theme fixes for Site Health/Personal Data/Updates, and an opt-in Disable Gutenberg toggle. Continues the "nothing stays native" takeover goal and closes gaps found via live testing and the WordPress Plugin Check tool. See CHANGELOG.md for the full per-version breakdown (1.1-1.12). Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
faf9f35992
commit
24be114f9a
@@ -10,22 +10,6 @@ const props = defineProps({
|
||||
|
||||
const visibleCategories = settingsCategories;
|
||||
|
||||
// Shared REST fetcher for field types that need their own API calls beyond
|
||||
// the generic wp/v2/settings save flow (currently just 'companion-plugin').
|
||||
const api = (path, options = {}) =>
|
||||
fetch(`${props.serverData.restUrl}aurora-admin/v1${path}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'X-WP-Nonce': props.serverData.restNonce,
|
||||
'Content-Type': 'application/json',
|
||||
...(options.headers || {}),
|
||||
},
|
||||
}).then(async (r) => {
|
||||
const body = await r.json().catch(() => ({}));
|
||||
if (!r.ok) throw new Error(body.message || 'Request failed');
|
||||
return body;
|
||||
});
|
||||
|
||||
// Working copy of the settings, seeded from the server + field defaults.
|
||||
const settings = reactive({ ...(props.serverData.settings || {}) });
|
||||
visibleCategories.forEach((cat) =>
|
||||
@@ -264,7 +248,6 @@ const importSettings = (e) => {
|
||||
:field="f"
|
||||
:options="optionsFor(f)"
|
||||
:disabled="!!f.dependsOn && !settings[f.dependsOn]"
|
||||
:api="api"
|
||||
v-model="settings[f.key]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -14,9 +14,6 @@ const props = defineProps({
|
||||
// True when this field's `dependsOn` key is falsy — greys out the
|
||||
// control without hiding it, so the relationship stays visible.
|
||||
disabled: { type: Boolean, default: false },
|
||||
// Shared REST fetcher, only used by field types that need their own API
|
||||
// calls beyond the generic wp/v2/settings save flow (companion-plugin).
|
||||
api: { type: Function, default: null },
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
@@ -76,43 +73,14 @@ const pickFont = (name) => {
|
||||
fontOpen.value = false;
|
||||
};
|
||||
const openFontList = () => {
|
||||
fontQuery.value = props.modelValue || '';
|
||||
// Start with an empty query so the whole font list is shown on focus.
|
||||
// Seeding it with the current font filtered the list down to just that
|
||||
// one font, making it impossible to pick a different one without first
|
||||
// clearing the box. The active font stays highlighted via `val === name`.
|
||||
fontQuery.value = '';
|
||||
fontOpen.value = true;
|
||||
};
|
||||
|
||||
// Companion plugin (Aurora File Manager) install card -----------------------
|
||||
const companionStatus = ref(null); // { installed, active } | null while loading
|
||||
const companionBusy = ref(false);
|
||||
const companionError = ref('');
|
||||
|
||||
const loadCompanionStatus = async () => {
|
||||
if (props.field.type !== 'companion-plugin' || !props.api) return;
|
||||
try {
|
||||
companionStatus.value = await props.api(props.field.statusEndpoint);
|
||||
} catch {
|
||||
companionStatus.value = { installed: false, active: false };
|
||||
}
|
||||
};
|
||||
if (props.field.type === 'companion-plugin') {
|
||||
loadCompanionStatus();
|
||||
}
|
||||
|
||||
const installCompanion = async () => {
|
||||
if (!props.api) return;
|
||||
companionBusy.value = true;
|
||||
companionError.value = '';
|
||||
try {
|
||||
const result = await props.api(props.field.installEndpoint, { method: 'POST' });
|
||||
if (!result.success) {
|
||||
companionError.value = result.message || 'Installation failed.';
|
||||
}
|
||||
await loadCompanionStatus();
|
||||
} catch (e) {
|
||||
companionError.value = e.message || 'Installation failed.';
|
||||
} finally {
|
||||
companionBusy.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -273,31 +241,6 @@ const installCompanion = async () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Companion plugin install card -->
|
||||
<div v-else-if="field.type === 'companion-plugin'" class="field__companion">
|
||||
<div v-if="!companionStatus" class="field__companion-status">Checking…</div>
|
||||
<template v-else>
|
||||
<a
|
||||
v-if="companionStatus.active"
|
||||
class="field__companion-manage"
|
||||
:href="field.manageUrl"
|
||||
>
|
||||
Installed & active — open File Manager →
|
||||
</a>
|
||||
<template v-else>
|
||||
<button
|
||||
type="button"
|
||||
class="field__companion-install"
|
||||
:disabled="companionBusy"
|
||||
@click="installCompanion"
|
||||
>
|
||||
{{ companionBusy ? 'Installing…' : (companionStatus.installed ? 'Activate' : 'Install & Activate') }}
|
||||
</button>
|
||||
<p v-if="companionError" class="field__companion-error">{{ companionError }}</p>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Repeater -->
|
||||
<div v-else-if="field.type === 'repeater'" class="field__repeater">
|
||||
<div v-for="(row, i) in rows" :key="i" class="field__repeater-row">
|
||||
@@ -460,20 +403,6 @@ const installCompanion = async () => {
|
||||
.field__font-item:hover { background: var(--aurora-bg-subtle); }
|
||||
.field__font-item--active { color: var(--aurora-accent); }
|
||||
|
||||
/* Companion plugin install card */
|
||||
.field__companion-status { font-size: 0.8125rem; color: var(--aurora-text-muted); }
|
||||
.field__companion-install {
|
||||
border: none; border-radius: var(--aurora-radius-sm); background: var(--aurora-accent); color: #fff;
|
||||
padding: 8px 16px; font-size: 0.8125rem; font-weight: 600; cursor: pointer;
|
||||
}
|
||||
.field__companion-install:disabled { opacity: 0.6; cursor: default; }
|
||||
.field__companion-manage {
|
||||
display: inline-block; font-size: 0.8125rem; font-weight: 600;
|
||||
color: var(--aurora-accent); text-decoration: none;
|
||||
}
|
||||
.field__companion-manage:hover { text-decoration: underline; }
|
||||
.field__companion-error { margin: 8px 0 0; font-size: 0.8125rem; color: #e5484d; }
|
||||
|
||||
@media (max-width: 782px) {
|
||||
.field { grid-template-columns: 1fr; gap: 12px; }
|
||||
}
|
||||
|
||||
@@ -99,7 +99,9 @@ export const settingsGroups = [
|
||||
key: 'font_family',
|
||||
type: 'font-picker',
|
||||
label: 'Font family',
|
||||
description: 'Google Font used across the Aurora interface.',
|
||||
description:
|
||||
'Optional. Leave empty to use your system font (no external requests). ' +
|
||||
'Choosing a font loads it from Google Fonts (fonts.googleapis.com) on each admin page.',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -195,6 +197,46 @@ export const settingsGroups = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'login-redirect',
|
||||
title: 'Login Redirect',
|
||||
subtitle: 'Control where visitors and users land, before and after login',
|
||||
icon: 'dashicons-redo',
|
||||
fields: [
|
||||
{
|
||||
key: 'login_redirect_enabled',
|
||||
type: 'toggle',
|
||||
label: 'Enable login redirects',
|
||||
description:
|
||||
'Turns on the redirects below. This never changes, hides, or blocks your login page — wp-login.php always stays reachable at its normal address, so this can’t lock you out of logging in.',
|
||||
},
|
||||
{
|
||||
key: 'redirect_unauthenticated_url',
|
||||
type: 'text',
|
||||
label: 'Redirect logged-out wp-admin visitors',
|
||||
description:
|
||||
'Send visitors who try to access wp-admin without being logged in to this URL instead of the login screen. Leave empty to keep the normal WordPress behavior.',
|
||||
placeholder: 'https://example.com/',
|
||||
dependsOn: 'login_redirect_enabled',
|
||||
},
|
||||
{
|
||||
key: 'redirect_roles',
|
||||
type: 'multiselect',
|
||||
label: 'Redirect these roles after login',
|
||||
description: 'Users with these roles are sent to the URL below after logging in, instead of the dashboard.',
|
||||
optionsSource: 'roles',
|
||||
dependsOn: 'login_redirect_enabled',
|
||||
},
|
||||
{
|
||||
key: 'redirect_after_login_url',
|
||||
type: 'text',
|
||||
label: 'Redirect to',
|
||||
description: 'Where the roles above land after logging in.',
|
||||
placeholder: 'https://example.com/welcome',
|
||||
dependsOn: 'login_redirect_enabled',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'menu',
|
||||
title: 'Menu',
|
||||
@@ -281,6 +323,22 @@ export const settingsGroups = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'editor',
|
||||
title: 'Editor',
|
||||
subtitle: 'Choose the editor used for posts and pages',
|
||||
icon: 'dashicons-edit',
|
||||
fields: [
|
||||
{
|
||||
key: 'disable_gutenberg',
|
||||
type: 'toggle',
|
||||
label: 'Disable Gutenberg',
|
||||
description:
|
||||
'Use WordPress’s classic editor instead of the block editor for all post types. Off by default.',
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'admin-takeover',
|
||||
title: 'Admin Takeover',
|
||||
@@ -493,51 +551,6 @@ export const settingsGroups = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'add-ons',
|
||||
title: 'Add-ons',
|
||||
icon: 'dashicons-admin-plugins',
|
||||
categories: [
|
||||
{
|
||||
id: 'add-ons',
|
||||
title: 'Add-ons',
|
||||
subtitle: 'Standalone companion plugins',
|
||||
icon: 'dashicons-admin-plugins',
|
||||
fields: [
|
||||
{
|
||||
key: 'file_manager_addon',
|
||||
type: 'companion-plugin',
|
||||
label: 'Aurora File Manager',
|
||||
description:
|
||||
'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.',
|
||||
statusEndpoint: '/companion-plugins/file-manager/status',
|
||||
installEndpoint: '/companion-plugins/file-manager/install',
|
||||
manageUrl: 'admin.php?page=aurora-file-manager',
|
||||
},
|
||||
{
|
||||
key: 'database_explorer_addon',
|
||||
type: 'companion-plugin',
|
||||
label: 'Aurora Database Explorer',
|
||||
description:
|
||||
'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',
|
||||
manageUrl: 'admin.php?page=aurora-database-explorer',
|
||||
},
|
||||
{
|
||||
key: 'site_backup_addon',
|
||||
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',
|
||||
installEndpoint: '/companion-plugins/site-backup/install',
|
||||
manageUrl: 'admin.php?page=aurora-site-backup',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user