Skip to content

feat: editable notice field in sidebar + metadata API integration#2709

Open
flash7777 wants to merge 13 commits into
opencloud-eu:mainfrom
flash7777:feature/notice
Open

feat: editable notice field in sidebar + metadata API integration#2709
flash7777 wants to merge 13 commits into
opencloud-eu:mainfrom
flash7777:feature/notice

Conversation

@flash7777

Copy link
Copy Markdown

Summary

  • Adds a two-line Notice textarea below tags in the file details sidebar
  • Reads user.oc.md.note via GET /graph/v1beta1/.../metadata (key: note)
  • Writes via PUT /graph/v1beta1/.../metadata on blur or Ctrl+Enter
  • New SetNoticeFactory (WebDAV PROPPATCH) for future use when PROPPATCH namespace mapping is fixed
  • DavProperty.Notice added to PROPFIND default properties
  • Unit tests for special characters (umlauts, CJK, emoji, XML entities, etc.)

Dependencies

Test plan

  • Open file sidebar, verify Notice textarea appears below tags
  • Type text, click away (blur) — verify xattr user.oc.md.note is set on server
  • Re-open sidebar — verify text is loaded from metadata API
  • Test with special characters: Ä Ö Ü, <script>, emoji, newlines
  • Verify Ctrl+Enter also saves

🤖 Generated with Claude Code

flash and others added 13 commits June 16, 2026 18:12
New sidebar tab "Metadata" that displays custom metadata (user.oc.md.*)
for the selected file or folder. Fetches data from the Graph API
endpoint GET /drives/{driveID}/items/{itemID}/metadata.

- MetadataPanel.vue: renders key-value pairs with formatted labels
- useFileSideBars.ts: registers panel, visible for single item selection
- Strips "oy." prefix and converts camelCase to Title Case for display

Depends on: OpenCloud Graph API metadata endpoint
1. Resource model: add `immutable` boolean field

2. Indicators (useResourceIndicators.ts):
   - Frozen file: snowflake icon
   - Protected folder: shield-check icon

3. Context menu actions (useFileActionsImmutable.ts):
   - "Freeze file": POST /freeze with confirmation dialog (irreversible!)
   - "Protect folder": POST /protect
   - "Remove protection": DELETE /protect

4. Actions registered in useFileActions.ts for context menu

Depends on: OpenCloud Graph API freeze/protect/unprotect endpoints
(blocked by cs3org/cs3apis#275 - Gateway SetImmutable RPC)
Read oc:immutable property from PROPFIND responses (no extra request).
Reva returns "frozen" (file) or "protected" (folder/inherited) state.

Data flow:
  Reva xattr → GetImmutableState() → oc:immutable property
  → WebDAV PROPFIND → DavProperty.Immutable
  → resource.immutableState ("frozen"|"protected"|undefined)
  → Quick Action icons + Indicator badges

Quick Actions (hover buttons in file list):
  File   | normal    | leaf icon       | click → freeze (confirmation dialog)
  File   | frozen    | snowflake icon  | disabled (irreversible)
  File   | protected | shield-fill     | disabled (parent protected)
  Folder | normal    | shield-line     | click → protect
  Folder | protected | shield-fill     | click → unprotect

Indicators (badges next to filename):
  frozen    → snowflake icon
  protected → shield-fill icon

Changes:
- DavProperty.Immutable added + included in default PROPFIND request
- Resource type: immutableState?: 'frozen' | 'protected'
- Resource builder: maps oc:immutable to immutableState
- useFileActionsImmutable: 5 actions for all state combinations
- useResourceIndicators: indicator based on immutableState
- useFileActions: registered as quickActionsExtensionPoint (not context!)
- immutableState: 'frozen' | 'protected' | 'shielded'
- Quick Actions: shield for protect/unprotect, leaf for freeze
- Indicators: shield-fill (protected), shield-line (shielded), snowflake (frozen)
- Shielded folders can still be protected/unprotected
- console.error if folder has frozen state (bug detection)
- After unprotect: check parent state → set 'shielded' if parent still protected
- Batch protect: select multiple folders → protect all
- Batch unprotect: select multiple protected folders → unprotect all
- No batch freeze (irreversible, single-item only with confirmation)
Move useFileActionsImmutable from web-pkg to web-app-files (where
v7.x actions live). Add SpecialFolderHeader component and
useSpecialFolderView composable for .special/ directory detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a two-line textarea below tags in the file details sidebar that
reads and writes the oc:md-note WebDAV property (user.oc.md.note xattr).
Saves on blur or Ctrl+Enter via PROPPATCH.

- DavProperty.Notice mapped to oc:md-note
- SetNoticeFactory analog to SetFavoriteFactory
- Resource.notice field parsed from PROPFIND
- Unit tests for special characters (umlauts, CJK, XML, emoji, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changed DavProperty.Notice from md-note to md-oy-notice to match
the oy.* Aktenplan metadata namespace (user.oc.md.oy.notice).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The metadata endpoint is registered under /graph/v1beta1/, not /graph/v1.0/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PROPFIND cannot resolve custom oc: properties to ArbitraryMetadata keys
due to namespace/key mismatch (metadataKeyOf returns full namespace URI
but ArbitraryMetadata uses short dot-separated keys). Load notice from
/graph/v1beta1/.../metadata endpoint which works correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use md-note (user.oc.md.note) for the notice field, metadata API
key is 'note'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PROPPATCH sends full namespace URI as metadata key which doesn't match
the short xattr key. Use PUT /graph/v1beta1/.../metadata instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant