@bongos/core 1.21.34 → 1.21.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.bongos-core.json +65 -50
  2. package/clients/bongos-client/index.d.ts +3 -3
  3. package/docs/api/openapi.json +25 -35
  4. package/docs/api-reference.md +1 -1
  5. package/docs/module-api-changelog.md +4 -0
  6. package/docs/page-inventory.json +10 -1
  7. package/docs/page-readings.json +356 -251
  8. package/modules/autonomy/governor-docket.js +68 -1
  9. package/modules/autonomy/matter-acts.js +41 -0
  10. package/modules/autonomy/routes/autonomy.js +2 -0
  11. package/modules/government/board.js +4 -0
  12. package/modules/government/db.js +14 -0
  13. package/modules/government/decision-board.js +90 -11
  14. package/modules/government/docket-floors.js +20 -0
  15. package/modules/government/docket-vocab.js +19 -0
  16. package/modules/government/docket.js +114 -2
  17. package/modules/government/routes/government.js +15 -1
  18. package/modules/hall-ui/public/street-card.js +157 -1
  19. package/modules/hall-ui/public/street-desk.js +205 -11
  20. package/modules/hall-ui/public/street-inside.js +11 -8
  21. package/modules/hall-ui/public/street.css +16 -0
  22. package/modules/hall-ui/public/street.js +97 -9
  23. package/modules/hall-ui/public/street.states.json +355 -6
  24. package/modules/ideas/governor-docket.js +91 -0
  25. package/modules/lifecycle/governor-docket.js +93 -2
  26. package/modules/lifecycle/matter-acts.js +63 -0
  27. package/modules/lifecycle/routes/done-when.js +26 -12
  28. package/modules/lifecycle/routes/gate-approvals.js +74 -59
  29. package/modules/lifecycle/routes/lifecycle.js +2 -0
  30. package/modules/lifecycle/routes/project-settings.js +24 -0
  31. package/modules/onboarding/routes/access-requests.js +7 -0
  32. package/modules/provisioning/core-upgrade.js +1 -1
  33. package/modules/provisioning/routes/core-upgrade.js +36 -1
  34. package/modules/security/routes/reports.js +23 -0
  35. package/package-lock.json +2 -2
  36. package/package.json +1 -1
  37. package/release-notes.json +16 -0
  38. package/src/bongos/route-rank-check.js +2 -0
  39. package/src/bongos/routes/backup.js +26 -0
  40. package/src/bongos/routes/builders.js +96 -1
  41. package/src/bongos/routes/modules.js +18 -0
  42. package/src/module-api.js +1 -1
  43. package/tests/governor_docket.mjs +28 -1
  44. package/tests/governor_matter_acts.mjs +241 -0
  45. package/tests/hall_matter_card.mjs +11 -2
  46. package/tests/hall_street_desk.mjs +473 -4
  47. package/tests/hall_street_inside.mjs +3 -3
@@ -310,9 +310,22 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
310
310
  .desk-chip--primary { background: var(--ink); border: 0; color: var(--bg); }
311
311
  .desk-chip--quiet, .desk-chip--choice { background: none; border: 1px solid var(--street-rule-strong); color: var(--ink); }
312
312
  .desk-chip--choice { height: 30px; padding: 0 14px; }
313
+ .desk-field { height: 30px; min-width: 0; flex: 1 1 140px; max-width: 220px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--street-rule-strong); background: none; color: var(--ink); font-family: var(--font-body); font-size: 13.5px; }
313
314
  .desk-chip:hover { filter: brightness(1.08); }
314
315
  .desk-chip[disabled] { opacity: 0.55; cursor: progress; }
315
316
  .desk-wait { font-size: 13px; color: var(--ink-faint); border: 1px dashed var(--street-rule-strong); border-radius: 999px; padding: 6px 12px; white-space: nowrap; }
