[pull] main from TryGhost:main - #1468
Merged
Merged
Conversation
no ref Added Chinese translation in new fields.
Two races made these specs unreliable. A screen's unsaved-changes guard is not armed the moment you type: the keystroke has to reach the screen's dirty state, re-render the guard and register it with the router, and none of that has happened by the time the typing step resolves. And the route assertion the specs used as a cue to act reads the address bar, which the browser updates before the router re-renders, so a spec that reopens a dialog it just closed could type into the copy already on its way out and lose the edit. They now wait on the app instead: on the guard itself, by dispatching a synthetic close-the-tab event and seeing whether the app objects, and on the departing dialog actually being gone before acting on its replacement. The fake API the suite runs against also shut itself down on that event, so it now ignores it. Claude-Session: https://claude.ai/code/session_01HjrKZqSXQ54LgAsX1VMzQp
no ref Adds some e2e tests for the post editor to cover React & Ember paths. Most of our coverage is only in Acceptance.
ref https://linear.app/ghost/issue/DES-1519/ ## Why The Admin 7 display-oriented Inter features are intentionally limited to headings, but three prominent title treatments are not all represented by semantic heading elements. They should use the same title typography while the surrounding UI keeps the quieter base feature set. ## What changed - Applied the existing heading Inter features to the sidebar site title. - Applied them to the post title field in the editor. - Applied them to publish-flow titles, including “Ready, set, publish. Share it with the world.” - Kept the change inside the existing `admin7PageChrome` shell and portal scope, so flag-off presentation is unchanged. - Added no automated tests because this is a CSS-only font-feature adjustment with no behavioral contract; visual acceptance will be done manually before merge.
ref https://linear.app/ghost/issue/BER-3920/ Adds `GET /ghost/api/admin/emails/:id/status` so Admin can poll newsletter email preparation and provider submission progress independently from the email resource. The response exposes: - sending status: `preparing`, `submitting`, `submitted`, or `failed` - completed and total recipient counts - a rough estimated number of seconds remaining - the phase in which a failed send stopped
ref https://linear.app/ghost/issue/BER-3922/rename-the-code-behind-the-metafields-api-to-match-the-domain-language The API vocabulary, the CSV columns and the filter relation all say "metafields", but the package holding the shared catalog and its column predicate still said "custom field", so the same concept went by two names depending on which layer you were reading. Renaming the package to @tryghost/metafield-types, and isCustomFieldColumn to isMetafieldColumn, leaves one word for it everywhere the shared vocabulary is used. Claude-Session: https://claude.ai/code/session_01XFCbqgYHYhd9rZ5WXtqZyT
ref https://linear.app/ghost/issue/BER-3922/rename-the-code-behind-the-metafields-api-to-match-the-domain-language Members carry a bag of extra fields grouped by the namespace that owns them, and the API, the CSV columns and the filter relation all call that mechanism metafields. The tables underneath still called it custom fields, which reads as though the publisher's namespace were the only one there can be. The definitions table, the values it keys, the bindings a checkout writes through, and the column naming that key now use the same word as everything above them. They are dropped and recreated rather than renamed in place, because the feature sits behind a private flag with no released data, so there is nothing to carry across and rebuilding gives every foreign key and index its new name without a per-dialect rename dance. products_checkout_fields keeps its own name and is rebuilt only because its foreign key points at the bindings table. One sealed migration had to change with them. The leaf-rows migration in 6.57 asked schema.js for the shape of the column it adds, and the idempotency suite re-runs every migration against the final schema, where that table no longer answers to its old name. Pinning the shape inline, the way the same migration's rollback already does, makes it self-contained and leaves what it does untouched. The tier checkout API still speaks of a custom_field_key on the wire. Renaming a published field is an API change rather than a schema one, so it is deliberately left where it is. Claude-Session: https://claude.ai/code/session_01XFCbqgYHYhd9rZ5WXtqZyT
ref https://linear.app/ghost/issue/BER-3922/rename-the-code-behind-the-metafields-api-to-match-the-domain-language A member carries a bag of extra fields grouped by the namespace that owns them, and metafields is the name for that mechanism everywhere it is already visible: the payload key, the route, the CSV columns, the filter relation. Behind them the service still called the whole mechanism custom fields, which reads as a claim that the publisher's namespace is the only namespace there can be. The service and its three aggregates, the types they hand out, the config ceiling, the filter relation, the telemetry event names, and the names the members read and write path, the importer, the exporter and the Stripe checkout binding know their collaborators by, all now use the same word as the API above them. Several things keep the old word because they are about the publisher's namespace rather than the mechanism, and are better left accurate than made uniform. The labs flag gates a feature the publisher knows as Custom fields. So does the error copy, the limit error code and the stored name of an edit in the activity log, all of which are read by someone looking at that screen; renaming them would also split a string across the boundary where admin and core deploy independently, in exchange for nothing. The tier checkout API names a key that has the custom namespace already applied to it, so a custom field key is exactly what it is. Stripe's own checkout custom fields are a different concept that happens to share a name. The permission object type is still member_custom_field. Renaming it means rewriting a fixture and migrating the rows that already carry it, which is its own change rather than a line in this one. Claude-Session: https://claude.ai/code/session_01XFCbqgYHYhd9rZ5WXtqZyT
ref https://linear.app/ghost/issue/BER-3922/rename-the-code-behind-the-metafields-api-to-match-the-domain-language Reading a field definition is no longer gated by a permission. A definition says only that the site collects a shoe size, and every signed-in member is already shown the whole list through Portal, so holding it back from staff protected nothing that was not already on offer elsewhere. It was also inverted. An integration holding member browse received members' field values on the member payload, which never consults this permission, while a request for the definitions describing those same values was refused. It could read the data but not the schema, which is the wrong way round. The routes had already drawn the line correctly and deliberately: reads are unflagged so Admin can ask any site and get an empty list, and everything that changes something is flagged. Only the permission layer had not caught up. What remains on the resource is defining fields, which stays with the publisher. The smaller change alongside it is one of order. Which namespace is being written to now settles before who is asking, so a namespace nobody can define in refuses on that ground whatever role the caller holds, rather than answering with a missing permission that no one could have been granted. That is also where namespace ownership belongs once an app owns a namespace of its own, since the caller will then have to be that app rather than hold a role. Claude-Session: https://claude.ai/code/session_01XFCbqgYHYhd9rZ5WXtqZyT
no ref Added raw components for the post preview activity in the React editor implementation. Nothing is wired up yet.
ref https://linear.app/ghost/issue/BER-3920/ Allowed unreleased Admin features to be tested on live sites without changing server-side Labs settings. Overrides are read from the labs query parameter, persisted for the browser session, and synchronized with Ember during cold loads so both Admin implementations use the same flag state.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )