Back to Wekan

Design: the Admin Panel's URLs

docs/Design/Page/Admin-Panel-URLs.md

10.559.6 KB
Original Source

Design: the Admin Panel's URLs

Every left-menu entry of the Admin Panel has its own URL.

The panel used to be four addresses — /setting, /people, /admin-reports, /attachments — each opening whichever pane its page happened to open first. Which pane you were looking at was ReactiveVar state and nothing else, so a pane could not be linked to a colleague, bookmarked, opened in a second tab or reached with the back button; /setting always landed on Version even if you had just been in Global Webhooks.

The shape

/admin/<page>/<slug>     the pane

Slugs are lowercase, words separated by -, and say what the pane is.

Under /admin. The four pages sat at the top level — /settings, /people, /attachments — as if they were pages of the app rather than of the Admin Panel, and /attachments is also the path the file server serves attachments from (server/routes/universalFileServer.js), so the panel and the files were claiming one address. The prefix says which they are and keeps them out of everyone else's way.

Every pane is named, the default one included. This used to leave the first pane unnamed — /settings rather than /settings/version — so the address of "Settings" and the address of "Settings showing Version" were the same string. The address is meant to say where you are, and the first pane is somewhere too. The bare /admin/settings still resolves; it redirects to /admin/settings/version rather than being a second name for it.

Settings — /admin/settings

URLPanePane id
/admin/settings/versionVersionversion-setting
/admin/settings/visibilityVisibilitytableVisibilityMode-setting
/admin/settings/announcementAnnouncementannouncement-setting
/admin/settings/accessibilityAccessibilityaccessibility-setting
/admin/settings/translationTranslationtranslation-setting
/admin/settings/pwaPWAlayout-setting
/admin/settings/global-webhooksGlobal Webhookswebhook-setting

People — /admin/people

URLPanePane id
/admin/people/peoplePeoplepeople-setting
/admin/people/loginLoginregistration-setting
/admin/people/emailEmailemail-setting
/admin/people/domainsDomainsdomains-setting
/admin/people/organizationsOrganizationsorg-setting
/admin/people/teamsTeamsteam-setting
/admin/people/locked-usersLocked Userslocked-users-setting
/admin/people/rolesRolesroles-setting
/admin/people/shared-templatesShared templatestemplates-setting

Problems — /admin/problems

URLPanePane id
/admin/problems/summarySummaryreport-summary
/admin/problems/securitySecurityfeatures-security
/admin/problems/notificationsNotificationsfeatures-notifications
/admin/problems/security-reportSecurity Reportreport-security
/admin/problems/impersonationImpersonation Reportreport-impersonation
/admin/problems/performancePerformancefeatures-performance
/admin/problems/speedSpeedreport-speed
/admin/problems/testsTestsreport-tests
/admin/problems/cpuCPU usagereport-cpu
/admin/problems/broken-cardsBroken Cardsreport-broken
/admin/problems/filesFiles Reportreport-files
/admin/problems/rulesRules Reportreport-rules
/admin/problems/boardsBoards Reportreport-boards
/admin/problems/cardsCards Reportreport-cards
/admin/problems/recoveryRecoveryreport-recovery
/admin/problems/databaseDatabase problemsreport-database

Two panes are called Security, and they are different things: the settings pane and the report. security is the settings one, beside notifications and performance; security-report is the report, beside impersonation.

Attachments — /admin/attachments

URLPanePane id
/admin/attachments/backupBackupbackup
/admin/attachments/moveMove Attachmentmove
/admin/attachments/default-save-storageDefault Save Storagedefault-save-storage
/admin/attachments/limitsLimitslimits
/admin/attachments/gridfsMongoDB GridFS Storagegridfs
/admin/attachments/filesystemFilesystem Storagefilesystem
/admin/attachments/s3S3/MinIO Storages3
/admin/attachments/azureAzure Blob Storageazure
/admin/attachments/gcsGoogle Cloud Storagegcs
/admin/attachments/database-migrationDatabase migrationdatabase-migration

The slug is not derived from the pane id

The pane ids are internal and read like it — tableVisibilityMode-setting, layout-setting, report-cpu — while a URL is something a person types, reads and pastes into a chat. /settings/tablevisibilitymode-setting is not an improvement on no URL at all.

So models/lib/adminUrls.js is an explicit map, not a rule, and a guard checks it against the real menus in both directions: every slug names a pane the page actually has, and every menu entry has a slug. Neither failure is visible until somebody clicks that row — a slug naming nothing renders an empty panel, and a pane with no slug simply cannot be linked.

This is also the lesson from allBoardsMultiselectionSidebar: a name derived from another name is wrong the moment the two spellings differ, and it fails silently.

The title bar names the same three things

Admin Panel / Settings / Version. The address names the panel, the page and the pane, and so does the title beside the house icon — "Admin Panel" alone named the building and not the room.

The pane's words are the menu row's own, so the title and the row that opened it always agree. They are a second copy of them: the header is a separate Blaze instance from the Admin Panel's pages and must not import them — doing that once ran a page module before its own template was registered, and the throw aborted every module after it — so it reads the slug from the URL and looks the title up in ADMIN_PANE_TITLES. Nothing but a guard keeps that copy equal to the menu, and tests/adminUrls.test.cjs is it.

Two forms, the ones a menu entry already has: a translation key, or a literal label for a name that is not translated (PWA is a product name).

What happens on a bad slug

It falls back to the page's default pane. A URL is typed, and a typo must not render an empty panel.

Old URLs

OldNow
/setting/admin/settings/version
/information/settings — Version, which it used to be a page of
/translation/admin/settings/translation

They redirect with the redirect their trigger is handed, never with FlowRouter.go() — a go() from inside triggersEnter runs while that route is still entering and is swallowed, so nothing renders and the browser keeps showing whatever page it was on.

They used to hand the pane over in a Session value the page consumed once. Every pane has an address now, so they redirect to it: the pane ends up in the URL, where it can be linked, bookmarked and gone back to.

How a page opens the pane

The route resolves the slug and puts the pane id in a Session value — settingsOpenPane, peopleOpenPane, problemsOpenPane, attachmentsOpenPane — which the page reads in an autorun. It is reactive rather than a one-shot read on purpose: following a link to another pane while the page is already open runs the route action again without re-creating the template, so a one-shot read would leave you on the pane you were already looking at.

Clicking a menu row does the same thing in reverse: it opens the pane and then FlowRouter.gos to that pane's URL. go, not replace, so Back returns to the previous pane instead of leaving the Admin Panel — and only when the path would actually change, or every click becomes a navigation to where you already are.

Each page has one function that opens a pane by id (openSettingsPane, openPane, openReportPane, activeSection.set), used by both the URL and the click, so "which state is this pane" is answered once instead of in two places that can disagree.

File PathFile TypeDescription
models/lib/adminUrls.js.js module, pureThe slug ↔ pane map, the path builder, and the pane titles the header bar shows. No Meteor, so it is unit-testable.
config/router.js.js routesThe four /admin/<page>/:pane routes and the old-URL redirects, built from the same map.
client/components/settings/settingBody.js.js Blaze template logicSettings: openSettingsPane, the URL autorun, the menu click.
client/components/settings/peopleBody.js.js Blaze template logicPeople: openPane, the URL autorun, the menu click.
client/components/settings/adminReports.js.js Blaze template logicProblems: openReportPane, the URL autorun, the menu click.
client/components/settings/attachments.js.js Blaze template logicAttachments: activeSection, the URL autorun, the menu click.
tests/adminUrls.test.cjs.cjs Node testThe map against the real menus, both directions; the fallback; the routes; and that a click updates the URL.
tests/adminOldUrlRedirect.test.cjs.cjs Node testThat the old page URLs redirect to the pane they used to be.