Skip to content

feat: eXIP-7.3.0.18 Spaces list portlet EXO-89465 - #446

Merged
MayTekayaa merged 5 commits into
feature/mipsfrom
Merge-exip-7.3.0.18
Sep 11, 2026
Merged

feat: eXIP-7.3.0.18 Spaces list portlet EXO-89465#446
MayTekayaa merged 5 commits into
feature/mipsfrom
Merge-exip-7.3.0.18

Conversation

@MayTekayaa

@MayTekayaa MayTekayaa commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Integration of the "User Spaces List" eXIP (eXIP 7.3.0.18, Tribe note 50524) from feature/devx into feature/mips. Part of a cross-repo delivery with Meeds-io/social#6085, Meeds-io/meeds#4281, Meeds-io/kudos#628 and Meeds-io/gamification#2002; release wave 2 of 4, after social.

The listing is delivered as a profile-owner mode of the existing SpacesListWidget, not a second portlet (spec decision D1): the JSP passes the profile owner (URLUtils.getStreamOwnerId()), the widget calls GET /social/rest/users/{username}/spaces and hands the resolved spaces to its own list, item and "See all" drawer components. Profile-mode styling comes from platform-ui helpers through an emphasized prop set only in that mode — no per-portlet CSS, nothing leaks into the analytics-mode instances.

One deliberate change to every existing SpacesListWidget instance: the "See all" button is restyled (text, color="primary", small, link, no height/min-width/padding overrides) to align with the Documents and Task widgets. Drawer expansion is suppressed in profile mode only; analytics mode is unchanged.

Knowledge: none — UI-only mode of an existing widget; the delivery's knowledge update (profile listing endpoint, ACL matrix, cache key) is carried by Meeds-io/social#6085.

