Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions assets/js/dock.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ var allTerrainFormsDock = function(exports) {
windowId: THEMES
});
}
if (config2?.canEdit && config2?.adminUrl) {
submenu.push({
title: "Import forms",
url: `${config2.adminUrl}admin.php?page=allterrain-forms-import`
});
}
if (config2?.canEdit && config2?.devMode) {
submenu.push({
title: "Demo data",
Expand Down
2 changes: 1 addition & 1 deletion assets/js/dock.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,19 @@ can be read aloud, selected and searched; resizing is a reflow rather than a
redraw; and the plugin ships no charting dependency to every site that installs
it.

### Import, the one page with no native window

**Forms → Import** is deliberately not a native window. It is a server-rendered
page whose buttons `POST` to `admin-post.php`, which is the right shape for a
one-time migration and the wrong shape for a window rendering into the shell's
own DOM. With the shell up it is reached instead through the dock tile's
`Import forms` row — the one row carrying a real `url`, which the shell opens
as a window of its own.

That row is load-bearing rather than convenient. With the shell active the
Forms admin menu is not registered at all (see below), so a page with neither a
native window nor a dock row exists at a URL nobody can navigate to.

### The admin-URL handoff

Every surface — builder, entries, analytics, Theme Studio — also has an admin
Expand Down
14 changes: 14 additions & 0 deletions src/dock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface RuntimeConfig {
canEdit?: boolean;
canRead?: boolean;
devMode?: boolean;
adminUrl?: string;
}

const config: RuntimeConfig | undefined = ( window as unknown as { allTerrainForms?: RuntimeConfig } ).allTerrainForms;
Expand Down Expand Up @@ -130,6 +131,19 @@ export function submenuFor( config: RuntimeConfig | undefined ): SubmenuRow[] {
} );
}

// The one row that is a URL rather than a native window, because the import
// page is one: a server-rendered page whose buttons POST to `admin-post.php`.
// The shell opens a row with a real `url` as a window of its own, which is
// the only way this page is reachable on a desktop — with the shell up, the
// Forms admin menu is not registered, so a page with no native window and no
// row here exists at a URL nobody can get to.
if ( config?.canEdit && config?.adminUrl ) {
submenu.push( {
title: 'Import forms',
url: `${ config.adminUrl }admin.php?page=allterrain-forms-import`,
} );
}

// Developer mode only, and last — it writes several hundred entries into the
// database, which is not something to leave one hover away from "Themes" on a
// site that is collecting real enquiries.
Expand Down
27 changes: 27 additions & 0 deletions tests/vitest/dock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,30 @@ describe( 'the rest of the menu', () => {
expect( submenuFor( config( {} ) ) ).toEqual( [] );
} );
} );

describe( 'the import row', () => {
const admin = { canEdit: true, canRead: true, adminUrl: 'http://example.com/wp-admin/' };

it( 'is offered to somebody who may build forms', () => {
expect( titles( admin ) ).toContain( 'Import forms' );
} );

it( 'carries a real URL rather than a callback', () => {
// The import page is a server-rendered page whose buttons POST, not a
// native window — the shell opens a row with a `url` as its own window,
// and that is the only way the page is reachable with the shell up.
const row = submenuFor( config( admin ) ).find( ( candidate ) => candidate.title === 'Import forms' );

expect( row?.url ).toBe( 'http://example.com/wp-admin/admin.php?page=allterrain-forms-import' );
expect( row?.onSelect ).toBeUndefined();
} );

it( 'is absent for somebody who may only read entries', () => {
expect( titles( { canRead: true, adminUrl: 'http://example.com/wp-admin/' } ) ).not.toContain( 'Import forms' );
} );

it( 'is absent when there is no admin URL to point at', () => {
// Rather than a row that opens `undefinedadmin.php`.
expect( titles( { canEdit: true, canRead: true } ) ).not.toContain( 'Import forms' );
} );
} );
Loading