Skip to content

[Portal] Framework-first Create Application wizard#5737

Draft
fungc-io wants to merge 85 commits into
authgear:mainfrom
fungc-io:fungc-io/dev-2392-create-application-framework-first-wizard
Draft

[Portal] Framework-first Create Application wizard#5737
fungc-io wants to merge 85 commits into
authgear:mainfrom
fungc-io:fungc-io/dev-2392-create-application-framework-first-wizard

Conversation

@fungc-io

Copy link
Copy Markdown
Member

Summary

Replaces the type-first "Create Application" screen with a framework-first wizard and builds out Quick Start tabs per client kind. The portal's OAuth-app management UX is redesigned around what the user is building (React, Django, iOS, etc.) instead of OAuth taxonomy.

Backend

  • New optional x_framework field on OAuthClientConfig (pkg/lib/config/oauth.go). JSON-schema enum of allowed framework ids. Nullable, additive, no migration needed. The auth server never branches on this field — it's a portal-only label.

Portal — Create flow

  • Apps-list header now exposes a split button: Application → new framework wizard at /configuration/apps/add, Machine-to-Machine → extracted M2M flow at /configuration/apps/add-m2m.
  • New wizard renders a framework grid (Website + Mobile · Desktop sections) using ChoiceButton tiles (consistent with Login Methods). Picking a server framework reveals an inline Stage 2 ("OIDC tokens" / "Cookie session via reverse proxy") — defaults to OIDC tokens with the nginx docs link clickable below.
  • Frameworks → application-type mapping is encapsulated in frameworks.ts via resolveType(stage2?). Submitting writes both x_application_type and x_framework.
  • On success the wizard deep-links to …/edit?tab=quick-start.

Portal — App details

  • New header above the tabs: framework icon, name, type + monospaced client ID with copy.
  • Apps-list redesigned: each row shows the framework icon, name, and a Type · Framework subline.
  • Settings tab: visual separators between sections; the Cookie-based authentication note is hidden for non-cookie clients.

Portal — Quick Start tab

A new tab for every framework-typed client (spa / traditional_webapp / native / confidential), in addition to the existing M2M Quick Start.

  • Shows the selected framework with a Change framework dialog (same ChoiceButton grid as the create wizard, filtered to same-type frameworks). Changes save on Apply via saveWithState.
  • Cookie SSO clients get an nginx-specific tutorial body and a Read user session in your code code snippet per framework (Express / Flask / Laravel / Java Spring Boot / ASP.NET Core MVC), with copy buttons.
  • "Other OIDC/SAML compatible" gets a dedicated panel with Client ID, Client Secret (with Reveal / copy), OpenID scope, and the OIDC endpoints (Login / Userinfo / Token / End Session / JWK Set).
  • SAML tab is hidden for OIDC-only confidential frameworks (Express / Flask / Laravel / Java / ASP.NET); kept for legacy and other-oidc clients.
  • Type-label rename in i18n only: "Single Page Application" → "Public Client", "Traditional Web Application" → "Cookie SSO", "OIDC/SAML Client Application" → "Confidential Client". Enum values unchanged.

Misc fixes / polish

  • Wizard auto-focuses the Name input on load.
  • Empty-state on Quick Start (no framework set) redesigned as a centered card.
  • Responsive framework grid: repeat(auto-fill, minmax(240px, 1fr)) so columns reflow on narrow viewports.
  • Express moved from the SPA cluster to the server cluster in the catalog order.

ref DEV-2392

Related: DEV-2532 (richer per-framework Quick Start content) — out of scope here.

Test plan

  • Backend: `go test ./pkg/lib/config/`
  • Backend: `go build ./...`
  • Portal: `npm run typecheck`
  • Portal: `npx jest` (168 tests across 27 suites)
  • Manual — split button menu shows both Application and Machine-to-Machine options
  • Manual — SPA framework (React) → no Stage 2; submits with `x_application_type=spa`, `x_framework=react`
  • Manual — Server framework (Flask, Java, ASP.NET) → Stage 2 visible, OIDC tokens preselected
  • Manual — Stage 2 OIDC tokens → `confidential`; Cookie SSO → `traditional_webapp`; switching framework clears Stage 2 silently
  • Manual — Reserved/duplicate name → inline error
  • Manual — Submit lands on `…/edit?tab=quick-start`
  • Manual — Quick Start tab visible for spa / traditional_webapp / native / confidential / m2m
  • Manual — Change framework dialog (filtered per type) → Apply saves immediately
  • Manual — Cookie SSO client: tutorial points at `/backend-api/nginx`, per-framework code snippet renders with copy
  • Manual — Other OIDC/SAML compatible: OIDC endpoints panel renders with Reveal button on Client Secret
  • Manual — Confidential + per-framework: SAML tab hidden; confidential + other-oidc or legacy: SAML tab shown
  • Manual — Apps list redesign: icon + Type · Framework subline; M2M uses server icon

🤖 Generated with Claude Code

@tung2744

Copy link
Copy Markdown
Contributor

@fungc-io Should I review this?

@fungc-io
fungc-io marked this pull request as draft May 27, 2026 12:54
@fungc-io

Copy link
Copy Markdown
Member Author

@tung2744 , no, it's still in progress, i've changed it to draft
Thanks

fungc-io and others added 27 commits July 8, 2026 13:34
Additive, nullable. JSON schema enum lists allowed framework IDs.
No behavior change; field is a label used by the portal.

ref DEV-2392
ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Behavior unchanged. Route wired in the next commit.