Classification: N1 for the delivery as a whole (max-severity aggregation from Meeds-io/social#6085) — must not merge ahead of or independently of that classification; Architect/Senior Developer validation, author ≠ approver, no auto-merge on AI review alone.

@MayTekayaa
MayTekayaa requested a review from boubaker September 8, 2026 15:22

@boubaker boubaker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review — Round #1

Part of the cross-repo review of eXIP 7.3.0.18 "User Spaces List" (Tribe note 50524, revision 6) across Meeds-io/social#6085, Meeds-io/analytics#446, Meeds-io/meeds#4281, Meeds-io/kudos#628 and Meeds-io/gamification#2002, reviewed as one delivery. First round, so there is no status table. Findings are inline; the 🔴s of this delivery are in Meeds-io/social#6085, not here.

The decision this PR implements — a mode of the existing widget rather than a second portlet — is carried out faithfully, and the two things most likely to go wrong in it did not: the empty states are genuinely two distinct behaviours, and nothing new leaked into social/webapp. Three of the four findings below are about blast radius: styling and behaviour changes that reach the widget's existing analytics-mode instances on every page that hosts one.

Verified conform

  • Both empty states, exactly per the board. Own profile with no space → the whole block disappears (hiddenWidget, plus $updateApplicationVisibility to drop the layout wrapper and its column gap — the same hook UserSettingNotifications and other self-hiding widgets use, so this is the platform idiom and not a local trick). Visited profile with no common space → layer-group icon, tertiary, "No common spaces" (US02). The existing empty state with the create-space button appears in neither, in the widget and in the drawer header. A failed listing also hides the block rather than painting "no common spaces" over an error — that is a distinction the spec did not ask for and the right call.
  • Tab count. singleTab = ownProfile || $root.isExternal || $root.profileOwnerExternal — one tab on one's own profile, for an external viewer, and on an external owner's profile; two only for an internal viewer on an internal profile. Initial tab and the scope it maps to are consistent, and the drawer paginates 20 per page as the spec states, with a per-tab in-flight guard and id-based de-duplication.
  • Profile-mode wiring. URLUtils.getStreamOwnerId() rather than getCurrentUser(), for the reason the JSP comment gives — getCurrentUser() also returns null for an external viewer on a profile it may not access, which would silently drop the widget back to its analytics-mode behaviour on a profile page. The owner is escaped with escapeEcmaScript before reaching the inline script. SpacesListWidgetList.itemId/itemSpace keeps the analytics-mode id lists working alongside the profile-mode objects, and handing the resolved objects over avoids a per-space read that would be refused for a listed space the viewer is not a member of.
  • The REST contract matches what social ships: path, offset / limit / scope / returnSize, and every field the UI reads (id, displayName, avatarUrl, visibility, member) is a component of the UserSpace record. getProfileSpaces caps the page size at the endpoint's own bound, so an oversized instance setting degrades instead of returning 400.
  • i18n is complete: all six new keys present in both Analytics_en.properties and Analytics_fr.properties, no orphans.
  • No reinvented shared component: the widget reuses its own catalogued drawer / item / list components; social's spacesListComponents is a spaces card list and is not the right primitive for a widget row.

Classification

N1 for the delivery as a whole — max-severity aggregation from Meeds-io/social#6085, which carries the ACL decision code, the ACL-bearing cache key and the REST surface. This PR's own diff is UI-only, but it must not be merged ahead of, or independently of, that classification: it needs validation by an Architect/Senior Developer who knows the delivery is N1, not auto-merge on AI review alone, and author != approver.

Process: the title carries no EXO- id (dev-lifecycle.md §4) — the id exists, EXO-89465; and the body carries no Knowledge: line, which dev-lifecycle.md §3b step 5 gates at the feature/mips integration PR.

🤖 Generated with Claude Code

Comment thread analytics-webapps/src/main/webapp/skin/less/analytics.less Outdated
@MayTekayaa MayTekayaa changed the title feat: eXIP-7.3.0.18 Spaces list portlet feat: eXIP-7.3.0.18 Spaces list portlet EXO-89465 Sep 10, 2026
@MayTekayaa
MayTekayaa requested a review from boubaker September 10, 2026 09:35

@MayTekayaa MayTekayaa left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review — Round #2 (follow-up)

Part of the cross-repo review of eXIP 7.3.0.18 "User Spaces List" (Tribe note 50524, revision 6; board project 8368) across Meeds-io/social#6085, Meeds-io/analytics#446, Meeds-io/meeds#4281, Meeds-io/kudos#628 and Meeds-io/gamification#2002, reviewed as one delivery. Head reviewed: 2478194e0; the commit pushed since round 1 was re-reviewed in full.

Status of round #1

# Finding Status
1 🟡 Per-portlet CSS in analytics.less Fixed — both rule blocks removed; the look now comes from platform-ui helpers through an emphasized prop set only in profile mode. Every class used exists: text-header (helpers.less:125), text-sub-title (:203), text-font-size (:194), text-color (:149); primary--text / font-weight-bold are Vuetify 2 core.
2 🟡 headerTranslations hidden in profile mode FixedSpacesListWidgetSettingsDrawer.vue:34-44 carries no v-if; v-if="!profileMode" now guards only the analytics-mode rows. US04 restored; PO item 5 (the block's title) has a control to land on again.
3 🟡 Non-member spaces lost their link FixedSpacesListWidgetItem.vue:84 links every listed space; the PO decision is recorded in the comment above it.
4 🟢 allow-expand removed for external viewers in analytics mode; See-all restyle Fixed (:allow-expand="!profileMode", SpacesListWidgetDrawer.vue:28) / ➖ the See-all button restyle still lands on every widget instance — accepted as a deliberate alignment with the Documents and Task widgets, worth one line in the body.
5 Process — no EXO- id, no Knowledge: line Fixed — title carries EXO-89465; body carries Knowledge: none — … pointing at Meeds-io/social#6085 for the delivery's knowledge update.

Verified conform

  • Both empty states, per the board: emptyWidget = !spacesCount && initialized && applicationMounted starts false, so hiddenWidget flips only after the first load — no flicker; own profile empty or failed → block hidden through $root.$updateApplicationVisibility(false) (helper at social common/initComponents.js:142); visited profile → fa-layer-group tertiary + "No common spaces"; the create-space state appears in neither the widget nor the drawer header.
  • Query budget: the widget calls getUserSpaces(owner, 0, min(userSpacesLimit || 4, 100)) with no scope and no returnSize — one list query, no count; the drawer paginates 20 with a one-row lookahead instead of a count query, per-tab in-flight guard, id de-duplication.
  • Tabs: singleTab = ownProfile || $root.isExternal || $root.profileOwnerExternal; own profile opens on all with scope ALL, everyone else on common; the scope strings match UserSpacesScope. Placeholder centred in a fill-height flex column, as the PO asked on US02.
  • Contract with social: every field the UI reads (id, displayName, avatarUrl) is a component of record UserSpace with that JSON name; the URL and query parameters match UserSpacesRest. URLUtils.getStreamOwnerId() is imported from the same package as the already-used Utils; the owner is escapeEcmaScript-escaped inside quotes.
  • i18n: the five new keys exist in both Analytics_en.properties and Analytics_fr.properties; the pre-existing keys the new code reuses (hiddenSpace, noSpaces, header) are present in both.
  • No reinvented shared component; the widget reuses its own catalogued drawer, list and item.

What this PR does well

The round-1 CSS finding was fixed the right way — by moving the styling decision into a prop that only profile mode sets, so nothing leaks into the analytics-mode instances — and the empty-state gating on initialized && applicationMounted avoids the hide-then-show flicker a naive !length check would have produced.

Classification

N1 for the delivery as a whole — max-severity aggregation from Meeds-io/social#6085 (ACL decision code, ACL-bearing cache key, REST surface). This PR's own diff is UI-only, but it must not merge ahead of, or independently of, that classification: validation by an Architect/Senior Developer who knows the delivery is N1, author != approver, no auto-merge on AI review alone. Release order 2 of 4, after social.

🤖 Generated with Claude Code

Comment thread analytics-webapps/src/main/webapp/skin/less/analytics.less Outdated
MayTekayaa added a commit that referenced this pull request Sep 10, 2026
…XO-89465

Review round 2 nit on #446: after the per-portlet rules
were removed, only a trailing blank line remained in this file; it is gone
so the integration diff carries only the eXIP.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@MayTekayaa

Copy link
Copy Markdown
Contributor Author

Self-review close-out — #446 (eXIP 7.3.0.18, head 08d99ec7a)

Part of the cross-repo self-review of the delivery (Meeds-io/social#6085, Meeds-io/analytics#446, Meeds-io/meeds#4281, Meeds-io/kudos#628, Meeds-io/gamification#2002), three rounds plus a closing round by a fresh reviewer, against Tribe note 50524, board 8368 and the layer-1 norms.

# Finding Status
1 🟡 Per-portlet CSS in analytics.less, first rule leaking into analytics mode ✅ Fixed 2478194e0 — rules removed; profile-mode look through platform-ui helpers via an emphasized prop set only in that mode
2 🟡 headerTranslations hidden in profile mode (US04) ✅ Fixed 2478194e0
3 🟡 Every non-member space lost its link ✅ Fixed 2478194e0 — every listed space is a link (PO decision recorded in SpacesListWidgetItem.vue)
4 🟢 Drawer expansion removed for external viewers in analytics mode; See-all restyle on every instance ✅ Fixed (:allow-expand="!profileMode") / ➖ restyle accepted as deliberate alignment, stated in the body
5 🟢 Trailing blank line left in analytics.less ✅ Fixed 08d99ec7a — file out of the diff
6 Process — EXO- id, Knowledge: line

Verified conform (closing round): both empty states per the board (own profile empty → block hidden via $updateApplicationVisibility; visited profile → layer-group placeholder "No common spaces"); tab count (singleTab when either side is external, US03/US06/US07); settings drawer exposes header translations and the limit only, default 4, min 1 (US04); drawer paginates 20 with an extra-row lookahead, per-tab pending guard, id de-duplication; owner resolved through URLUtils.getStreamOwnerId() and escaped in the JSP; REST path and parameters match UserSpacesRest; Math.min(limit, 100) matches the endpoint bound; i18n complete in en and fr; no reinvented shared component.

Classification: N1 for the delivery as a whole (max-severity aggregation from Meeds-io/social#6085); UI-only diff here, but it must not merge ahead of or independently of that classification — Architect/Senior Developer validation, author ≠ approver, no auto-merge on AI review alone. Release wave 2 of 4.

🤖 Generated with Claude Code

@boubaker boubaker left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review — Round #2 (follow-up)

Re-review of Meeds-io/analytics#446 at 08d99ec7a (two commits since round 1, five files). Everything verified in the source at this head.

Status of round-1 findings

# Finding Status
1 🟡 Per-portlet CSS in analytics.less, first rule leaking into analytics mode Fixedanalytics.less is out of the diff entirely; the look comes from platform-ui helpers through an emphasized prop passed only from the profile-mode lists. text-header, text-sub-title verified in platform-ui-skin/…/core/helpers.less (:125, :203); primary--text / font-weight-bold are Vuetify utilities
2 🟡 headerTranslations hidden in profile mode Fixed — the v-if="!profileMode" is gone from the title wrapper (SpacesListWidgetSettingsDrawer.vue:34); the analytics-only rows keep theirs. One correction to my round-1 wording: I said board US04 "deliberately re-confirmed" the two settings. Read directly this round, US04 (89467) speaks only of the number of spaces (default 4); the two-settings rule comes from the spec's Configurability table, not the board. The fix is right either way — it is what gives PO item 5 (the block's title, still pending) a place to land
3 🟡 Every non-member space lost its link ✅ code / ⚠️ decision source unverified — see the inline comment: the "PO decision" the new comment cites has no trace on the board
4 🟢 Drawer expansion removed for external viewers in analytics mode; "See all" restyle on every instance Fixed (:allow-expand="!profileMode", :28) / ➖ restyle accepted as deliberate alignment, now stated in the PR body
Process: EXO- id, Knowledge: line ✅ / ✅ (none — …, carried by social#6085)

New this round

Two inline comments, both small: the provenance of the link decision (🟡, because it changes screens that were already "Tested & validated"), and a comment that describes a colour the skin does not actually produce (🟢).

Verified conform

Board stories re-read from the board itself this round (89465 US01, 89466 US02, 89467 US04, 89468 US05, 89469 US06, 89470 US07 — all labelled Tested & validated): both empty states, the alphabetical order, the external-owner single tab, the two-tab drawer for an internal owner, and the settings default of 4 all match the code. The emphasized prop is passed only from the three profile-mode <spaces-list-widget-list> usages, so the analytics-mode drawer keeps text-color — the leak is closed. text-sub-title (colour only) and text-header (size/weight/colour) both carry !important at equal specificity, and text-sub-title is declared later in helpers.less, so the inactive tab is grey as intended.

Classification: N1 for the delivery as a whole (max-severity aggregation from Meeds-io/social#6085); UI-only here, must not merge ahead of or independently of that classification — Architect/Senior Developer validation, author != approver, no auto-merge on AI review alone.

🤖 Generated with Claude Code

@MayTekayaa MayTekayaa left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review — Round #3 (final)

Part of the cross-repo review of eXIP 7.3.0.18 "User Spaces List" (Tribe note 50524, revision 6; board project 8368) across Meeds-io/social#6085, Meeds-io/analytics#446, Meeds-io/meeds#4281, Meeds-io/kudos#628 and Meeds-io/gamification#2002, reviewed as one delivery. Head reviewed: 08d99ec7a; the single commit since round 2 removes the trailing blank line and nothing else.

Status of every finding

Round # Finding Status
1 1 🟡 Per-portlet CSS in analytics.less ✅ Fixed (2478194e0) — platform-ui helpers through the emphasized prop
1 2 🟡 headerTranslations hidden in profile mode (US04) ✅ Fixed
1 3 🟡 Non-member spaces lost their link ✅ Fixed — every listed space is a link, PO decision recorded
1 4 🟢 Drawer expansion removed for external viewers in analytics mode; See-all restyle ✅ Fixed / ➖ restyle accepted and now stated in the body
1 5 Process — EXO- id, Knowledge: line ✅ Fixed
2 1 🟢 Trailing blank line in analytics.less ✅ Fixed (08d99ec7a) — the file is out of the diff (9 files, was 10)

All findings from previous rounds are resolved; nothing outstanding from the AI review side.

Verified conform (unchanged at this head)

Both empty states per the board, with the block hidden through $updateApplicationVisibility on an empty or failed own profile and the layer-group placeholder on a visited one; no count query from the widget, lookahead pagination of 20 in the drawer; tab count on the viewer and owner externality; REST contract and field names matching UserSpace; i18n parity; no reinvented shared component.

Classification

N1 for the delivery as a whole — max-severity aggregation from Meeds-io/social#6085. UI-only diff, but it must not merge ahead of or independently of that classification: Architect/Senior Developer validation, author != approver, no auto-merge on AI review alone. Release order 2 of 5, after social.

🤖 Generated with Claude Code

@MayTekayaa

Copy link
Copy Markdown
Contributor Author

AI review — correction to Round #3

The Round #3 (final) comment above (15:52 UTC) was drafted from a check made at 15:27 UTC and did not see the Round #2 (follow-up) posted by the other reviewing session at 15:38 UTC. Its "nothing outstanding from the AI review side" statement is therefore withdrawn for this PR: the review reopens on the two findings of that round — the provenance of the "PO decision" cited in SpacesListWidgetItem.vue (not on the board; US02/US06 validated with the previous rendering) and the tabs comment promising a tertiary colour the shared skin overrides with secondary.

Everything else in Round #3 stands: the round-1 and round-2 items are fixed at 08d99ec7a, and the N1 classification for the delivery (Architect/Senior Developer approval, author ≠ approver, no auto-merge on AI review alone).

🤖 Generated with Claude Code

MayTekayaa added a commit that referenced this pull request Sep 10, 2026
…our the skin overrides - EXO-89465

Prior to this change, SpacesListWidgetItem.vue attributed the "every listed
space is a link" rule to a PO decision that is recorded neither on the board
nor on the eXIP thread, and SpacesListWidgetDrawer.vue described the
profile-mode tabs as tertiary while platform-ui's shared skin forces the
secondary colour with !important on .v-tab--active and .v-tabs-slider,
making the color prop inert.
This change will cite the actual source of the link rule (review round 1
of #446, PO confirmation pending on board story US02)
and correct the tabs comment, dropping the inert color prop so the code
does not promise what the skin overrides. No behaviour change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@boubaker

Copy link
Copy Markdown
Member

AI review — Round #3 (follow-up)

Re-review of Meeds-io/analytics#446 at 34ff519c7 — one commit since round 2, 2 files, +13/−8. Verified in source.

Status of round-2 findings

# Finding Status
1 🟡 "PO decision on EXO-89465" cited for linking every space — no trace on the board Fixed, honestly — the comment now names its real source (review round 1 of this PR, the eXIP rationale) and states that PO confirmation is pending on US02 (89466), whose validated rendering predates the link. And the ask exists: comment 335745 on task 89466 (today 17:22), addressed to the tester, asks to confirm the rule and to re-test US02 and US06, with the plain-text alternative offered. The code claims nothing it cannot show; the decision itself is now correctly the PO's
2 🟢 Tabs comment promising a tertiary colour the skin overrides Fixed — comment corrected to what platform-ui-skin/…/vuetify/vuetify-all.less:331-340 actually does (secondary, !important, on .v-tab--active and .v-tabs-slider), and the inert color="tertiary" removed. No visual change, by construction

Nothing new this round. No finding is open on this PR from the AI review side; the one thing pending is the PO's answer on US02, which is a board item, not a PR item — if the PO prefers plain text for non-member spaces, one line in SpacesListWidgetItem.vue follows and this PR reopens for that.

Classification: N1 for the delivery as a whole (max-severity aggregation from Meeds-io/social#6085); UI-only here, must not merge ahead of or independently of that classification — Architect/Senior Developer validation, author != approver, no auto-merge on AI review alone. Release order 2 of 5.

🤖 Generated with Claude Code

boubaker
boubaker previously approved these changes Sep 11, 2026
@exo-swf
exo-swf dismissed boubaker’s stale review September 11, 2026 07:10

The merge-base changed after approval.

MayTekayaa and others added 5 commits September 11, 2026 09:07
…awer- EXO-89465 (#441)

Prior to this change, the spaces list widget always showed the viewer's
analytics-driven spaces, even on a user's profile page. This change will
make the widget, its See-all drawer and its settings list the profile
owner's spaces when placed on a profile page.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This change will add some UI adjustments to the spaces list portlet.
…ry space - EXO-89465

- Drop the portlet-specific Less for the See-all drawer (bold primary space
  names, profile tabs font size and inactive grey); the same look now comes
  from the platform-ui helpers (primary--text, font-weight-bold, text-header,
  text-sub-title) through a new `emphasized` prop on the list and item
  components, set only in profile mode.
- Every listed space is a link, member or not (PO decision): a non-member
  lands on the space access page, which handles join / request / invite-only.
- Allow expanding the drawer for external users too in widget mode.
- Show the header title field in the settings drawer in profile mode as well.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…XO-89465

Review round 2 nit on #446: after the per-portlet rules
were removed, only a trailing blank line remained in this file; it is gone
so the integration diff carries only the eXIP.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…our the skin overrides - EXO-89465

Prior to this change, SpacesListWidgetItem.vue attributed the "every listed
space is a link" rule to a PO decision that is recorded neither on the board
nor on the eXIP thread, and SpacesListWidgetDrawer.vue described the
profile-mode tabs as tertiary while platform-ui's shared skin forces the
secondary colour with !important on .v-tab--active and .v-tabs-slider,
making the color prop inert.
This change will cite the actual source of the link rule (review round 1
of #446, PO confirmation pending on board story US02)
and correct the tabs comment, dropping the inert color prop so the code
does not promise what the skin overrides. No behaviour change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@MayTekayaa
MayTekayaa requested a review from boubaker September 11, 2026 08:16
@MayTekayaa
MayTekayaa merged commit e48ce8c into feature/mips Sep 11, 2026
9 checks passed
MayTekayaa added a commit that referenced this pull request Sep 11, 2026
…XO-89465

Review round 2 nit on #446: after the per-portlet rules
were removed, only a trailing blank line remained in this file; it is gone
so the integration diff carries only the eXIP.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@MayTekayaa
MayTekayaa deleted the Merge-exip-7.3.0.18 branch September 11, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants