Repository navigation
chore: main to 1.47.0-beta.dev-1784059879-fix1 (admin-cms version) - #217
Merged
volarname merged 1108 commits intoSep 28, 2026
Merged
Conversation
…dRequestToJoinCollabRoom
Add approveRequestBlocked prop for ACollabManagement and emit approve…
# Conflicts: # package.json
…rsion to 1.47.0-beta.333
The one-shot reconnect flag was burned by the first transient network error, so a later JWT expiration never triggered a token refresh. Transient errors are also no longer sent to Sentry, socket.io retries them on its own.
Promise.all discarded the successfully loaded image form when the audio or video form returned 403, which broke image upload for users without those permissions.
Both locales shipped the English sentence, so consumers inheriting the library error messages showed English to Slovak and Czech users.
Unresolved ids handed back through add() are already in the cache, so counting them as incoming inflated the overflow and evicted more entries than needed. Also exposes isUnresolved as the terminal counterpart of isLoaded.
useDebounceFn's maxWait timer is a second invocation path whose promise never reaches the caller, so catching on the returned promise still let a rejection escape as an unhandled rejection. Adds the missing tests for the state machine.
The server serialises join and leave per room only for the lifetime of its Redis lease, not of the action holding it, so a leave whose work outruns the lease lets a following join acquire, finish and acknowledge first. The leave then reports the membership it read before that join and marks a live room inactive, after which changeCollabAnyData and lock acquisition return early and the client goes quiet with nothing visible to show for it. Every acknowledgement that writes collabRoomInfoState now claims a sequence number first and writes only if it is still the newest. The counter is global and never resets: a per-room one cleared on reconnect hands the same number out twice, and an acknowledgement claimed before the reconnect would match the one claimed by the re-join after it. A claim that ends in failure writes nothing yet still suppresses older acknowledgements, so a failed join records an explicitly inactive room rather than deleting the entry. The mutation guards test for an entry that is inactive; a missing one falls straight through and emits. leaveCollabRoom() returns a promise so a caller that re-joins the same room can serialise the two. It never rejects, because every existing caller invokes it without handling the result, mostly from unmount hooks.
They had grown into essays: the reasoning behind a decision, the alternative that was rejected and the bug that prompted it, where a line of why would do. Comment-only, no behaviour change.
The server answers with the locks it holds only when it holds some, so a lock released while this client was out of the room produces no event and the field reads as locked until some later one arrives. Anything remembered from a previous stay is a guess the join is about to correct.
…stale chip - FiltersSelected: the chip styles were hardcoded light (#f5f5f5 container, white chip) with no dark variant, so in dark theme Vuetify's light chip foreground rendered white text on a white chip. Add a dark-theme block driven by the theme tokens; light theme is untouched. - en/common/model.json: filterPlaceholder shipped Slovak strings in the English bundle, so every AFilterString placeholder was Slovak under the en locale. - AFilterValueObjectOptionsSelect: emptying a multi-select through the dropdown returned early and left the entry in filterSelected, so a chip stayed behind for a filter that was no longer applied. Drop it, like clearField does.
Vuetify 4.1 moves DOM focus onto the clicked day before the picker emits the new value. The resulting text field blur re-applied its stale content over the date just picked, so the first click on a freshly opened calendar did nothing and the previously selected day stayed. Skip the re-assignment when the re-parsed text has not changed, comparing by second so lastMinuteMoment's ms=999 is neither missed nor flattened. Adds the first test coverage the component has had.
@sentry/vue, @shikijs/vitepress-twoslash, eslint and oxfmt; reindents the FlagSk eslint-disable that the newer oxfmt flags.
Pasting an article editor URL straight into the address bar left the moderator unset: no save button, no add-author button, for the only user in the room, indefinitely. The join acknowledgement was correct on the wire and its write was discarded on arrival. On that path the router guard awaits joinCollabRoom while the socket is still connecting, so socket.io buffers the packet. On connect it flushes sendBuffer before emitting the public connect event, so the join goes out and the handler here then reset every write claim. The acknowledgement arrived a round trip later to find its claim gone, isNewestWrite() said no, and collabRoomInfo fell back to a default with a null moderator that nothing repairs while the client is alone in the room. resetRoomInfoWrites() is dropped rather than confined to reconnects. socket.io already deletes the acknowledgement handler of a packet it put on the wire and keeps the one still in sendBuffer, so an acknowledgement emitted before a reconnect cannot land after it and the reset guarded against nothing. Confining it to reconnects would still discard the claim of a join emitted during one, which is the same failure a connection later. The per-room latest-wins ordering that made a late leave lose to a following join is untouched.
The declaration build ran over src/test as well, because tsconfig.libdts carried an include with no exclude beside it, and it did so without DOM.Iterable, which tsconfig.app has. Spreading a NodeList in the datetime picker test therefore failed the library build under TS2488 while a typecheck against tsconfig.app stayed clean. Excludes the same four test patterns tsconfig.app already lists, so test sources cannot reach the published types, and adds DOM.Iterable to match.
… silent save failures
ASortableListEditor: SortableJS options are built once at setup, so a `#view-body`
consumer entering reorder mode got an instance re-created from a stale
`disabled: true` object — handles rendered, dragging did nothing. Watch the rows
container alongside `dragEnabled`.
ImageWidgetMultiple:
- gate the editor's mount on the initial fetch, so images arriving later are not
baselined as "added" ("N unconfirmed changes" on an untouched form)
- re-baseline via `commit()` after a successful save, whose `setImages` replaces
every row key
- emit the empty id list when the last image is removed, so the parent stops
holding the old ids and the images do not come back on reload
- refuse to save while the initial fetch is pending or after it failed: the store
is empty for reasons unrelated to the user, and saving that emptiness detached
every image the gallery still had
- report the real save error instead of returning a bare `false`
- drop the dead drag handle and arrows from the tile; reordering lives in reorder
mode, which is the only place SortableJS binds
Tests: dirty baseline at mount and after `commit(rows)`, and a `#view-body`
consumer having a live Sortable instance in reorder mode.
…dist before copying
8d87197 stopped the null VAutocomplete raises when its search text is emptied, which had poisoned models bound to a non-nullable backend enum: core-cms then 500'd on every following save. That guard keyed on "null arriving over a non-null value", so it also swallowed a legitimate pick of a null-valued option, and a tri-state Yes / No / By system select could never leave Yes or No. Gate the guard on whether the list actually offers null instead. Vuetify resolves a bare null item and {value: null} alike to a null value, so the predicate covers both shapes and agrees with its own hasNullItem test. A list that does offer null cannot tell Vuetify's clear-on-empty-search apart from a pick, so backspacing over such a field lands on the null option. That is accepted: null is a legal answer there and no model is poisoned by it. One Vuetify bug is left in place. After a swallowed null its selectionIndex goes stale, so one Backspace past empty costs the typed search term. A wrapper cannot reach it; VAutocomplete.js:206-207 should gate on props.multiple, the way VSelect already gates its Backspace clear on clearable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main gets the version admin-cms runs on develop and master; main's own commits since the fork are the scraper docs (Omny clip, Sportnet video).
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Brings main up to tag
1.47.0-beta.dev-1784059879-fix1(9f26b68), the version admin-cms pins on bothdevelopandmaster.main. There were no conflicts.docs/only). The merge keeps them.docs/, all from main. The code is identical to what admin-cms runs.Merge with a merge commit (not squash or rebase), so main's history includes the tag's commits and later branches from the tag merge into main cleanly.
🤖 Generated with Claude Code