collabcentral/html
Joseph B. McQueen 524b443dce Make favorite groups editable from the compose page
Selecting a group in "Additional groups" now auto-saves it to the
caller's favorites, and each favorite gets a × affordance for one-click
removal. Favorites still live where they always have —
config.webex.bot[app].authorized[personId].groups — so nothing changes
for existing installations.

Backend
- New POST /CollabCentral/:app/user/groups/add. Body { id }. Validates
  the caller is authorized for :app, validates :id resolves to a real
  Webex group by looking it up in the cached org-wide group list
  (blocks arbitrary strings from being stuffed into config.json),
  dedups against the existing favorites array, writes config.json via
  saveConfig, and returns the updated array.
- New POST /CollabCentral/:app/user/groups/remove. Body { id }.
  Filters that id out of the caller's favorites, writes only when
  something actually changed (a remove of an unknown id no-ops instead
  of rewriting config.json), and returns the updated array.
- Both endpoints are safe against concurrent writes: index.js is
  single-process and node is single-threaded, so read/mutate/write
  runs atomically per request.
- Both log a compact audit line (last-8 of personId + group name) so
  operators can see who is curating what.

Frontend (sendMessage.html + .js + app.css)
- New "Manage favorites" chip strip renders directly under the
  Favorite Groups picker. Each favorite becomes a pill (uses .alias
  when set, otherwise .name; long labels truncate with ellipsis).
  Clicking × on a pill removes that favorite server-side and updates
  the strip locally.
- Additional Groups picker wires a 'change' listener that diffs the
  current selection against the previous one and only fires
  /user/groups/add for newly-picked ids (never re-fires on the
  reselect side of a deselect+reselect, never spams the API with the
  full selection on every keystroke).
- Client keeps favoriteGroups mirrored to every API response so the
  "already a favorite?" dedup check is a pure in-memory lookup — no
  wasted round trips when the user re-picks a group they already
  favorited.
- Transient status message ("Added to favorites." / "Removed from
  favorites." / error variants) fades under the field label; sticks
  around ~4s.
- New shared styles: .fieldLabelRow (label + inline status),
  .fieldStatus (with --error variant), .chipStrip, .chip,
  .chip__label, .chip__close (with hover/focus states).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 20:25:15 -04:00
..
css Make favorite groups editable from the compose page 2026-07-01 20:25:15 -04:00
js Phase 9: rebuild frontend on a shared layout + fix Monitor Jobs race 2026-07-01 19:36:36 -04:00
aeoPropsBot.png Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
auth.js Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
DirectoryConnector.zip Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
index.html Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
jobDetail.html Phase 9: rebuild frontend on a shared layout + fix Monitor Jobs race 2026-07-01 19:36:36 -04:00
jobDetail.js Phase 9: rebuild frontend on a shared layout + fix Monitor Jobs race 2026-07-01 19:36:36 -04:00
monitorJobs.html Phase 9: rebuild frontend on a shared layout + fix Monitor Jobs race 2026-07-01 19:36:36 -04:00
monitorJobs.js Phase 9: rebuild frontend on a shared layout + fix Monitor Jobs race 2026-07-01 19:36:36 -04:00
novi.ico Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
novi.png Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
sendMessage.html Make favorite groups editable from the compose page 2026-07-01 20:25:15 -04:00
sendMessage.js Make favorite groups editable from the compose page 2026-07-01 20:25:15 -04:00
techupdates.ico Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00
techupdates.png Initial commit: multi-bot CollabCentral 2026-07-01 17:53:07 -04:00