feat(overview): flag shared files with a sharing indicator - #125
feat(overview): flag shared files with a sharing indicator#125karlitschek wants to merge 1 commit into
Conversation
Files in the overview could not be told apart by sharing state. Show a
"shared" indicator on both the grid cards and the list rows.
A file counts as shared when the current user has shared it out (a
non-empty oc:share-types) or it is owned by someone else and shared with
them — the same definition the Files app uses. The overview did not fetch
sharing state, so register the oc:share-types DAV property, as
files_sharing does, to include it in the search results.
The indicator carries an accessible label ("Shared", or "Shared by
{owner}" for an incoming share) so the state is never conveyed by icon or
colour alone. In the grid it uses a new FileCard overlay slot over the
thumbnail; in the list it joins the favourite star in the indicator slot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Frank Karlitschek <frank.karlitschek@nextcloud.com>
There was a problem hiding this comment.
Pull request overview
Adds a sharing-state indicator to the Office overview so users can distinguish shared vs non-shared files consistently with Nextcloud Files (via oc:share-types and ownership), rendering the indicator in both grid cards (overlay badge) and list rows (row indicator area), with accessible labeling.
Changes:
- Register
oc:share-typesfor the overview DAV search and add a sharing-state utility (isShared/isIncomingShare/outgoingShareTypes). - Introduce a
ShareIndicatorcomponent (with ARIA label + tooltip) and integrate it into grid and list views. - Extend
FileCardwith an optionaloverlayslot to support badge-style overlays over thumbnails.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/views/OfficeOverview.vue | Renders ShareIndicator in grid overlay and list indicator area; adds indicator layout styling. |
| src/utils/fileSharing.ts | New pure helpers to normalize oc:share-types and determine shared/incoming share state. |
| src/utils/fileSharing.spec.ts | Adds unit tests for the new sharing helpers. |
| src/test-utils/fixtures.ts | Extends makeNode fixtures to include nested DAV-shaped share types. |
| src/services/officeFiles.ts | Registers oc:share-types DAV property so the overview search returns sharing state. |
| src/services/officeFiles.spec.ts | Verifies DAV property registration occurs at module load. |
| src/components/ShareIndicator.vue | New share icon indicator with accessible label/tooltip for outgoing vs incoming shares. |
| src/components/ShareIndicator.spec.ts | Unit tests for rendering and labeling behavior of ShareIndicator. |
| src/components/FileCard.vue | Adds overlay slot and overlay positioning/chip styling over the preview thumbnail. |
| src/components/FileCard.spec.ts | Tests overlay slot rendering behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| it('flattens the nested DAV shape for a single share type', () => { | ||
| expect(outgoingShareTypes(makeNode({ shareTypes: [3] }))).toEqual([3]) | ||
| }) | ||
|
|
||
| it('flattens the nested DAV shape for several share types', () => { | ||
| expect(outgoingShareTypes(makeNode({ shareTypes: [0, 3] }))).toEqual([0, 3]) | ||
| }) |
| <button type="button" class="file-card" @click="$emit('click', $event)"> | ||
| <div class="file-card__preview"> | ||
| <slot name="preview" /> | ||
| <span v-if="$slots.overlay" class="file-card__overlay"> |
|
TL;DR: Solid feature, good test coverage on the new utils/component. Two real accessibility defects in the label, plus a reuse-before-you-write miss and the recurring untested-wiring gap. Proposed fixes below. Findings and proposed fixes1. Double-escaped owner names in the accessible label (medium-high)
That string then gets bound via Fix — the escaping is redundant on a DOM-attribute sink, so opt the placeholder out: return owner
? t('office', 'Shared by {owner}', { owner: { value: owner, escape: false } })
: t('office', 'Shared')Worth a regression test with a name containing a special character, since the current fixture ( 2.
|
What
Files in the overview couldn't be told apart by sharing state. This adds a "shared" indicator to both the grid cards and the list rows.
How it decides "shared"
Mirrors the Files app's sharing-status definition, so the indicator means the same thing here as elsewhere in Nextcloud:
oc:share-typesis non-empty), orThe overview's DAV search didn't fetch sharing state, so it now registers the
oc:share-typesproperty (the same callfiles_sharingmakes). The nestedoc:share-typespayload is flattened the same way the Files app does.Accessibility
The indicator has an accessible label — "Shared", or "Shared by {owner}" for an incoming share — used as both the ARIA name and the tooltip, so the state is never carried by icon or colour alone.
Notes
isShared/isIncomingShare/outgoingShareTypesutil (pure, takescurrentUidexplicitly likefilterFiles) and aShareIndicatorcomponent, each with a.spec.ts.FileCardgains an optionaloverlayslot (positioned over the preview) for the grid badge.--color-box-shadow-rgbfor the badge chip shadow, etc.).js//css/still need a maintainer/compile.<oc:share-types>and the indicator shows on a shared file (grid and list), owner-only files stay unmarked.🤖 Generated with Claude Code