ref DEV-2392
Replaces the type-first ChoiceGroup with a framework grid and an
inline Stage-2 callout for server-side frameworks. Submits the
chosen framework as x_framework alongside the resolved
x_application_type. M2M flow extracted to its own screen in a
previous commit.

ref DEV-2392
ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
constructConfig was called on every render via useMemo, but threw
when the user had not yet picked a framework — crashing the screen
on initial mount. Return the input config unchanged in that state
so the form stays clean until the user makes a selection.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the constructConfig guard: a server framework selected
without a stage-2 choice would still crash via resolveType. Return
undefined so no secret instruction is emitted until the user has
completed the Stage 2 selection.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reuses the same FluentUI CompoundButton-based ChoiceButton used by
the Login Methods authentication selectors (Passwordless / Enter
password). Visual treatment of selected/unselected states matches
the rest of the portal automatically.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The checked ChoiceButton draws a 1px outline outside its
border-box. Without padding on the grid, that outline gets clipped
against the parent's overflow boundary on the outermost cards
(React, Angular, Next.js, Other SPAs).

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the 16 placeholder SVG files and switch the catalog from
file-import logos to Tabler glyph names (already loaded in the
portal via the iconfont). The visual style now matches
LoginMethodIcon and other Tabler usages in the portal.

Frameworks without a Tabler brand glyph fall back to a closely
related icon:
- express -> brand-javascript
- other-spa -> world-www
- java -> coffee
- aspnet -> brand-windows
- other-oidc -> shield-check
- ionic -> device-mobile

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restore the original gating: only M2M clients show the Quick Start
tab. The wizard's post-create ?tab=quick-start URL still works for
M2M; for other types the query value is invalid and usePivot falls
back to Settings — which is the desired behavior until DEV-2532
fills in framework-specific Quick Start content for SPA / native /
confidential / traditional_webapp.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Framework column reads from x_framework via the catalog and
shows the framework display name (e.g. "React", "Python (Django)").
For legacy apps without x_framework, or for M2M clients, it falls
back to the application-type label so the cell is never empty.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the custom 15px font-size in FrameworkGrid section labels and
the AuthMethodChoice question. Both now use WidgetSubtitle (Text
variant 'medium', fontWeight 600) to match the rest of the portal.

ref DEV-2392

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fungc-io added 30 commits July 8, 2026 15:38
Move the Other OIDC/SAML compatible card out of the Website section into
a new integration section, in preparation for surfacing machine-to-machine
in the same category.

ref DEV-2392
Add an M2M card to the Integrations & other section of the Create
Application grid. Selecting it navigates to the existing machine-to-machine
create screen, so M2M is discoverable from the main flow instead of only
the split-button dropdown.

ref DEV-2392
Machine-to-machine is now discoverable as a card in the Create Application
wizard, so the split-button dropdown that exposed it is redundant. Revert
the Add Application button to a plain button and drop the now-unused create
menu and its strings.

ref DEV-2392
Selecting the machine-to-machine card no longer jumps straight to the M2M
screen. It now behaves like the framework tiles: it toggles selection so the
user can switch to another tile, hides the name field (the M2M screen collects
its own name), and turns the primary button into Next, which routes to the
machine-to-machine setup screen.

ref DEV-2392
Right-align the machine-to-machine screen's buttons to match the wizard, and
make them a Back button that returns to the framework grid plus a primary
Create application button (was a single left-aligned Save). Remove the now
unused .buttons style.

ref DEV-2392
Clarify what the Other OIDC/SAML compatible tile is for by giving a concrete
example.

ref DEV-2392
"Integrations · other" read awkwardly; "Other" is a clean catch-all
alongside Website and Mobile · Desktop.

ref DEV-2392
Match the rest of the portal: the Create Application wizard and the
machine-to-machine screen now left-align their footer buttons with the
primary action on the left and the secondary (Cancel / Back) on the right,
instead of right-aligning with the primary last.

ref DEV-2392
The application name is now entered on the New Application (/add) screen
for M2M applications too, then carried to the add-m2m screen via router
state where it is shown read-only instead of as an editable input.
Generalize the starter-kit config model to support both .env files and
JS-file edits (public/app.js), then add Vue (Vite .env) and Other SPAs
(spa-js, public/app.js) catalog entries. Download URLs use HEAD.zip so
they work regardless of the repo's default branch.
Add a 'literal' config token (for a self-generated SESSION_SECRET
placeholder) and parameterize the config file name so the step can
reference .env.local. Add the Next.js catalog entry (public client,
server callback redirect URI, npm install / npm run dev on :3000).
… run steps

Generalize redirectURI to a redirectURIs list (authorized together in one
click; step 2 pluralizes and lists them). Add an optional mobileRun to the
kit and render 'Run on iOS' / 'Run on Android' steps after the web-test
step, with the trailing step numbers computed dynamically. Add the Ionic
catalog entry (native client, Capacitor build/run, ionic serve on :8100).
Configure via lib/constants.dart (reusing the const-assignment config
format), single custom-scheme redirect URI, flutter pub get / flutter run.
Make homepageUrl optional and add a device-launch variant of the start
step for apps with no local web homepage.
Add a swift config format (static let in Constants.swift), make the
install and start commands optional, and add an IDE run variant (open in
Xcode). Step numbers are now derived from which optional steps are present,
so iOS omits the install step and renumbers accordingly.
Add a kotlin config format (const val in Constants.kt), Android Studio as
the IDE-run target (no install/start command), and broaden the IDE run
wording to cover simulators and emulators.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants