feat(board): a board can be edited and added on the boards page - #962
Merged
Conversation
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.
What this does
A board is written down and corrected on
/board, the page it is read on. The plus at the endof the timeline adds a board; a pencil on any stop opens the board it belongs to.
domains/boards/island/BoardDialog.vue, in the island's dialog shell: number,name, cheer, colour, description, the two dates, and the board photo. Which it is — adding or
correcting — follows from whether there is a board in it, so there is one form rather than two
that drift.
nextBoardNumberreads one past the highest numberrecorded, so ten boards make the eleventh, and a history with a gap in it still suggests a
number nothing holds. Typed over freely: a board added out of order is a correction somebody
may be making on purpose.
visible while it can still be changed.
ImagePickeris bound to the boards adapter's ownstoreBoardPhoto, which is what a shared control asks its caller for rather than importing adomain (ADR-001).
board X has none yet, so that is the normal case for half the history — the offer belongs in
the band standing in for it, not behind a pencil elsewhere.
onto the board only on Save, so a cancelled dialog leaves the board on the photograph it had
and the bytes where they are. There is a spec that counts the writes and asserts none.
ConfirmDialog, naming how many seats are in the way — thepage already read the board whole, so nothing is asked of the api to say it. Pressing through
reports the api's own refusal,
BoardHoldsSeatscomposed byrefusals.ts, on the questionthat is standing. Board X holds nobody, so the empty path is real and removes.
saveBoardOrReasonjoinsdropBoard: the sdk hands a refusal backas a body rather than throwing, and a clashing number answers "Board 9 already exists", which
is the one thing whoever typed it can act on. The form stands with what was typed.
The colour, and what reads on it
The accent is a fill rather than an ink: it washes a band, lights a stretch of the timeline
and backs the swatch. So the new rule is which ink reads on it, not how to make the colour
readable —
domains/boards/accent.ts,inkOnAccent, whichever of the two inks the fillcontrasts with more. Read against the four colours #958 just seeded:
#eaa4b6#b00b69#9100d0#65c6cd#3387faA blank field is answered against the blue, because that is the fill a board with no colour is
drawn in — as is a colour written in a notation the rule cannot read. The dialog's swatch is that
rule made visible: the field's colour painted as a block with the board's numeral on it in
whichever ink it takes, live as it is typed, and the stylesheet's blue showing through while the
field is empty.
Board X was the case to check first. It has no photograph, so its cyan fills the whole band
with the numeral on top — and the band does not paint the accent raw:
BoardBandwashes it 30%into the theme's own ground, so the numeral in
--color-chalkclears 8.19:1 in the dark halfand 10.98:1 in the light one. The same holds for all five accents (worst case 8.03:1), so
nothing there needed changing and the band's painting is untouched.
Reconciled with what was already on the page rather than replacing it.
Board.vue's--accent-inkanswers a different question — the cheer is text in the accent, on the page'sground — and it is kept: it mixes towards the ink of the theme, so one formula lifts a deep
colour off the dark half and drops a pale one onto the light half. Both directions now have a
spec that measures what is actually painted: board VI's pink reads 3.51:1 in light mode where
raw it would be 1.57:1, and board VII's magenta 3.38:1 in dark mode where raw it would be
2.51:1. Those two specs convert the rendered colour through a canvas, because Chromium serialises
a colour mixed in oklab as
oklab(...)and reading the numbers out of that string measuresnothing — which is exactly how the first version of them passed while asserting garbage.
Who may edit
useMayEditBoards, beside the boards' other island pieces, asking the one questionuseMayEditEsportsasks: whether the viewer holds BOARD. The api rule ishasPermission(..., 'Board', 'write'), which is BOARD and above, and the login response carriesinherited roles, so an admin arrives holding it. Asked per domain rather than shared, so a page
never reaches into another domain to find out who is reading. It decides what is offered and
nothing else — a visitor and a plain member get no pencil, no plus and no dialog mounted at all,
and the api still refuses what it refuses.
The
candidatecolumnNothing to add.
saveBoardalready passed a candidate through asundefinedwhen it carriesnone, and
BoardUseCases.candidateForfills theNOT NULLcolumn with the board's name — orwith
Board <number>where there is no name — on every create and every update. The dialogtherefore sends no candidate and never shows the field, and the adapter says in one comment why
it is passed through rather than composed: a second copy of that rule on this side would be a
second thing to keep in step.
Also
image, the asset file name the early history still points at, is carried through the dialoguntouched. A save replaces every field, so leaving it out would quietly clear it.
reachable before the first one can be added. A visitor still sees it only from two boards up.
tests/e2e/mocks.tsgainsPOST /boards,DELETE /boards/{id}with theBoardHoldsSeatsrefusal, the two board picture ladders, and boards remembered across a test's own writes, so a
page that reads again is answered the way the api would. New cases in a new spec file rather
than changes to the ones other specs read.
Verification
yarn typecheck,yarn lint --max-warnings=0,yarn test:unit(1013 passed) andyarn test:e2e --grep "board"(104 passed) all exit 0. The fullyarn test:e2ecame back 674passed with three
page.gototimeouts in three unrelated specs —boards.spec.ts,esports-removals.spec.ts,esports-island.spec.ts— which pass together in isolation: eightworkers on four vCPUs, the starvation #424 describes.
Closes #932
Diff breakdown —
█added░removed, scaled to the largest row.