About pages for spaces, maintained resources, and users (#478)#479
Draft
tkuhn wants to merge 32 commits into
Draft
About pages for spaces, maintained resources, and users (#478)#479tkuhn wants to merge 32 commits into
tkuhn wants to merge 32 commits into
Conversation
Add three standalone, mounted, parameterized About pages, reachable by direct URL only (not yet linked from the existing pages, and the existing pages are unchanged): - AboutSpacePage -> /spaceabout?id= - AboutResourcePage -> /resourceabout?id= - AboutUserPage -> /userabout?id= Each page shows a listing of the resource's assigned view displays (built on the get-view-displays query Nanodash uses internally, rendered via a newly published ResourceView/TabularView nanopub) plus a references table -- rather than rendering the assigned data views themselves. The user About page additionally shows a new read-only PublicProfilePanel (introductions, public keys with per-user approval, default license) that works for any user, unlike the session-bound ProfilePage items. ReferencesPage.REFERENCES_VIEW is promoted to public so the About pages can reuse it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ripes (#478) - Render the user's introductions as a proper view on AboutUserPage (live ResourceView/TabularView backed by a per-user get-user-introductions query), replacing the custom intro DataView. - Replace PublicProfilePanel with a "Profile" view (default license + profile picture, one row each, with source-nanopub column and "update profile image/license..." result actions); remove the panel and the public-keys section. - style.css: make the table zebra stripe alpha-based (rgba(0,0,0,0.06)) so it darkens whatever is behind it instead of looking brighter on darker backgrounds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…display queries (#478) - AboutSpacePage: show an "Assigned roles" view (role/user/date + source np), rendered above the view-displays listing. - Point the Assigned roles and Assigned view displays views at dedicated, less-technical queries (linked view/role/user columns, status, date, source np) instead of the app-internal GET_SPACE_ROLES/GET_VIEW_DISPLAYS queries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…stripe (#478) Renders identically (#F3F6F9) over white sections, but darkens over the matching #F3F6F9 row-section stripe instead of blending in. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ces) (#478) Extract the duplicated action-rendering loop into a shared addViewActions helper and call it from the resourceWithProfile == null branch too, so view "linked actions" (template buttons) appear on the general Spaces page. The helper only sets the target/context/part params when an id/contextId is present, so resource-less listings work without bogus params. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bundles of default views and roles, defined once and assigned to resources. Mirrors the view-display mechanism: authorized agents only (admins+maintainers, or the user on a user page), latest-wins, with presets and standalone view displays sharing one override pool. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Presets (issue #302) bundle default views and roles and are assigned to a resource. The get-view-displays query now also returns preset-supplied views (unbound ?display), which AbstractResourceWithProfile builds via ViewDisplay.forPresetView and merges into the existing latest-wins/dedup pool. Adds Preset and PresetAssignment domain models, the gen: preset vocabulary, and two About-page listings (authority-filtered to admins/maintainers/affected user): the existing "View displays" view now includes preset-supplied views marked with their preset, and a new "Assigned presets" view is shown before it on the Space, Resource and User About pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#302) Repoint GET_VIEW_DISPLAYS to get-view-displays v6, which applies the same authority gate as the About-page listings: only view displays and preset assignments signed by an admin or maintainer of the owning space, or by the affected user themselves, are rendered. This also closes the user-page gap (space-less resources were previously unfiltered). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All QueryResult* views (Table, Rdf, List, ItemList, NanopubSet, PlainParagraph) now show an italic "(nothing found)" note (class no-records-note) and hide the data element entirely when empty. Table and Rdf drop Wicket's NoRecordsToolbar so the header row is no longer shown for empty results; the table's visibility is driven by onConfigure (with an output-markup placeholder) so the AJAX filter collapses it when a filter matches nothing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#302) Repoint the view-displays-view and preset-assignments-view constants to the versions that declare an "add view display..." / "add preset..." result action, and pass the page resource as id/contextId to the table builder so the action pre-fills param_resource (the target space/resource/user) on the publish form. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A preset's gen:hasTopLevelView pins to the resource's own page; gen:hasView defers to the view's own class/namespace targeting (gen:appliesToInstancesOf / appliesToNamespace) instead of being forced to the top level. Top-level rendering now passes the resource's own type (getOwnClasses: Space / MaintainedResource / IndividualAgent) so a view targeting the resource type shows there, while a view targeting a part type (e.g. owl:Class) shows on matching parts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The get-view-displays query now follows each referenced view's npx:supersedes chain server-side (as list-view-displays does), so ?view is already the latest version. New artifact: RAWD7diDNUAR0DLMS5gUMCyk9O6wAu7wRkfTGtS_Hf9Uo/get-view-displays (supersedes RAd-T...). Nanodash no longer resolves latest versions one-by-one when building a page's view displays: - View.get(id, resolveLatest) overload skips getLatestVersionId; the query's already-latest ?view is loaded directly. - ViewDisplay.get(id, latestViewIri) + 3-arg ctor thread the view IRI through; forPresetView loads its view directly. - The per-display getLatestVersionId in ViewDisplay.get is removed: the query's invalidates filter already returns only current display nanopubs (all superseded displays are also invalidated under the same signing key), so the display np is loaded directly. Net result: zero one-by-one latest-version round-trips in the get-view-displays render path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point GET_VIEW_DISPLAYS at the v8 get-view-displays query (RAJtBiC...). Both get-view-displays and list-view-displays now resolve each referenced view to the most recent *current head* of its version tree -- a nanopub itself neither superseded nor validly retracted (npx:invalidates) -- with date only as a tiebreak among surviving heads, instead of picking the max-timestamp node. This is robust to backdated supersedes and to retracted versions. Verified identical to the prior queries on all current live data. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point GET_VIEW_DISPLAYS at the v10 query (RAy49uUd...), which wraps the cross-repo latest-view resolution in a run-once sub-SELECT. The resolution was previously invoked once per referenced view, costing ~44 federation round-trips (~4.3s of a ~4.5s query); evaluating it once for the whole view set cuts a 44-display page to ~1.7s, with identical results (verified against the deployed closure across all 548 views). list-view-displays got the same treatment and view-displays-view was re-pointed at it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…478) Replace the standalone About/Raw pages with a tab strip selected via a ?tab= query param on the main /space, /user, /resource and /part pages (default content). Tab bodies are reusable panels (AboutSpacePanel, AboutResourcePanel, AboutUserPanel, ExplorePanel) plus DownloadRdfLinks for Raw; bodies are built conditionally so non-content tabs don't fire the content queries. The tab strip lives in the breadcrumb stripe (rounded-top tabs, gray-italic "- About/Explore/Raw" title suffixes); its bottom border was removed. /explore stays for arbitrary terms but forwards known resources to their page's Explore tab. References moved from About to Explore. Also: deleted AboutSpacePage/AboutUserPage/AboutResourcePage/RawPage and their mounts; removed the "+ view display" buttons (kept on /part), the per-id Explore button and the ExploreDisplayMenu/UserPageMenu dropdowns, "See Your Profile Details", and the raw component on /list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add QueryResult.fitsOnFirstPage() (page size < 1, or total rows <= page size) and hide the filter input in QueryResultTable/List/ItemList/ NanopubSet/PlainParagraph when it holds, so the Filter box only shows when there are more rows than fit on the first page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Breadcrumbs: split each label on list/title punctuation (, : ; | and spaced -) into separate crumb segments instead of truncating at ": ". - Action-menu dropdowns: white-background (light) style; nudge the down- arrow up so it lines up with the action buttons and filter field. - Result tables: hide the header of a trailing np/nps column and right-align its cells (the ^ source-nanopub links). - Hide the result filter textfield when all rows fit on the first page. - Make the per-tab contentContainer a transparent wicket:container so the content row-sections stay direct children of #content-pane, fixing the alternating background stripes (were appearing only after a refresh). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add ProfileAccountPanel to the current user's /user?tab=about: logout (ORCID-login mode only) and an ORCID set/change form (local mode only). - Dropdown arrows: CSS-drawn outline "v" chevron (no top line), matching the action buttons' box and vertical-align so they line up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Embed ProfileSigItem in ProfileAccountPanel so the current user's About tab also shows their public key and (in local mode) the local key-file path (migrating profile feature B). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… action - Revert the introductions-view retract entry action: republish a read-only introductions-view (RAElH_0Za…, supersedes the action version) and point the constant at it. - AboutUserPanel: the logged-in user (with a local key) now gets the ProfileIntroItem companion *instead of* the read-only view (others keep the read-only view) — no more duplicate listing. - Restyle ProfileIntroItem to match the view tables: a Recommended Actions section (paneltitlerow header) holding the recommendation note + actions (incl. Create Introduction), then the "👋 Introductions" pseudo-view rendered as a table (date/location/keys/np + per-row retract/derive/ include-keys). - Style the Account header like Signing Key; fold the "multiple introductions" note into the retract bullet so no introductory text sits directly in front of the table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spec for auto-binding view-query placeholders (LOCALPUBKEY, SITEURL) from the session, plus the empty-into-required entry-action visibility rule, as the path to replace the custom ProfileIntroItem table with a proper view. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Move the four notes from doc/ into docs/ (alongside userlist-views.md). - Add a **Status:** line (Implemented / In progress / Proposed) to each doc. - Add docs/README.md index with a status table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
View displays visible only to a given role tier (Maintainer, ...) or specific role via a single gen:isVisibleTo predicate, riding nanopub-query's existing role-tier model. Records the AboutUserPanel preset/view-display action leak as a known gap to fix with the declarative mechanism. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements steps 1-4 of docs/role-specific-views.md: - KPXL_TERMS: role-tier IRIs (AdminRole/MaintainerRole/MemberRole/ ObserverRole) and the gen:isVisibleTo predicate. - SpaceMemberRole: tier field (parsed from the get-space-roles roleType column, defaulting to ObserverRole), tier ranking (admin>maintainer> member>observer>everyone) and isTier/tierRank helpers; the built-in ADMIN_ROLE carries the AdminRole tier. - Space: consume the roleType column; userTier(iri) and viewerHoldsRole(iri, role) lookups. - View/ViewDisplay: parse gen:isVisibleTo; ViewDisplay.isVisibleTo(...) matches a tier threshold or a specific role (no admin override), falling back to the view default; empty => everyone. - AbstractResourceWithProfile.getViewDisplays: drop displays the viewer is not entitled to, after the latest-wins/deactivation pass. Session-safe via NanodashSession.getCurrentUserIriOrNull() and fails closed off-request. - Tests for the tier ranking/parsing. Inert until a view display declares gen:isVisibleTo; maintainer/member tiers need the get-space-roles roleType republish (P0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The get-space-roles query nanopub was republished (RAKJFw-x..., supersedes RAERgisN...) to also return ?roleType (npa:hasRoleType), so SpaceMemberRole can pick up each role's tier for gen:isVisibleTo gating. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nodes Pivot from whole-view visibility to per-action gating, per the reworked docs/role-specific-views.md. - View: parse gen:isVisibleTo on action nodes -> getActionVisibleTo(actionIri). - SpaceMemberRole.isViewerEntitled(...): tier-threshold / specific-role match (no admin override), plus a convenience overload resolving viewer/space/owner from the rendered resource. A user page is a degenerate space whose sole admin is the owner: tier-gated actions show only to the owner, specific-role gates match nobody (observers can be added later). - Filter actions in all five renderers (additive; undeclared actions unchanged): QueryResultTable(Builder), QueryResultList(Builder), QueryResultPlainParagraphBuilder. - Remove the whole-view filter (AbstractResourceWithProfile) and ViewDisplay/ View view-level visibility parsing. - Tests for the tier ranking and isViewerEntitled matching. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The view-creation template can't leave the per-action gen:isVisibleTo statement optional inside its repeated action group, so it emits an explicit default. Add gen:EveryoneRole (rank-0 "no restriction" sentinel — a Nanodash-side visibility tier, never a nanopub-query grant tier): - KPXL_TERMS.EVERYONE_ROLE; SpaceMemberRole.isTier includes it and isViewerEntitled short-circuits to visible (incl. anonymous) when present. - Tests for the everyone-to-all semantics. - Doc updated; records the published authoring template RA8_hijwsfGCryMYtjtEpec21ZSNY68-qmL0bHRWR0sWM (tier picker + SpaceMemberRole API + EveryoneRole default). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s done Per-action gating is client-side relevance-gating over public data, so there is no server-side enforcement to do (that framing was a holdover from the whole-view design). Replace it with an optional performance-only note (have a query return the viewer's tier directly), and mark the feature Implemented. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The presets and view-displays tables in AboutUserPanel / AboutSpacePanel / AboutResourcePanel were built without resourceWithProfile, so their "add preset…" / "add view display…" result actions fell into ButtonList's ungated regular bucket and leaked onto other users' (and visitors') pages. Pass resourceWithProfile so the actions are owner/admin-gated — on user pages via the IndividualAgent admin bucket immediately, and on space/resource pages via the per-action gen:isVisibleTo filter (which needs the governing space resolved from the resource). Pairs with the gen:isVisibleTo gen:MaintainerRole republish of the preset-assignments-view and view-displays-view. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Republished preset-assignments-view (RAdznW...) and view-displays-view (RAZJUh...) with gen:isVisibleTo gen:MaintainerRole; panels pass resourceWithProfile. Mark the known gap as fixed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
View-creation templates can't leave a statement optional inside a repeated action group, so views now carry every action field with "void" for the not-applicable ones (its presence lets Nanodash repopulate the action group when superseding a view). Parse "void" as absent so it never becomes a bogus param_void in the action link. Pairs with republishing preset-assignments-view (RA4fgq...) and view-displays-view (RAl3LO...) with complete "void"-filled action blocks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
First, low-risk step toward #478. Adds three standalone About pages, reachable by direct URL only — no existing page is changed, and nothing links to them yet.
AboutSpacePage/spaceabout?id=AboutResourcePage/resourceabout?id=AboutUserPage/userabout?id=What each page shows
get-view-displaysquery Nanodash uses internally.PublicProfilePanel(introductions, public keys with per-user approval, default license) that works for any user — unlike the session/edit-boundProfilePageitems.The tables carry their own
dct:title, so there are no extra section headers.Supporting nanopub (published live)
The view-displays listing is backed by a new
ResourceView/TabularViewnanopub published to the live registry:https://w3id.org/np/RAQO0kK2FFtdfdGShuLkpFTbrq90btzt38z4w1hGVQfJE/view-displays-viewIt deliberately omits
gen:appliesToInstancesOf(like the references-view) so it never auto-attaches to the main pages; it's rendered explicitly viaView.get(...).Other changes
ReferencesPage.REFERENCES_VIEWpromoted topublic staticfor reuse.mountPage(...)lines inWicketApplication.Deliberately deferred (marked
// TODO(#478))Space).Status
mvn compilepasses. Not yet verified in a running Nanodash (needs the dev server + real resource IDs to see the tables populate).🤖 Generated with Claude Code