317
+ /* the Planning desks (task 1004560): a goal's place in the order, its promise
318
+ pips (or a vote's seats), the two arrows, and the save bar under a moved order */
319
+ .desk-pos { width: 22px; flex: none; font-size: 13px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
320
+ .desk-pips { display: flex; gap: 4px; flex: none; }
321
+ .desk-pip { width: 12px; height: 12px; border-radius: 3px; box-sizing: border-box; border: 1px solid var(--street-rule-strong); }
322
+ .desk-pip--on { background: var(--ink); border-color: var(--ink); }
323
+ .desk-arrow { width: 34px; height: 34px; flex: none; border-radius: 999px; border: 1px solid var(--street-rule-strong); background: none; color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
324
+ .desk-arrow svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
325
+ .desk-arrow[disabled] { opacity: 0.55; cursor: progress; }
326
+ .desk-arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
327
+ .desk-save { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; padding: 16px 0 0; animation: street-enter 300ms cubic-bezier(.16,1,.3,1) both; }
328
+ .desk-save__line { font-size: 13.5px; color: var(--ink-soft); margin-right: auto; }
316
329
  .desk-facts, .desk-choices { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 0 2px 52px; animation: street-enter 300ms cubic-bezier(.16,1,.3,1) both; }
317
330
  .desk-fact { font-size: 13px; color: var(--ink-soft); background: var(--street-wash); border-radius: 6px; padding: 6px 10px; white-space: nowrap; }
318
331
  .desk-choices__ask { font-size: 12.5px; color: var(--ink-faint); margin-right: 4px; }
@@ -372,6 +385,9 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
372
385
  .inside-gov__row { flex-wrap: wrap; row-gap: 4px; }
373
386
  .desk-row__main { flex-wrap: wrap; row-gap: 8px; }
374
387
  .desk-name { flex-basis: calc(100% - 52px); }
388
+ .desk-pos ~ .desk-name { flex-basis: calc(100% - 88px); }
389
+ .desk-pos ~ .desk-pips { margin-left: 88px; }
390
+ .desk-pips ~ .desk-acts { margin-left: auto; }
375
391
  .desk-acts { margin-left: 52px; }
376
392
  .desk-facts, .desk-choices { padding-left: 0; }
377
393
  .desk-tile { min-width: 0; padding: 10px 14px; }
@@ -82,7 +82,8 @@
82
82
  var view = { open: null, opener: null, model: null, scale: 1, mode: null, inside: null, insideModel: null };
83
83
  // the desk's own state: rows you acted on this visit, what you did per floor,
84
84
  // the floors you cleared, the row whose facts or chips are open
85
- var desk = { done: {}, mine: {}, cleared: {}, open: null, ask: null, busy: false, roomAsked: false, model: null };
85
+ // order: the Priorities desk's order as the viewer has moved it, per floor (task 1004560)
86
+ var desk = { done: {}, mine: {}, cleared: {}, order: {}, open: null, ask: null, busy: false, roomAsked: false, model: null };
86
87
  var TODAY_KEY = 'gov-desk-today';
87
88
  var today = { day: '', n: 0 };
88
89
 
@@ -553,7 +554,7 @@
553
554
  var D = window.GovDesk, st = view.inside;
554
555
  if (!D || !st) return;
555
556
  var k = st.key + ':' + bv.selFloor;
556
- var dm = D.deskModel({ key: st.key, floor: bv.selFloor, docket: data.docket, goals: (data.goals || []).filter(function (g) { return g && g.status === 'open'; }), now: Date.now(), room: data.room, constitution: data.constitution, done: desk.done, mine: desk.mine[k] || [], cleared: !!desk.cleared[k], today: today.n, sym: bv.sym });
557
+ var dm = D.deskModel({ key: st.key, floor: bv.selFloor, docket: data.docket, goals: (data.goals || []).filter(function (g) { return g && g.status === 'open'; }), now: Date.now(), room: data.room, constitution: data.constitution, done: desk.done, mine: desk.mine[k] || [], cleared: !!desk.cleared[k], today: today.n, sym: bv.sym, order: desk.order[k] || null });
557
558
  desk.model = dm;
558
559
  el.className = 'inside-open desk' + (dm.quiet ? ' desk--quiet' : '');
559
560
  el.setAttribute('data-desk', dm.key);
@@ -595,6 +596,14 @@
595
596
  dm.rows.forEach(function (r) { list.appendChild(deskRow(r)); });
596
597
  el.appendChild(list);
597
598
  }
599
+ // a changed order: what saving does, then undo and save (task 1004560)
600
+ if (dm.save) {
601
+ var bar = node('div', 'desk-save');
602
+ bar.appendChild(node('span', 'desk-save__line', dm.save.line));
603
+ bar.appendChild(chipBtn('desk-chip--quiet', 'undo', function () { desk.order[k] = null; draw(); }));
604
+ bar.appendChild(chipBtn('desk-chip--primary', dm.save.label, function () { saveOrder(dm, k); }));
605
+ el.appendChild(bar);
606
+ }
598
607
  // the record line: what you just did here, then what this building closed
599
608
  var rec = node('div', 'desk-record');
600
609
  rec.appendChild(node('span', 'desk-record__label', 'record'));
@@ -606,6 +615,7 @@
606
615
  var row = node('div', 'desk-row' + (r.needs ? ' desk-row--needs' : ''));
607
616
  row.setAttribute('data-row', r.key);
608
617
  var main = node('div', 'desk-row__main');
618
+ if (r.pos) main.appendChild(node('span', 'desk-pos', String(r.pos)));
609
619
  main.appendChild(node('span', 'desk-ini', r.ini));
610
620
  var name = node('button', 'desk-name');
611
621
  name.setAttribute('type', 'button');
@@ -615,13 +625,36 @@
615
625
  name.appendChild(node('span', 'desk-name__f', r.fact));
616
626
  name.addEventListener('click', function () { desk.open = desk.open === r.key ? null : r.key; desk.ask = null; draw(); focusRow(r.key, 'name'); });
617
627
  main.appendChild(name);
628
+ // promises kept of total, or a vote's seats: one pip each
629
+ if (r.pips && r.pips.length) {
630
+ var pips = node('span', 'desk-pips');
631
+ pips.setAttribute('aria-hidden', 'true');
632
+ r.pips.forEach(function (p) { pips.appendChild(node('span', 'desk-pip' + (p.on ? ' desk-pip--on' : ''))); });
633
+ main.appendChild(pips);
634
+ }
618
635
  var acts = node('span', 'desk-acts');
619
636
  if (r.wait) acts.appendChild(node('span', 'desk-wait', r.wait));
637
+ if (r.order) {
638
+ // the order's two arrows: the move is the viewer's until saved
639
+ [['up', -1, 'M6 15l6-6 6 6'], ['down', 1, 'M6 9l6 6 6-6']].forEach(function (m) {
640
+ if (!r.actions.some(function (a) { return a.key === m[0]; })) return;
641
+ var b = node('button', 'desk-arrow');
642
+ b.setAttribute('type', 'button');
643
+ b.setAttribute('aria-label', 'move ' + r.name + ' ' + m[0]);
644
+ // the top goal cannot go up, nor the last down
645
+ if (desk.busy || (m[1] < 0 && r.top) || (m[1] > 0 && r.bottom)) b.setAttribute('disabled', '');
646
+ b.appendChild(icon(m[2], null, 14));
647
+ b.addEventListener('click', function () { moveRow(r, m[1]); });
648
+ acts.appendChild(b);
649
+ });
650
+ }
620
651
  // the primary button sits rightmost, as on the board
621
- r.actions.slice().reverse().forEach(function (a) {
652
+ // a row whose chips stand open is decided by its chip alone: no button for it
653
+ if (!r.order) r.actions.slice().reverse().forEach(function (a) {
654
+ if (r.show && a.key === r.show) return;
622
655
  acts.appendChild(chipBtn('desk-chip--' + a.tone, a.label, function () {
623
656
  if (a.go) { window.location.href = a.go; return; }
624
- if (a.ask) { desk.ask = desk.ask === r.key ? null : r.key; desk.open = null; draw(); focusRow(r.key, 'chip'); return; }
657
+ if (a.ask) { var at = r.key + '|' + a.key; desk.ask = desk.ask === at ? null : at; desk.open = null; draw(); focusRow(r.key, 'chip'); return; }
625
658
  deskAct(r, a.key, {});
626
659
  }));
627
660
  });
@@ -632,14 +665,58 @@
632
665
  r.facts.forEach(function (f) { facts.appendChild(node('span', 'desk-fact', f)); });
633
666
  row.appendChild(facts);
634
667
  }
635
- if (desk.ask === r.key && r.chips) {
668
+ var asked = desk.ask && desk.ask.indexOf(r.key + '|') === 0 ? (r.choices || {})[desk.ask.slice(r.key.length + 1)] : null;
669
+ // a blocker's options stand open: deciding it is picking one
670
+ if (!asked && r.show) asked = (r.choices || {})[r.show] || null;
671
+ if (asked) {
636
672
  var chips = node('div', 'desk-choices');
637
- chips.appendChild(node('span', 'desk-choices__ask', r.chips.ask));
638
- r.chips.options.forEach(function (c) { chips.appendChild(chipBtn('desk-chip--choice', c.label, function () { deskAct(r, r.chips.for, c.input); })); });
673
+ chips.appendChild(node('span', 'desk-choices__ask', asked.ask));
674
+ asked.options.forEach(function (c) { chips.appendChild(chipBtn('desk-chip--choice', c.label, function () { deskAct(r, asked.for, c.input); })); });
675
+ if (asked.field) {
676
+ // the one typed value a desk takes: a name to invite (never a reason)
677
+ var input = node('input', 'desk-field');
678
+ input.setAttribute('type', 'text');
679
+ input.setAttribute('aria-label', asked.ask);
680
+ input.setAttribute('autocomplete', 'off');
681
+ input.setAttribute('maxlength', '60');
682
+ var send = function () { var v = input.value.trim(); if (v) deskAct(r, asked.for, { option: v, label: v }); };
683
+ input.addEventListener('keydown', function (e) { if (e.key === 'Enter') send(); });
684
+ chips.appendChild(input);
685
+ chips.appendChild(chipBtn('desk-chip--primary', 'send', send));
686
+ }
639
687
  row.appendChild(chips);
640
688
  }
641
689
  return row;
642
690
  }
691
+ // The Priorities desk (task 1004560): a move is kept in this visit until saved.
692
+ function moveRow(r, by) {
693
+ var D = window.GovDesk, st = view.inside;
694
+ if (!D || !st || !desk.model) return;
695
+ var k = st.key + ':' + (view.insideModel ? view.insideModel.selFloor : 0);
696
+ var now = desk.model.rows.filter(function (x) { return x.order; }).map(function (x) { return x.key; });
697
+ desk.order[k] = D.moved(now, r.key, by);
698
+ draw();
699
+ focusRow(r.key, 'arrow');
700
+ }
701
+ // Save: the order goes to POST /goals/reorder, or is filed for the council;
702
+ // the server's own checks decide either way.
703
+ function saveOrder(dm, k) {
704
+ var C = window.GovMatterCard;
705
+ var req = C && C.orderRequest ? C.orderRequest(dm.save) : null;
706
+ if (!req || desk.busy) return Promise.resolve(false);
707
+ desk.busy = true;
708
+ draw();
709
+ return send(req).then(function (out) {
710
+ desk.busy = false;
711
+ if (!out.ok) { say(C.refusal(out.status, out.body)); draw(); return false; }
712
+ desk.order[k] = null;
713
+ desk.mine[k] = [dm.save.council ? 'order sent to council' : 'order set'].concat(desk.mine[k] || []);
714
+ bumpToday();
715
+ say(dm.save.said);
716
+ draw();
717
+ return load().then(function () { return true; });
718
+ });
719
+ }
643
720
  function deskRowsEl() {
644
721
  var st = view.insideModel;
645
722
  var on = $(st && st.flipA ? 'insideOpenA' : 'insideOpenB');
@@ -654,6 +731,7 @@
654
731
  if (rows[i].getAttribute('data-row') !== key) continue;
655
732
  var main = rows[i].children[0];
656
733
  var target = what === 'chip' && rows[i].children[1] ? rows[i].children[1].children[1] : main && main.children[1];
734
+ if (what === 'arrow' && main) target = main.querySelector ? main.querySelector('.desk-arrow') : target;
657
735
  if (target && target.focus) target.focus();
658
736
  return;
659
737
  }
@@ -666,7 +744,15 @@
666
744
  if (typeof setTimeout !== 'function') return then();
667
745
  setTimeout(then, 320);
668
746
  }
669
- var DONE_WORDS = { for: 'voted yes', object: 'voted no', fine: 'let in', refuse: 'turned away', release: 'released', hold: 'held' };
747
+ var DONE_WORDS = {
748
+ for: 'voted yes', object: 'voted no', fine: 'let in', refuse: 'turned away', release: 'released', hold: 'held',
749
+ confirm: 'confirmed', dispute: 'disputed', fix: 'fixed', remove: 'removed', keep: 'kept', signoff: 'signed off', force: 'forced',
750
+ switch_on: 'switched on', switch_off: 'switched off', allow: 'allowed', disallow: 'disallowed', first: 'put first',
751
+ pause: 'paused', resume: 'resumed', tier: 'new tier', deactivate: 'deactivated', give: 'gave', take: 'took back',
752
+ check: 'checked', rot: 'set', module_on: 'turned on', module_off: 'turned off', backup: 'backed up', invite: 'invited',
753
+ decide: 'decided', ratify: 'ratified', ratify_goal: 'made a goal of',
754
+ budget: 'set the limit of', unsign: 'undid',
755
+ };
670
756
  // One act from a row: checked, sent through the card's own request (the
671
757
  // server's permission checks decide), then the row clears, the floor counts
672
758
  // it, the meter takes a pip and the toast says what happened. An act that
@@ -680,7 +766,9 @@
680
766
  var req = C.request(r.card, key, input);
681
767
  var settle = function (body) {
682
768
  var a = C.answer(r.card, key, body);
683
- desk.mine[k] = [DONE_WORDS[key] + ' ' + r.name].concat(desk.mine[k] || []);
769
+ // an act at a building a sitting decides went to it as a matter (task 1004561)
770
+ var sent = r.card.subject && r.card.subject.council && req && /\/government\/board\/matters$/.test(req.url);
771
+ desk.mine[k] = [(sent ? 'sent to council:' : DONE_WORDS[key]) + ' ' + r.name].concat(desk.mine[k] || []);
684
772
  desk.done[r.matter] = true;
685
773
  desk.open = null; desk.ask = null;
686
774
  if (desk.model && !desk.model.rows.some(function (x) { return x.matter !== r.matter; })) desk.cleared[k] = true;
@@ -55,14 +55,37 @@
55
55
  "auth": true,
56
56
  "_": "In the hall since task 1004544: the shell's full-screen switch pressed, the sidebar and the top bar gone, the street filling the window and the one exit in the corner (the sky's mechanism, task 1004327).",
57
57
  "actions": [
58
- ["wait", 900],
59
- ["click", "#fullscreen-toggle"],
60
- ["wait", 500]
58
+ [
59
+ "wait",
60
+ 900
61
+ ],
62
+ [
63
+ "click",
64
+ "#fullscreen-toggle"
65
+ ],
66
+ [
67
+ "wait",
68
+ 500
69
+ ]
61
70
  ],
62
71
  "expect": {
63
- "visible": ["#streetBoard", "#streetSigns", "#streetMode", "#fullscreen-toggle"],
64
- "hidden": ["#app-sidebar", "#topbar-title"],
65
- "attr": [["#fullscreen-toggle", "aria-pressed", "true"]]
72
+ "visible": [
73
+ "#streetBoard",
74
+ "#streetSigns",
75
+ "#streetMode",
76
+ "#fullscreen-toggle"
77
+ ],
78
+ "hidden": [
79
+ "#app-sidebar",
80
+ "#topbar-title"
81
+ ],
82
+ "attr": [
83
+ [
84
+ "#fullscreen-toggle",
85
+ "aria-pressed",
86
+ "true"
87
+ ]
88
+ ]
66
89
  }
67
90
  },
68
91
  "card": {
@@ -456,6 +479,332 @@
456
479
  ".desk-quiet"
457
480
  ]
458
481
  }
482
+ },
483
+ "desk-people-builders": {
484
+ "auth": true,
485
+ "_": "Task 1004559: People, Builders floor. Each builder is a row with tier and deactivate, the acts the old builders page held.",
486
+ "url": "/builders/street#building=people",
487
+ "actions": [
488
+ [
489
+ "wait",
490
+ 900
491
+ ],
492
+ [
493
+ "clickIfVisible",
494
+ "[data-craft-close]"
495
+ ],
496
+ [
497
+ "wait",
498
+ 300
499
+ ],
500
+ [
501
+ "click",
502
+ "[data-floor=\"2\"]"
503
+ ],
504
+ [
505
+ "wait",
506
+ 600
507
+ ]
508
+ ],
509
+ "expect": {
510
+ "visible": [
511
+ ".desk-rows",
512
+ ".desk-chip--primary"
513
+ ]
514
+ }
515
+ },
516
+ "desk-people-tier": {
517
+ "auth": true,
518
+ "_": "Task 1004559: the tier button opens its tiers as one-tap chips in place (one rung up at most).",
519
+ "url": "/builders/street#building=people",
520
+ "actions": [
521
+ [
522
+ "wait",
523
+ 900
524
+ ],
525
+ [
526
+ "clickIfVisible",
527
+ "[data-craft-close]"
528
+ ],
529
+ [
530
+ "wait",
531
+ 300
532
+ ],
533
+ [
534
+ "click",
535
+ "[data-floor=\"2\"]"
536
+ ],
537
+ [
538
+ "wait",
539
+ 600
540
+ ],
541
+ [
542
+ "click",
543
+ ".desk-row .desk-chip--primary"
544
+ ],
545
+ [
546
+ "wait",
547
+ 400
548
+ ]
549
+ ],
550
+ "expect": {
551
+ "visible": [
552
+ ".desk-choices"
553
+ ]
554
+ }
555
+ },
556
+ "desk-disputes": {
557
+ "auth": true,
558
+ "_": "Task 1004559: Disputes, Security reports. Confirm or dispute an open report; mark a confirmed one fixed.",
559
+ "url": "/builders/street#building=disputes",
560
+ "actions": [
561
+ [
562
+ "wait",
563
+ 900
564
+ ],
565
+ [
566
+ "clickIfVisible",
567
+ "[data-craft-close]"
568
+ ],
569
+ [
570
+ "wait",
571
+ 300
572
+ ],
573
+ [
574
+ "click",
575
+ "[data-floor=\"0\"]"
576
+ ],
577
+ [
578
+ "wait",
579
+ 600
580
+ ]
581
+ ],
582
+ "expect": {
583
+ "visible": [
584
+ ".desk-rows",
585
+ ".desk-status--hot"
586
+ ]
587
+ }
588
+ },
589
+ "desk-automation-goals": {
590
+ "auth": true,
591
+ "_": "Task 1004559: Automation, Allowed goals. Disallow, put first, or allow an open goal from chips.",
592
+ "url": "/builders/street#building=automation",
593
+ "actions": [
594
+ [
595
+ "wait",
596
+ 900
597
+ ],
598
+ [
599
+ "clickIfVisible",
600
+ "[data-craft-close]"
601
+ ],
602
+ [
603
+ "wait",
604
+ 300
605
+ ],
606
+ [
607
+ "click",
608
+ "[data-floor=\"1\"]"
609
+ ],
610
+ [
611
+ "wait",
612
+ 600
613
+ ]
614
+ ],
615
+ "expect": {
616
+ "visible": [
617
+ ".desk-rows"
618
+ ]
619
+ }
620
+ },
621
+ "desk-release-core": {
622
+ "auth": true,
623
+ "_": "Task 1004559: Release, Core update. Check first (a dry run); take it is offered only after the check passed for that version.",
624
+ "url": "/builders/street#building=release",
625
+ "actions": [
626
+ [
627
+ "wait",
628
+ 900
629
+ ],
630
+ [
631
+ "clickIfVisible",
632
+ "[data-craft-close]"
633
+ ],
634
+ [
635
+ "wait",
636
+ 300
637
+ ],
638
+ [
639
+ "click",
640
+ "[data-floor=\"3\"]"
641
+ ],
642
+ [
643
+ "wait",
644
+ 600
645
+ ]
646
+ ],
647
+ "expect": {
648
+ "visible": [
649
+ ".desk-rows"
650
+ ]
651
+ }
652
+ },
653
+ "desk-rules": {
654
+ "auth": true,
655
+ "_": "Task 1004559: Rules in force. The rot timer as day chips, work categories as a link, each module on or off.",
656
+ "url": "/builders/street#building=rules",
657
+ "actions": [
658
+ [
659
+ "wait",
660
+ 900
661
+ ],
662
+ [
663
+ "clickIfVisible",
664
+ "[data-craft-close]"
665
+ ],
666
+ [
667
+ "wait",
668
+ 300
669
+ ],
670
+ [
671
+ "click",
672
+ "[data-floor=\"0\"]"
673
+ ],
674
+ [
675
+ "wait",
676
+ 600
677
+ ]
678
+ ],
679
+ "expect": {
680
+ "visible": [
681
+ ".desk-rows"
682
+ ]
683
+ }
684
+ },
685
+ "desk-planning-priorities": {
686
+ "auth": true,
687
+ "_": "Task 1004560: Planning, Priorities. The open goals in order with promise pips and two arrows; one goal moved down, so the save bar says the new order goes to the council and how many yes it needs, with undo.",
688
+ "url": "/builders/street#building=planning",
689
+ "actions": [
690
+ [
691
+ "wait",
692
+ 900
693
+ ],
694
+ [
695
+ "clickIfVisible",
696
+ "[data-craft-close]"
697
+ ],
698
+ [
699
+ "wait",
700
+ 300
701
+ ],
702
+ [
703
+ "click",
704
+ "[data-floor=\"0\"]"
705
+ ],
706
+ [
707
+ "wait",
708
+ 600
709
+ ],
710
+ [
711
+ "click",
712
+ ".desk-arrow[aria-label$=\" down\"]"
713
+ ],
714
+ [
715
+ "wait",
716
+ 400
717
+ ]
718
+ ],
719
+ "expect": {
720
+ "visible": [
721
+ ".desk-rows",
722
+ ".desk-pips",
723
+ ".desk-save"
724
+ ]
725
+ }
726
+ },
727
+ "desk-planning-ideas": {
728
+ "auth": true,
729
+ "_": "Task 1004560: Planning, Ideas to ratify. A Full Idea in its vote with seat pips, a promise to ratify in one tap, and a carried Full Idea made a goal from a version chip.",
730
+ "url": "/builders/street#building=planning",
731
+ "actions": [
732
+ [
733
+ "wait",
734
+ 900
735
+ ],
736
+ [
737
+ "clickIfVisible",
738
+ "[data-craft-close]"
739
+ ],
740
+ [
741
+ "wait",
742
+ 300
743
+ ],
744
+ [
745
+ "click",
746
+ "[data-floor=\"1\"]"
747
+ ],
748
+ [
749
+ "wait",
750
+ 600
751
+ ],
752
+ [
753
+ "focus",
754
+ ".desk-rows .desk-row:last-child .desk-name"
755
+ ],
756
+ [
757
+ "wait",
758
+ 300
759
+ ]
760
+ ],
761
+ "expect": {
762
+ "visible": [
763
+ ".desk-rows"
764
+ ]
765
+ }
766
+ },
767
+ "desk-planning-blockers": {
768
+ "auth": true,
769
+ "_": "Task 1004560: Planning, Waiting on you. Each blocker decided by one of its options as chips standing open; go ahead, not now, need more when it lists none.",
770
+ "url": "/builders/street#building=planning",
771
+ "actions": [
772
+ [
773
+ "wait",
774
+ 900
775
+ ],
776
+ [
777
+ "clickIfVisible",
778
+ "[data-craft-close]"
779
+ ],
780
+ [
781
+ "wait",
782
+ 300
783
+ ],
784
+ [
785
+ "click",
786
+ "[data-floor=\"2\"]"
787
+ ],
788
+ [
789
+ "wait",
790
+ 600
791
+ ],
792
+ [
793
+ "focus",
794
+ ".desk-rows .desk-row:last-child .desk-name"
795
+ ],
796
+ [
797
+ "wait",
798
+ 300
799
+ ]
800
+ ],
801
+ "expect": {
802
+ "visible": [
803
+ ".desk-rows",
804
+ ".desk-choices",
805
+ ".desk-status--hot"
806
+ ]
807
+ }
459
808
  }
460
809
  },
461
810
  "reducedMotion": {