@conduction/nextcloud-vue 2.150.0 → 2.151.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +7 -2
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +40 -41
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +6 -3
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +13 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +5 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +46 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +64 -64
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +15 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue.js +1 -1
- package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue2.js.map +1 -1
- package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js +16 -5
- package/dist/esm/components/CnPlanWidget/CnPlanWidgetRow.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +25 -2
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +82 -68
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue.js +1 -1
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/eventStatus.js +43 -2
- package/dist/esm/integrations/builtin/calendar/eventStatus.js.map +1 -1
- package/dist/esm/l10n/en.json.js +4 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +5 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +623 -362
- package/dist/nextcloud-vue.cjs.js +894 -720
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +623 -362
- package/l10n/en.json +4 -1
- package/l10n/nl.json +5 -2
- package/package.json +1 -1
- package/src/components/CnActionDialog/CnActionDialog.vue +17 -4
- package/src/components/CnConversationThread/CnConversationThread.vue +16 -2
- package/src/components/CnConversationThread/CnConversationWidget.vue +5 -1
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +47 -2
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.md +1 -1
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +15 -1
- package/src/components/CnPlanWidget/CnPlanWidgetRow.vue +17 -2
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +45 -2
- package/src/components/CnRetentionWidget/CnRetentionWidget.vue +8 -1
- package/src/components/CnTimelineWidget/CnTimelineManage.vue +1 -1
- package/src/css/dialog.css +6 -0
- package/src/css/look-board-detail.css +137 -0
- package/src/css/look-board.css +78 -2
- package/src/integrations/builtin/calendar/eventStatus.js +42 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnFilesBrowser.vue2.js","sources":["../../../../src/components/CnFilesBrowser/CnFilesBrowser.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tclass=\"cn-files-browser\"\n\t\t:class=\"{ 'cn-files-browser--dragging': dragging, 'cn-files-browser--drop-panel': dropOverlay && dropDetailTemplate !== '' }\"\n\t\tdata-testid=\"cn-files-browser\"\n\t\t@dragenter.prevent=\"onDragEnter\"\n\t\t@dragover.prevent=\"onDragOver\"\n\t\t@dragleave.prevent=\"onDragLeave\"\n\t\t@drop.prevent=\"onDrop\">\n\t\t<!-- The drop state, drawn on the browser itself when the host names it\n\t\t (`dropOverlay`): a dashed frame and one centred line over the list,\n\t\t so it is plain where the files go. The overlay is decoration for\n\t\t sighted users; the live region below says the same thing to a\n\t\t screen reader, and the upload button stays the way in for anyone\n\t\t who cannot drag. -->\n\t\t<div v-if=\"dropOverlay && dragging\"\n\t\t\tclass=\"cn-files-browser__drop-overlay\"\n\t\t\taria-hidden=\"true\"\n\t\t\tdata-testid=\"cn-files-browser-drop-overlay\">\n\t\t\t<span class=\"cn-files-browser__drop-icon\"><Upload :size=\"28\" /></span>\n\t\t\t<strong class=\"cn-files-browser__drop-label\">{{ cnTranslate(dropLabel) }}</strong>\n\t\t\t<span v-if=\"dropDetailText\"\n\t\t\t\tclass=\"cn-files-browser__drop-detail\"\n\t\t\t\tdata-testid=\"cn-files-browser-drop-detail\">{{ dropDetailText }}</span>\n\t\t</div>\n\t\t<p v-if=\"dropOverlay\"\n\t\t\tclass=\"hidden-visually\"\n\t\t\taria-live=\"polite\"\n\t\t\tdata-testid=\"cn-files-browser-drop-status\">\n\t\t\t{{ dropStatus }}\n\t\t</p>\n\t\t<!-- The bar: where you are, and what you can add. The crumbs are the\n\t\t Files app's own breadcrumb component; the New menu lists what the\n\t\t Files app and its plugins registered for this folder (a new folder,\n\t\t a template, a file request) beside a plain upload. -->\n\t\t<div class=\"cn-files-browser__bar\">\n\t\t\t<NcBreadcrumbs class=\"cn-files-browser__crumbs\" :class=\"{ 'cn-files-browser__crumbs--at-root': atRoot }\">\n\t\t\t\t<!-- The whole trail from the user's files root, as the Files app\n\t\t\t\t draws it. A crumb above the browser's root links into the Files\n\t\t\t\t app (the browser never leaves its root); the root and everything\n\t\t\t\t beneath it navigate in place. NcBreadcrumbs draws its first\n\t\t\t\t crumb as a home icon and keeps the name for screen readers;\n\t\t\t\t forceIconText puts the name beside the icon. -->\n\t\t\t\t<NcBreadcrumb\n\t\t\t\t\tv-for=\"(crumb, index) in crumbs\"\n\t\t\t\t\t:key=\"crumb.path\"\n\t\t\t\t\t:name=\"crumb.name\"\n\t\t\t\t\t:forceIconText=\"index === 0\"\n\t\t\t\t\t:disableDrop=\"true\"\n\t\t\t\t\t:href=\"crumb.aboveRoot ? filesAppUrl(crumb.path) : undefined\"\n\t\t\t\t\t:target=\"crumb.aboveRoot ? '_blank' : undefined\"\n\t\t\t\t\t:data-above-root=\"crumb.aboveRoot ? 'true' : undefined\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-crumb\"\n\t\t\t\t\t@click=\"crumb.aboveRoot ? undefined : navigate(crumb.path)\" />\n\t\t\t</NcBreadcrumbs>\n\t\t\t<!-- The Columns chooser hides declared columns for this user. It\n\t\t\t cannot add one: it is built by walking the host's declaration,\n\t\t\t so a column the host removed is not listed and cannot be\n\t\t\t ticked back on however the stored preference reads. -->\n\t\t\t<NcActions v-if=\"columnsChooserEnabled\"\n\t\t\t\t:menuName=\"columnsLabel\"\n\t\t\t\t:forceMenu=\"true\"\n\t\t\t\tdata-testid=\"cn-files-browser-columns\">\n\t\t\t\t<NcActionCheckbox\n\t\t\t\t\tv-for=\"column in declaredColumns\"\n\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t:modelValue=\"isColumnVisible(column)\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-column-${column.key}`\"\n\t\t\t\t\t@update:modelValue=\"toggleColumn(column)\">\n\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t</NcActionCheckbox>\n\t\t\t</NcActions>\n\t\t\t<NcActions v-if=\"canChange && newMenu\"\n\t\t\t\t:menuName=\"newLabel\"\n\t\t\t\t:forceMenu=\"true\"\n\t\t\t\t:forceName=\"true\"\n\t\t\t\t:variant=\"uploadButton ? 'secondary' : 'primary'\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-new\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Plus :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t<NcActionButton :closeAfterClick=\"true\" data-testid=\"cn-files-browser-upload\" @click=\"pickFiles\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<Upload :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ uploadLabel }}\n\t\t\t\t</NcActionButton>\n\t\t\t\t<NcActionButton\n\t\t\t\t\tv-for=\"entry in newMenuEntries\"\n\t\t\t\t\t:key=\"entry.id\"\n\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-new-${entry.id}`\"\n\t\t\t\t\t@click=\"runNewEntry(entry)\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcIconSvgWrapper v-if=\"entry.iconSvgInline\" :svg=\"entry.iconSvgInline\" />\n\t\t\t\t\t\t<span v-else-if=\"entry.iconClass\" :class=\"entry.iconClass\" />\n\t\t\t\t\t\t<Plus v-else :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ entry.displayName }}\n\t\t\t\t</NcActionButton>\n\t\t\t\t<!-- The host's own entries, after the Files app's. -->\n\t\t\t\t<NcActionButton\n\t\t\t\t\tv-for=\"action in newActions\"\n\t\t\t\t\t:key=\"`host-${action.id}`\"\n\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-new-host-${action.id}`\"\n\t\t\t\t\t@click=\"runHostAction(action, null)\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<CnIcon :name=\"action.icon || 'Plus'\" :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t</NcActionButton>\n\t\t\t</NcActions>\n\t\t\t<!-- The host's own buttons in the bar (\"Vraag een bestand aan een\n\t\t\t partij\", DqZaakDocumenten), dispatched like a New-menu entry with\n\t\t\t the current folder; `#header-actions` adds anything else. -->\n\t\t\t<NcButton v-for=\"action in headerActions\"\n\t\t\t\t:key=\"`header-${action.id}`\"\n\t\t\t\t:variant=\"action.variant === 'primary' ? 'primary' : 'secondary'\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\t:data-testid=\"`cn-files-browser-header-action-${action.id}`\"\n\t\t\t\t@click=\"runHostAction(action, null)\">\n\t\t\t\t<template v-if=\"action.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"action.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ hostLabel(action) }}\n\t\t\t</NcButton>\n\t\t\t<!-- New folder as its own button, when the host names it\n\t\t\t (`folderButton`): a bar without the New menu still creates\n\t\t\t folders. -->\n\t\t\t<NcButton v-if=\"folderButton && canChange\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-new-folder-button\"\n\t\t\t\t@click=\"askNewFolder\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<FolderPlusOutline :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ newFolderLabel }}\n\t\t\t</NcButton>\n\t\t\t<!-- @slot header-actions Buttons in the bar, before the upload button. -->\n\t\t\t<slot name=\"header-actions\" />\n\t\t\t<!-- A plain upload as its own button, when the host names it\n\t\t\t (`uploadButton`). It takes the primary place and the New\n\t\t\t menu steps back beside it. -->\n\t\t\t<NcButton v-if=\"uploadButton && canChange\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-upload-button\"\n\t\t\t\t@click=\"pickFiles\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Upload :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ uploadButtonLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- `:ref` (dynamic), not `ref`: a static ref on a vnode with only static\n\t\t bindings is hoisted, and a hoisted vnode has no owner instance to\n\t\t hold the ref, which throws in a production build. -->\n\t\t<input\n\t\t\t:ref=\"fileInputRef\"\n\t\t\ttype=\"file\"\n\t\t\tmultiple\n\t\t\tclass=\"cn-files-browser__file-input\"\n\t\t\t:aria-label=\"uploadLabel\"\n\t\t\t@change=\"onFilesPicked\">\n\n\t\t<ul v-if=\"uploads.length > 0\" class=\"cn-files-browser__uploads\" data-testid=\"cn-files-browser-uploads\">\n\t\t\t<li v-for=\"upload in uploads\" :key=\"upload.key\" class=\"cn-files-browser__upload\">\n\t\t\t\t<span class=\"cn-files-browser__upload-name\">{{ upload.name }}</span>\n\t\t\t\t<NcProgressBar :value=\"upload.progress\" :error=\"upload.error !== ''\" />\n\t\t\t\t<span v-if=\"upload.error\" class=\"cn-files-browser__upload-error\" role=\"alert\">{{ upload.error }}</span>\n\t\t\t</li>\n\t\t</ul>\n\n\t\t<!-- The review summary (`reviewSummary`): how many files are reviewed,\n\t\t a bar in the review tones and a legend with the count per value. -->\n\t\t<div v-if=\"review && review.total > 0 && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__review\"\n\t\t\tdata-testid=\"cn-files-browser-review\">\n\t\t\t<div class=\"cn-files-browser__review-head\">\n\t\t\t\t<strong class=\"cn-files-browser__review-title\">{{ reviewTitle }}</strong>\n\t\t\t\t<span v-if=\"reviewSubtitle\" class=\"cn-files-browser__review-sub\">{{ reviewSubtitle }}</span>\n\t\t\t</div>\n\t\t\t<span class=\"cn-files-browser__review-bar\" role=\"img\" :aria-label=\"reviewTitle\">\n\t\t\t\t<span v-for=\"segment in review.segments\"\n\t\t\t\t\tv-show=\"segment.count > 0 && !isOpenValue(segment.value)\"\n\t\t\t\t\t:key=\"segment.value\"\n\t\t\t\t\t:class=\"`cn-files-browser__review-part cn-files-browser__review-part--${segment.tone}`\"\n\t\t\t\t\t:style=\"{ width: `${segment.share}%` }\" />\n\t\t\t</span>\n\t\t\t<ul class=\"cn-files-browser__review-legend\">\n\t\t\t\t<li v-for=\"segment in review.segments\" :key=\"segment.value\" data-testid=\"cn-files-browser-review-entry\">\n\t\t\t\t\t<span :class=\"`cn-files-browser__review-dot cn-files-browser__review-part--${segment.tone}`\" aria-hidden=\"true\" />\n\t\t\t\t\t{{ hostLabel(segment) }}\n\t\t\t\t\t<strong>{{ segment.count }}</strong>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<!-- The host's filter: per declared column, a chip per value in use\n\t\t with how many files carry it. Chips narrow the list. -->\n\t\t<div v-if=\"facetGroups.length > 0 && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__facets\"\n\t\t\tdata-testid=\"cn-files-browser-facets\">\n\t\t\t<div v-for=\"facet in facetGroups\"\n\t\t\t\t:key=\"facet.key\"\n\t\t\t\tclass=\"cn-files-browser__facet\"\n\t\t\t\trole=\"group\"\n\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Filter by {column}', { column: facet.label })\">\n\t\t\t\t<button v-for=\"option in facet.values\"\n\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-files-browser__facet-chip\"\n\t\t\t\t\t:class=\"{ 'cn-files-browser__facet-chip--active': option.active }\"\n\t\t\t\t\t:aria-pressed=\"option.active ? 'true' : 'false'\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-facet-chip\"\n\t\t\t\t\t@click=\"toggleFacet(facet.key, option.value)\">\n\t\t\t\t\t{{ option.value }}\n\t\t\t\t\t<strong class=\"cn-files-browser__facet-count\">{{ option.count }}</strong>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<NcButton v-if=\"facetActive\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\tdata-testid=\"cn-files-browser-facets-clear\"\n\t\t\t\t@click=\"clearFacets\">\n\t\t\t\t{{ t('nextcloud-vue', 'Clear filters') }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- The host's bulk actions, once something is selected. -->\n\t\t<div v-if=\"bulkEnabled && selectedIds.length > 0\"\n\t\t\tclass=\"cn-files-browser__bulk-bar\"\n\t\t\trole=\"toolbar\"\n\t\t\t:aria-label=\"t('nextcloud-vue', 'Actions for the selected files')\"\n\t\t\tdata-testid=\"cn-files-browser-bulk-bar\">\n\t\t\t<span class=\"cn-files-browser__bulk-count\" aria-live=\"polite\" data-testid=\"cn-files-browser-bulk-count\">\n\t\t\t\t{{ selectionCountText }}\n\t\t\t</span>\n\t\t\t<NcButton v-for=\"action in bulkActions\"\n\t\t\t\t:key=\"action.id\"\n\t\t\t\t:data-testid=\"`cn-files-browser-bulk-action-${action.id}`\"\n\t\t\t\t@click=\"runBulkAction(action)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<CnIcon :name=\"action.icon || 'CheckboxMultipleMarkedOutline'\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ hostLabel(action) }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"showClearSelection\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\tdata-testid=\"cn-files-browser-bulk-clear\"\n\t\t\t\t@click=\"clearSelection\">\n\t\t\t\t{{ t('nextcloud-vue', 'Clear selection') }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<NcLoadingIcon v-if=\"loading\" :size=\"32\" class=\"cn-files-browser__loading\" />\n\n\t\t<CnEmptyContent v-else-if=\"error !== ''\"\n\t\t\terror\n\t\t\t:name=\"error\"\n\t\t\tclass=\"cn-files-browser__state\">\n\t\t\t<template #icon>\n\t\t\t\t<AlertCircleOutline :size=\"44\" />\n\t\t\t</template>\n\t\t\t<template #action>\n\t\t\t\t<NcButton @click=\"refresh\">\n\t\t\t\t\t{{ retryLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</CnEmptyContent>\n\n\t\t<CnEmptyContent\n\t\t\tv-else-if=\"sorted.length === 0 && linkedItems.length === 0\"\n\t\t\t:name=\"emptyLabel\"\n\t\t\t:description=\"canChange ? emptyHint : ''\"\n\t\t\tclass=\"cn-files-browser__state\">\n\t\t\t<template #icon>\n\t\t\t\t<FolderOutline :size=\"44\" />\n\t\t\t</template>\n\t\t</CnEmptyContent>\n\n\t\t<!-- The table. Its rows are @nextcloud/files nodes read over DAV, and\n\t\t each row's menu is the list of actions the Files app registered on\n\t\t this page, offered under the same names and icons the Files app\n\t\t uses. What cannot run away from the Files page (the details\n\t\t sidebar) is left out, and Show in Files covers it. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-files-browser__body\"\n\t\t\t:class=\"{ 'cn-files-browser__body--with-side': sideNode !== null && !sideInPage }\">\n\t\t\t<table class=\"cn-files-browser__table\" data-testid=\"cn-files-browser-table\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th v-if=\"bulkEnabled\" class=\"cn-files-browser__col-select\" scope=\"col\">\n\t\t\t\t\t\t\t<input type=\"checkbox\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__select\"\n\t\t\t\t\t\t\t\t:checked=\"allSelected\"\n\t\t\t\t\t\t\t\t:indeterminate.prop=\"someSelected && !allSelected\"\n\t\t\t\t\t\t\t\t:disabled=\"selectableIds.length === 0\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Select all files')\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-select-all\"\n\t\t\t\t\t\t\t\t@change=\"toggleAll($event.target.checked)\">\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th class=\"cn-files-browser__col-icon\" scope=\"col\">\n\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ t('nextcloud-vue', 'Type') }}</span>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\"\n\t\t\t\t\t\t\t:aria-sort=\"ariaSort(sortTokenOf(column))\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-header-${column.key}`\">\n\t\t\t\t\t\t\t<button v-if=\"column.sortable !== false\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__sort\"\n\t\t\t\t\t\t\t\t@click=\"sortBy(sortTokenOf(column))\">\n\t\t\t\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t\t\t\t\t<component :is=\"sortIcon(sortTokenOf(column))\" v-if=\"sortKey === sortTokenOf(column)\" :size=\"16\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th class=\"cn-files-browser__col-actions\" scope=\"col\">\n\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ t('nextcloud-vue', 'Actions') }}</span>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t<!-- A heading row per group when the host groups on a column; the\n\t\t\t\t destructured entry is either a group or a node. -->\n\t\t\t\t\t<template v-for=\"{ key, group, node } in displayRows\" :key=\"key\">\n\t\t\t\t\t\t<tr v-if=\"group\"\n\t\t\t\t\t\t\tclass=\"cn-files-browser__group\"\n\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-group\">\n\t\t\t\t\t\t\t<th :colspan=\"columnCount\" scope=\"rowgroup\" class=\"cn-files-browser__group-heading\">\n\t\t\t\t\t\t\t\t{{ group.label }}\n\t\t\t\t\t\t\t\t<span class=\"cn-files-browser__group-count\">{{ group.count }}</span>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:key=\"key\"\n\t\t\t\t\t\t\tclass=\"cn-files-browser__row\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-files-browser__row--folder': isFolder(node) }\"\n\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-row\"\n\t\t\t\t\t\t\t:data-name=\"node.basename\"\n\t\t\t\t\t\t\t@click=\"onRowClick(node, $event)\"\n\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t@auxclick=\"onRowAuxClick(node, $event)\">\n\t\t\t\t\t\t\t<td v-if=\"bulkEnabled\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__col-select\"\n\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t\t<input v-if=\"!isFolder(node)\"\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__select\"\n\t\t\t\t\t\t\t\t\t:checked=\"isSelected(node)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Select {name}', { name: node.basename })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-select\"\n\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(node, $event.target.checked)\">\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"cn-files-browser__col-icon\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tv-if=\"previewUrlFor(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__thumb\"\n\t\t\t\t\t\t\t\t\t:src=\"previewUrlFor(node)\"\n\t\t\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\t\t\t@error=\"onPreviewError(node)\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tv-else-if=\"mimeIconFor(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__mime\"\n\t\t\t\t\t\t\t\t\t:src=\"mimeIconFor(node)\"\n\t\t\t\t\t\t\t\t\talt=\"\">\n\t\t\t\t\t\t\t\t<FolderOutline v-else-if=\"isFolder(node)\" :size=\"32\" />\n\t\t\t\t\t\t\t\t<FileOutline v-else :size=\"32\" />\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\"\n\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-cell-${column.key}`\">\n\t\t\t\t\t\t\t\t<span v-if=\"column.key === 'name'\" class=\"cn-files-browser__name\">{{ node.basename }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"column.key === 'name' && nameSecondaryOf(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__name-secondary\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-name-secondary\">{{ nameSecondaryOf(node) }}</span>\n\t\t\t\t\t\t\t\t<template v-else-if=\"column.key === 'size'\">\n\t\t\t\t\t\t\t\t\t{{ isFolder(node) ? '' : formatSize(node.size) }}\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<NcDateTime v-else-if=\"column.key === 'modified'\" :timestamp=\"node.mtime\" :ignoreSeconds=\"true\" />\n\t\t\t\t\t\t\t\t<!-- Everything the host declared renders through the same\n\t\t\t\t\t\t\t cell renderer the tables use, so a `formatter` means\n\t\t\t\t\t\t\t here what it means there. -->\n\t\t\t\t\t\t\t\t<CnCellRenderer v-else\n\t\t\t\t\t\t\t\t\t:class=\"column.widget !== 'badge' && toneOf(column, node) ? `cn-files-browser__tone cn-files-browser__tone--${toneOf(column, node)}` : null\"\n\t\t\t\t\t\t\t\t\t:value=\"cellValue(column, node)\"\n\t\t\t\t\t\t\t\t\t:formatter=\"column.formatter || null\"\n\t\t\t\t\t\t\t\t\t:formatterOptions=\"column.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t:widget=\"column.widget || null\"\n\t\t\t\t\t\t\t\t\t:widgetProps=\"cellWidgetProps(column, node)\"\n\t\t\t\t\t\t\t\t\t:row=\"node\" />\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"cn-files-browser__col-actions\" @click.stop @auxclick.stop>\n\t\t\t\t\t\t\t\t<!-- The host's one visible button on a file (\"Beoordelen\"),\n\t\t\t\t\t\t\t\t primary while the row still asks for it. -->\n\t\t\t\t\t\t\t\t<NcButton v-if=\"rowButton && !isFolder(node) && hostActionApplies(rowButton, node)\"\n\t\t\t\t\t\t\t\t\t:variant=\"rowButtonPrimary(node) ? 'primary' : 'secondary'\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__row-button\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', '{action}: {name}', { action: hostLabel(rowButton), name: node.basename })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-row-button\"\n\t\t\t\t\t\t\t\t\t@click=\"runHostAction(rowButton, node)\">\n\t\t\t\t\t\t\t\t\t{{ hostLabel(rowButton) }}\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcActions class=\"cn-files-browser__row-menu\" :forceMenu=\"true\" :ariaLabel=\"t('nextcloud-vue', 'Actions for {name}', { name: node.basename })\">\n\t\t\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\t\t\tv-for=\"action in actionsFor(node)\"\n\t\t\t\t\t\t\t\t\t\t:key=\"action.id\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-action-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t@click=\"run(action, node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper :svg=\"iconOf(action, node)\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ labelOf(action, node) }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<!-- The host's own actions on a file (never on a folder): declared\n\t\t\t\t\t\t\t\t in its manifest, dispatched through the page's action runner\n\t\t\t\t\t\t\t\t with the node's file id, name and path merged in. -->\n\t\t\t\t\t\t\t\t\t<template v-if=\"!isFolder(node)\">\n\t\t\t\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\t\t\t\tv-for=\"action in hostActionsFor(node)\"\n\t\t\t\t\t\t\t\t\t\t\t:key=\"`host-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-host-action-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t\t@click=\"runHostAction(action, node)\">\n\t\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<CnIcon :name=\"action.icon || 'FileDocumentEditOutline'\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t<NcActionSeparator v-if=\"actionsFor(node).length > 0 || (!isFolder(node) && hostActionsFor(node).length > 0)\" />\n\t\t\t\t\t\t\t\t\t<!-- The Files app's own rename is its list's inline input,\n\t\t\t\t\t\t\t\t which is not here; this one is a dialog over a DAV move. -->\n\t\t\t\t\t\t\t\t\t<!-- With a `source`, the Files app's actions (which act over\n\t\t\t\t\t\t\t\t WebDAV) are not offered; download and delete go through\n\t\t\t\t\t\t\t\t the source instead. -->\n\t\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\t\tv-if=\"source && sourceDownloadUrl(node)\"\n\t\t\t\t\t\t\t\t\t\t:href=\"sourceDownloadUrl(node)\"\n\t\t\t\t\t\t\t\t\t\t:download=\"node.basename\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-download\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<Download :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ downloadLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t\t<NcActionButton v-if=\"source && canChange\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-delete\"\n\t\t\t\t\t\t\t\t\t\t@click=\"askRemove(node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<TrashCanOutline :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ deleteLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<NcActionButton v-if=\"canChange\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-rename\"\n\t\t\t\t\t\t\t\t\t\t@click=\"askRename(node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<Pencil :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ renameLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\t\tv-if=\"node.fileid && !source\"\n\t\t\t\t\t\t\t\t\t\t:href=\"permalink(node)\"\n\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ showInFilesLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t</NcActions>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</template>\n\t\t\t\t\t<tr v-if=\"facetActive && filteredFiles.length === 0\" class=\"cn-files-browser__no-match-row\">\n\t\t\t\t\t\t<td :colspan=\"columnCount\" class=\"cn-files-browser__no-match\" data-testid=\"cn-files-browser-no-match\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'No files match the filter.') }}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<!-- Rows that are not nodes of this folder: documents the host\n\t\t\t\t joined from elsewhere (another object's folder). Open and\n\t\t\t\t download only; nothing here can change the file. -->\n\t\t\t\t\t<tr\n\t\t\t\t\t\tv-for=\"item in linkedItems\"\n\t\t\t\t\t\t:key=\"`linked-${item.id}`\"\n\t\t\t\t\t\tclass=\"cn-files-browser__row cn-files-browser__row--linked\"\n\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-row\"\n\t\t\t\t\t\t:data-name=\"item.name\"\n\t\t\t\t\t\t@click=\"openLinked(item)\"\n\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t@auxclick=\"onLinkedAuxClick(item, $event)\">\n\t\t\t\t\t\t<td v-if=\"bulkEnabled\" class=\"cn-files-browser__col-select\" />\n\t\t\t\t\t\t<td class=\"cn-files-browser__col-icon\">\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tv-if=\"mimeIconFor({ mime: item.mime })\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__mime\"\n\t\t\t\t\t\t\t\t:src=\"mimeIconFor({ mime: item.mime })\"\n\t\t\t\t\t\t\t\talt=\"\">\n\t\t\t\t\t\t\t<FileOutline v-else :size=\"32\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<!-- A linked item is not a node of this folder, so it can only\n\t\t\t\t\t answer for name, size and modified. It still walks the same\n\t\t\t\t\t column list, or a declared column set would shift every\n\t\t\t\t\t linked row one cell out of line with its header. -->\n\t\t\t\t\t\t<td v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\">\n\t\t\t\t\t\t\t<template v-if=\"column.key === 'name'\">\n\t\t\t\t\t\t\t\t<span class=\"cn-files-browser__name\">{{ item.name }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"item.note\" class=\"cn-files-browser__note\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\tv-if=\"item.noteHref\"\n\t\t\t\t\t\t\t\t\t\t:href=\"item.noteHref\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__note-link\"\n\t\t\t\t\t\t\t\t\t\t@click.stop>{{ item.note }}</a>\n\t\t\t\t\t\t\t\t\t<template v-else>{{ item.note }}</template>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else-if=\"column.key === 'size'\">\n\t\t\t\t\t\t\t\t{{ item.size ? formatSize(item.size) : '' }}\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<NcDateTime v-else-if=\"column.key === 'modified' && item.mtime\" :timestamp=\"item.mtime\" :ignoreSeconds=\"true\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"cn-files-browser__col-actions\" @click.stop @auxclick.stop>\n\t\t\t\t\t\t\t<NcActions class=\"cn-files-browser__row-menu\" :forceMenu=\"true\" :ariaLabel=\"t('nextcloud-vue', 'Actions for {name}', { name: item.name })\">\n\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\tv-if=\"item.href\"\n\t\t\t\t\t\t\t\t\t:href=\"item.href\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-open\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ openLinkedLabel }}\n\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\tv-if=\"item.downloadHref\"\n\t\t\t\t\t\t\t\t\t:href=\"item.downloadHref\"\n\t\t\t\t\t\t\t\t\t:download=\"item.name\"\n\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-download\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<Download :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ downloadLabel }}\n\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t</NcActions>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<!-- `sideCards`: cards about the last selected file, beside the list,\n\t\t\t or in the detail page's side column (`sideCardsPlacement`). -->\n\t\t\t<Teleport v-if=\"sideNode !== null\"\n\t\t\t\t:to=\"pageSideTarget\"\n\t\t\t\t:disabled=\"!sideInPage\"\n\t\t\t\tdefer>\n\t\t\t\t<aside\n\t\t\t\t\tclass=\"cn-files-browser__side\"\n\t\t\t\t\t:class=\"{ 'cn-files-browser__side--in-page': sideInPage }\"\n\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'About {name}', { name: sideNode.basename })\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-side\">\n\t\t\t\t\t<section v-for=\"card in sideCardsFor(sideNode)\"\n\t\t\t\t\t\t:key=\"card.id\"\n\t\t\t\t\t\tclass=\"cn-files-browser__side-card\"\n\t\t\t\t\t\t:data-testid=\"`cn-files-browser-side-card-${card.id}`\">\n\t\t\t\t\t\t<h3 class=\"cn-files-browser__side-title\">\n\t\t\t\t\t\t\t{{ card.title }}\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<dl v-if=\"card.fields.length > 0\" class=\"cn-files-browser__side-facts\">\n\t\t\t\t\t\t\t<template v-for=\"field in card.fields\" :key=\"field.key\">\n\t\t\t\t\t\t\t\t<dt>{{ field.label }}</dt>\n\t\t\t\t\t\t\t\t<dd :class=\"field.tone ? `cn-files-browser__tone cn-files-browser__tone--${field.tone}` : ''\">\n\t\t\t\t\t\t\t\t\t<CnCellRenderer\n\t\t\t\t\t\t\t\t\t\t:value=\"field.value\"\n\t\t\t\t\t\t\t\t\t\t:formatter=\"field.formatter || null\"\n\t\t\t\t\t\t\t\t\t\t:formatterOptions=\"field.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t\t:row=\"sideNode\" />\n\t\t\t\t\t\t\t\t</dd>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</dl>\n\t\t\t\t\t\t<div v-if=\"card.actions.length > 0\" class=\"cn-files-browser__side-actions\">\n\t\t\t\t\t\t\t<NcButton v-for=\"action in card.actions\"\n\t\t\t\t\t\t\t\t:key=\"action.id\"\n\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-side-action-${action.id}`\"\n\t\t\t\t\t\t\t\t@click=\"runHostAction(action, sideNode)\">\n\t\t\t\t\t\t\t\t<template v-if=\"action.icon\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon :name=\"action.icon\" :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</section>\n\t\t\t\t</aside>\n\t\t\t</Teleport>\n\t\t</div>\n\n\t\t<p v-if=\"dropHint && canChange && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__drop-hint\"\n\t\t\tdata-testid=\"cn-files-browser-drop-hint\">\n\t\t\t<Upload :size=\"16\" />\n\t\t\t{{ dropHintLabel }}\n\t\t</p>\n\t\t<!-- The host's own line under the list (\"Elk bestand wordt bij het\n\t\t uploaden op virussen gescand\", DqDocumentenBeheer), apart from\n\t\t the drop hint. -->\n\t\t<p v-if=\"footnote && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__footnote\"\n\t\t\tdata-testid=\"cn-files-browser-footnote\">\n\t\t\t{{ cnTranslate(footnote) }}\n\t\t</p>\n\n\t\t<NcDialog\n\t\t\tv-if=\"renaming !== null\"\n\t\t\t:name=\"renameLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-rename\"\n\t\t\t@closing=\"renaming = null\">\n\t\t\t<form class=\"cn-files-browser__new-folder\" @submit.prevent=\"rename\">\n\t\t\t\t<NcTextField\n\t\t\t\t\tv-model=\"renameName\"\n\t\t\t\t\t:label=\"t('nextcloud-vue', 'New name')\"\n\t\t\t\t\t:error=\"renameError !== ''\"\n\t\t\t\t\t:helperText=\"renameError\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-rename-name\" />\n\t\t\t</form>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"renaming = null\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\t:disabled=\"renameName.trim() === '' || renameName.trim() === renaming.basename\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-rename-confirm\"\n\t\t\t\t\t@click=\"rename\">\n\t\t\t\t\t{{ renameLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\n\t\t<NcDialog\n\t\t\tv-if=\"removing !== null\"\n\t\t\t:name=\"deleteLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-delete\"\n\t\t\t@closing=\"removing = null\">\n\t\t\t<p>{{ t('nextcloud-vue', 'Delete {name}? This cannot be undone here.', { name: removing.basename }) }}</p>\n\t\t\t<p v-if=\"removeError\" class=\"cn-files-browser__upload-error\" role=\"alert\">\n\t\t\t\t{{ removeError }}\n\t\t\t</p>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"removing = null\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"error\" data-testid=\"cn-files-browser-delete-confirm\" @click=\"remove\">\n\t\t\t\t\t{{ deleteLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\n\t\t<NcDialog\n\t\t\tv-if=\"newFolderOpen\"\n\t\t\t:name=\"newFolderLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-new-folder\"\n\t\t\t@closing=\"newFolderOpen = false\">\n\t\t\t<form class=\"cn-files-browser__new-folder\" @submit.prevent=\"createFolder\">\n\t\t\t\t<NcTextField\n\t\t\t\t\tv-model=\"newFolderName\"\n\t\t\t\t\t:label=\"t('nextcloud-vue', 'Folder name')\"\n\t\t\t\t\t:error=\"newFolderError !== ''\"\n\t\t\t\t\t:helperText=\"newFolderError\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-new-folder-name\" />\n\t\t\t</form>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"newFolderOpen = false\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\t:disabled=\"newFolderName.trim() === ''\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-new-folder-create\"\n\t\t\t\t\t@click=\"createFolder\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Create') }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\n/**\n * CnFilesBrowser — a folder of Nextcloud files, on any page, built from the\n * Files app's own primitives rather than a copy of its screen.\n *\n * WHAT IS BORROWED, AND FROM WHERE.\n *\n * - The rows are `@nextcloud/files` nodes read over WebDAV with the same\n * PROPFIND the Files app sends, so a node here carries what a node there\n * carries: id, mime, size, mtime, permissions, attributes.\n * - Each row's menu is `getFileActions()`: the actions the Files app and its\n * plugins registered on this page (download, delete, rename, favourite, move\n * and copy, sharing status, tags, lock, open in Files…). They are run with\n * the same context the Files app hands them, so a plugin's action does what\n * it does in the Files app. The host page has to load those scripts: it\n * dispatches `LoadAdditionalScriptsEvent` and asks for the Files app's `init`\n * script server-side. On a page that did not, the menu holds only Show in\n * Files, which is the honest fallback.\n * - The New menu is `getNewFileMenuEntries(folder)`: new folder, a template,\n * a file request, whatever the plugins offer for this folder, beside a plain\n * upload that PUTs over DAV.\n * - The crumbs are NcBreadcrumbs, the icons are the theme's own mime icons\n * through `OC.MimeType`, and image previews come from the core preview\n * endpoint.\n *\n * WHAT IS NOT. The Files app's list itself (its column filters, selection bar\n * and inline rename) is a Vue app bound to the Files router and its own stores,\n * and so is its details sidebar on Nextcloud 34. Neither can be mounted here.\n * The actions that need them are left out of the menu by name\n * (`ACTIONS_NEEDING_THE_FILES_PAGE`), and Show in Files opens the Files app on\n * the file for the rest.\n *\n * THE REGISTRY IS VERSIONED. `@nextcloud/files` keeps its registries under\n * `window._nc_files_scope.v4_0`; a page's plugins register into the copy the\n * server ships, and this component reads through its own bundled copy. Both\n * have to be the same major, which is why this library depends on 4.x: a 3.x\n * copy read `window._nc_fileactions`, which the server's plugins never write,\n * and saw nothing while the page held thirty actions.\n */\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { FileType, formatFileSize, getFileActions, getNewFileMenuEntries, sortNodes, View } from '@nextcloud/files'\nimport { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcActionButton, NcActionCheckbox, NcActionLink, NcActions, NcActionSeparator, NcBreadcrumb, NcBreadcrumbs, NcButton, NcDateTime, NcDialog, NcIconSvgWrapper, NcLoadingIcon, NcProgressBar, NcTextField } from '@nextcloud/vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Download from 'vue-material-design-icons/Download.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport FolderOutline from 'vue-material-design-icons/FolderOutline.vue'\nimport FolderPlusOutline from 'vue-material-design-icons/FolderPlusOutline.vue'\nimport OpenInNew from 'vue-material-design-icons/OpenInNew.vue'\nimport Pencil from 'vue-material-design-icons/Pencil.vue'\nimport Plus from 'vue-material-design-icons/Plus.vue'\nimport TrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue'\nimport Upload from 'vue-material-design-icons/Upload.vue'\nimport CnCellRenderer from '../CnCellRenderer/CnCellRenderer.vue'\nimport CnEmptyContent from '../CnEmptyContent/CnEmptyContent.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\nimport { readUserPreference, writeUserPreference } from '../../composables/useUserPreferences.js'\nimport { dispatchAction } from '../../utils/actionsDispatcher.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { isNewTabClick, isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'\nimport { ACTIONS_NEEDING_THE_FILES_PAGE, crumbsFor, hostActionApplies, joinPath } from './filesBrowser.js'\nimport {\n\tattributePropertiesFor,\n\tfacetCounts,\n\tfileColumnValue,\n\tgroupNodes,\n\tnodeMatchesFacets,\n\tnormaliseFileColumns,\n\tsortNodesByColumn,\n\tvisibleFileColumns,\n} from './filesBrowserColumns.js'\nimport { reviewSummary } from './filesReview.js'\n\nlet uploadSeq = 0\n\n/** A folder glyph, the icon the Files app's View constructor requires. */\nconst VIEW_ICON = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\"/></svg>'\n\n// Event-bus channels that mean the open folder may have changed: the page's\n// Refresh signal, and the node events the Files app's actions and uploader emit.\nconst FOLDER_CHANGED_CHANNELS = ['cn:page:refresh', 'files:node:created', 'files:node:deleted', 'files:node:updated', 'files:node:moved']\n\nconst FOLDER_CHANGED_DEBOUNCE_MS = 300\n\nexport default {\n\tname: 'CnFilesBrowser',\n\n\tcomponents: {\n\t\tAlertCircleOutline,\n\t\tCnCellRenderer,\n\t\tCnIcon,\n\t\tDownload,\n\t\tFileOutline,\n\t\tFolderOutline,\n\t\tFolderPlusOutline,\n\t\tNcActionButton,\n\t\tNcActionCheckbox,\n\t\tNcActionLink,\n\t\tNcActionSeparator,\n\t\tNcActions,\n\t\tNcBreadcrumb,\n\t\tNcBreadcrumbs,\n\t\tNcButton,\n\t\tNcDateTime,\n\t\tNcDialog,\n\t\tCnEmptyContent,\n\t\tNcIconSvgWrapper,\n\t\tNcLoadingIcon,\n\t\tNcProgressBar,\n\t\tNcTextField,\n\t\tOpenInNew,\n\t\tPencil,\n\t\tPlus,\n\t\tTrashCanOutline,\n\t\tUpload,\n\t},\n\n\tinject: {\n\t\t// The page's pre-bound action runner (CnPageRenderer provides it);\n\t\t// absent outside a page tree, in which case the bare dispatcher runs.\n\t\tcnDispatchAction: { default: null },\n\t\t// The host app's translate function (CnAppRoot provides it). A row\n\t\t// action or column the manifest declares is authored in English as\n\t\t// the catalogue key, and read through this in the user's language.\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t// The detail page's side column (CnDetailPage), for side cards placed there.\n\t\tcnDetailSideColumn: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Where the folder is read from and written to. Null (the default)\n\t\t * is WebDAV under the signed-in person's files root, with the Files\n\t\t * app's own actions and New menu. An object from\n\t\t * `createOpenRegisterSource()` reads one OpenRegister object's folder\n\t\t * through OpenRegister's files API instead, under the object's access\n\t\t * rule: `rootPath` is then `/`, the Files app's actions and New menu\n\t\t * are not offered (they act over WebDAV), and upload, new folder,\n\t\t * rename and delete appear only when the listing says the person may\n\t\t * change the folder.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tsource: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label of the delete action and its dialog, with a `source`. */\n\t\tdeleteLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Delete'),\n\t\t},\n\n\t\t/**\n\t\t * The host's own actions on each file row, declared the way a\n\t\t * manifest declares any action (`open-modal`, `handler`, ...), and\n\t\t * dispatched through the page's action runner with the node's\n\t\t * `fileId`, `fileName` and `path` merged into an `open-modal` action's\n\t\t * props (or appended as the node to a `handler` action's args). Folders\n\t\t * get none. `icon` is an MDI icon name. `visibleIf` offers the action\n\t\t * only on some files: `extension` (a list, no case) and `mime` (a list;\n\t\t * `image/` or `image/*` names the family), each that is named must hold.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array, visibleIf?: {extension?: string[], mime?: string[]}}>}\n\t\t */\n\t\trowActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own entries in the New menu, after the ones the Files\n\t\t * app and its plugins register. Each is dispatched like a row action\n\t\t * (`type: 'open-modal' | 'handler' | …`) through the page's\n\t\t * `cnDispatchAction`, carrying the current folder rather than a row,\n\t\t * so a host can offer \"new from template\" or \"request a file from a\n\t\t * party\" here.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\tnewActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own buttons in the bar, before the upload button (\"Vraag\n\t\t * een bestand aan een partij\", DqZaakDocumenten). Each is dispatched\n\t\t * like a New-menu entry, with the current folder; `variant:\n\t\t * 'primary'` draws it as the primary button.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, variant?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\theaderActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * One visible button on every file row (\"Beoordelen\"), dispatched like a\n\t\t * row action. `primaryWhen: { key, values }` draws it as the primary\n\t\t * button while the row-data field `key` holds one of `values` (a file\n\t\t * still to review), and secondary otherwise. `visibleIf` works as on a\n\t\t * row action.\n\t\t *\n\t\t * @type {{id: string, label: string, type?: string, target?: string, props?: object, handler?: string, args?: Array, primaryWhen?: {key: string, values: Array<string>}, visibleIf?: object}|null}\n\t\t */\n\t\trowButton: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * A review summary above the list (DqZaakDocumenten \"4 van 7\n\t\t * beoordeeld\"): `{ key, open, values: [{ value, label?, tone? }], title?,\n\t\t * subtitle? }`. `key` is the row-data field with the review state, `open`\n\t\t * the value (or values) of a file still to review; a file without a\n\t\t * listed value counts as open. `tone` is `success`, `warning`, `error`,\n\t\t * `info` or `default`. `title` and `subtitle` take `{done}`, `{total}` and\n\t\t * `{open}`, through the host's translate; they default to the library's\n\t\t * \"{done} of {total} reviewed\" and \"{open} still to review\".\n\t\t *\n\t\t * @type {{key: string, open?: string|Array<string>, values: Array<{value: string, label?: string, tone?: string}>, title?: string, subtitle?: string}|null}\n\t\t */\n\t\treviewSummary: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Rows that are not nodes of this folder: files the host joined from\n\t\t * another object's folder. Rendered after the folder's own rows with\n\t\t * open and download only. `note` (and its optional `noteHref`) says\n\t\t * where the file lives.\n\t\t *\n\t\t * @type {Array<{id: string|number, name: string, mime?: string, size?: number, mtime?: Date|number, href?: string, downloadHref?: string, note?: string, noteHref?: string}>}\n\t\t */\n\t\tlinkedItems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Label of a linked row's open action.\n\t\t */\n\t\topenLinkedLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Open'),\n\t\t},\n\n\t\t/**\n\t\t * Label of a linked row's download action.\n\t\t */\n\t\tdownloadLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Download'),\n\t\t},\n\n\t\t/**\n\t\t * The folder this browser is rooted at, relative to the current user's\n\t\t * files root (`/Open Registers/Cases/<uuid>`). The browser never\n\t\t * navigates above it. Resolve it with `resolveObjectFolder()` for an\n\t\t * OpenRegister object.\n\t\t */\n\t\trootPath: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * What the root crumb reads. Null shows the folder's own name, which\n\t\t * is what the Files app shows; pass a label when the folder on disk is\n\t\t * a uuid and the host knows a better name.\n\t\t */\n\t\trootLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label of the New menu. */\n\t\tnewLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'New'),\n\t\t},\n\n\t\t/** Label of the upload entry in the New menu. */\n\t\tuploadLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Upload files'),\n\t\t},\n\n\t\t/** Label of the new-folder entry and its dialog. */\n\t\tnewFolderLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'New folder'),\n\t\t},\n\n\t\t/** Label of the rename action and its dialog. */\n\t\trenameLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Rename'),\n\t\t},\n\n\t\t/** Label of the link that opens the file in the Files app. */\n\t\tshowInFilesLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Show in Files'),\n\t\t},\n\n\t\t/**\n\t\t * Show a primary upload button beside the New menu, which then steps\n\t\t * back to a secondary button. Off (the default) keeps the upload\n\t\t * inside the New menu only.\n\t\t */\n\t\tuploadButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Whether the bar has the New menu (upload, new folder, the Files\n\t\t * app's entries and `newActions`). `false` leaves it out, so the bar\n\t\t * holds the host's `headerActions` buttons and, with `uploadButton`,\n\t\t * the upload button (DqZaakDocumenten).\n\t\t *\n\t\t * @spec openspec/changes/files-browser-toolbar-actions/specs/files-browser/spec.md#requirement-the-host-chooses-whether-the-bar-has-a-new-menu\n\t\t */\n\t\tnewMenu: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Show New folder as a button in the bar, before the host's buttons.\n\t\t * With `newMenu: false` it keeps folder creation in reach.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-toolbar-actions/specs/files-browser/spec.md#requirement-the-host-can-put-new-folder-in-the-bar-as-a-button\n\t\t */\n\t\tfolderButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Label of the upload button `uploadButton` shows. */\n\t\tuploadButtonLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Add files'),\n\t\t},\n\n\t\t/**\n\t\t * Draw the drop state over the browser while files are dragged onto\n\t\t * it (a dashed frame and `dropLabel`, centred) and announce it to\n\t\t * screen readers. Off (the default) keeps the plain dashed outline and\n\t\t * announces nothing.\n\t\t */\n\t\tdropOverlay: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The line `dropOverlay` draws and announces, through the host translate. */\n\t\tdropLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Drop to add'),\n\t\t},\n\n\t\t/**\n\t\t * A second line under `dropLabel` in the drop state, through the host\n\t\t * translate: where the files go (\"{count} bestanden komen bij zaak\n\t\t * 2026-0082, als nog te beoordelen document.\"). `{count}` is the number\n\t\t * of files dragged when the browser can tell, and the line is left out\n\t\t * when it cannot. The overlay then also fills the panel.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-panel/specs/files-browser/spec.md#requirement-the-drop-state-fills-the-panel-and-says-where-the-files-go\n\t\t */\n\t\tdropDetail: {\n\t\t\ttype: [String, Array],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Named values filled into `dropDetail` as `{name}`, such as the case\n\t\t * number (`{ \"case\": \"@object.identifier\" }` in a detail page's props).\n\t\t * While a value is unknown the line is left out.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t */\n\t\tdropDetailValues: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Show a line under the list saying files can be dropped on it. */\n\t\tdropHint: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * A line of the host's own under the list, apart from the drop hint\n\t\t * (\"Elk bestand wordt bij het uploaden op virussen gescand en krijgt een\n\t\t * controlegetal\", DqDocumentenBeheer). Translated with the host's\n\t\t * catalogue.\n\t\t */\n\t\tfootnote: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A second line under each file's name (DqDocumentenBeheer \"Inwoner ·\n\t\t * 4 okt\", DqZaakDocumenten \"PDF · 1,2 MB · 14 januari 2026\"): a field\n\t\t * template read from the file's row data, plus `name`, `modified` (the\n\t\t * change date), `owner` (the owner's display name), `size` (formatted)\n\t\t * and `type` (\"PDF\", \"Word\", \"Email\", else the extension), e.g.\n\t\t * `\"{type} · {size} · {modified|date}\"`. A line with an empty\n\t\t * value is left out. Translated with the host's catalogue first.\n\t\t */\n\t\tnameSecondary: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The second line as a list of fields joined with \" · \", a field\n\t\t * without a value left out: the `nameSecondary` tokens without their\n\t\t * braces (`[\"type\", \"size\", \"modified|date\"]`, a row-data field such as\n\t\t * `\"senderName\"`). Or a list of variants `{ when, fields }`: the first\n\t\t * whose `when` is `true`, or that has no `when`, is used (a case type\n\t\t * flag read through `@context`). Takes precedence over `nameSecondary`.\n\t\t *\n\t\t * @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields\n\t\t */\n\t\tsecondLine: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The line `dropHint` shows. */\n\t\tdropHintLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Or drag files onto this list.'),\n\t\t},\n\n\t\t/** Title of the empty state. */\n\t\temptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'This folder is empty'),\n\t\t},\n\n\t\t/** Line under the empty state's title. */\n\t\temptyHint: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Drop files here, or use New'),\n\t\t},\n\n\t\t/** Label of the retry button on a failed listing. */\n\t\tretryLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Try again'),\n\t\t},\n\n\t\t/**\n\t\t * The columns this browser shows, in order. An entry is a built-in name\n\t\t * (`name`, `size`, `modified`, `owner`, `type`, `tags`) or an object\n\t\t * declaring its own: `{ key, label, source, attribute, formatter,\n\t\t * sortable }`, where `source` is `node` (a property of the node),\n\t\t * `attribute` (a DAV property, added to the PROPFIND before listing) or\n\t\t * `row` (a value from `rowData`).\n\t\t *\n\t\t * Declaring none keeps today's table: name, size and modified.\n\t\t *\n\t\t * This is the membership list. The Columns chooser lets a user hide any\n\t\t * of these; it never adds one, and a column removed from here is gone\n\t\t * for every user, whatever they had stored.\n\t\t *\n\t\t * @type {Array<string|object>}\n\t\t */\n\t\tcolumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own per-file data for `source: 'row'` columns, keyed by\n\t\t * file id. Either an object, or a function of the listed nodes called\n\t\t * once per folder so the host can fetch its projection in one request.\n\t\t *\n\t\t * @type {object | ((nodes: Array<object>) => (object|Promise<object>))}\n\t\t */\n\t\trowData: {\n\t\t\ttype: [Object, Function],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The app id the Columns chooser stores this user's choice under. Unset\n\t\t * means the chooser is not offered and every declared column renders.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tpreferenceApp: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The key this browser's column choice is stored under, so two browsers\n\t\t * in one app remember separately.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tpreferenceKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'files-browser-columns',\n\t\t},\n\n\t\t/**\n\t\t * The host's actions on a selection of files, declared like\n\t\t * `rowActions`. With at least one, every file row (never a folder or a\n\t\t * linked row) gets a checkbox, the header a select-all, and a bar with\n\t\t * these actions shows while files are selected. An `open-modal`\n\t\t * action's props gain `files` (each `{ fileId, fileName, path }`) and\n\t\t * `fileIds`; a `handler` action's args gain the selected nodes. The\n\t\t * selection clears after an action and when another folder opens.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\tbulkActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The bulk bar's count, as a translatable template with `{count}`\n\t\t * (\"{count} documents selected\"); `selectionLabelOne` is used for one.\n\t\t * Empty reads \"{count} selected\".\n\t\t *\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-the-bulk-bar-names-what-is-selected\n\t\t */\n\t\tselectionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The bulk bar's count for one selected file, e.g. \"{count} document selected\". */\n\t\tselectionLabelOne: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the bulk bar ends in a \"Clear selection\" button. */\n\t\tshowClearSelection: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Cards beside the list about the last selected file:\n\t\t * `[{ id, title, fields: [{ key, label, source?, formatter?, formatterOptions?, colorMap?, colorKey? }], actions? }]`.\n\t\t * `title` may hold `{name}`, the file's name. A field reads `rowData`\n\t\t * (`source: 'row'`, the default) or the node (`source: 'node'`); a field\n\t\t * with no value is left out. `actions` are declared like `rowActions`\n\t\t * and run on that file. No side column while nothing is selected.\n\t\t *\n\t\t * @type {Array<{id: string, title: string, fields?: Array<object>, actions?: Array<object>}>}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\tsideCards: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Where the side cards stand: `beside` (default) next to the list, or\n\t\t * `page-side` in the detail page's side column, in place of its\n\t\t * generic cards while a file is selected. Without a page side column\n\t\t * they stay beside the list.\n\t\t */\n\t\tsideCardsPlacement: {\n\t\t\ttype: String,\n\t\t\tdefault: 'beside',\n\t\t},\n\n\t\t/**\n\t\t * The key of a declared column to group the files on: a heading row\n\t\t * per value, in the order each is first met, with its count. Files\n\t\t * with no value come last under `groupEmptyLabel`; folders stay above.\n\t\t * Empty (the default) does not group.\n\t\t */\n\t\tgroupBy: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The heading of the group of files with no value in the `groupBy` column. */\n\t\tgroupEmptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Other'),\n\t\t},\n\n\t\t/**\n\t\t * Keys of declared columns to filter on. Each gets a chip per value in\n\t\t * use among the folder's files (a list counts per entry) with how many\n\t\t * files carry it; chosen chips keep the files with any chosen value of\n\t\t * that column, across every column with a choice.\n\t\t *\n\t\t * @type {string[]}\n\t\t */\n\t\tfacets: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the toolbar's Columns chooser. */\n\t\tcolumnsLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Columns'),\n\t\t},\n\t},\n\n\temits: ['changed'],\n\n\tdata() {\n\t\treturn {\n\t\t\tcurrentPath: this.rootPath,\n\t\t\t/** The open folder as a node, or null before the first listing. */\n\t\t\tfolder: null,\n\t\t\t/** The open folder's children as nodes. */\n\t\t\tnodes: [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t\tsortKey: 'basename',\n\t\t\tsortAsc: true,\n\t\t\t/** The host's per-file data for `row` columns, by file id. */\n\t\t\tresolvedRowData: null,\n\t\t\t/** File ids (as strings) of the selected files. */\n\t\t\tselectedIds: [],\n\t\t\t/** Chosen facet values by column key. */\n\t\t\tfacetSelections: {},\n\t\t\t/**\n\t\t\t * The column keys this user chose to see, or null while they have\n\t\t\t * chosen nothing. Never a source of membership: it is intersected\n\t\t\t * with the host's declaration, never added to it.\n\t\t\t */\n\t\t\tvisibleColumnKeys: null,\n\t\t\tdragging: false,\n\t\t\t/** The number of files the current drag carries, null when unknown. */\n\t\t\tdragCount: null,\n\t\t\t/** Nested dragenter/dragleave pairs, so a child does not end the drag. */\n\t\t\tdragDepth: 0,\n\t\t\t/** What the live region says: the drop label, then what was added. */\n\t\t\tdropStatus: '',\n\t\t\tuploads: [],\n\t\t\tpreviewFailed: {},\n\t\t\tnewFolderOpen: false,\n\t\t\tnewFolderName: '',\n\t\t\tnewFolderError: '',\n\t\t\t/** The node being renamed, or null. */\n\t\t\trenaming: null,\n\t\t\trenameName: '',\n\t\t\trenameError: '',\n\t\t\t/** The row being deleted (with a `source`), or null. */\n\t\t\tremoving: null,\n\t\t\tremoveError: '',\n\t\t\tfileInputEl: null,\n\t\t\t/**\n\t\t\t * The view the Files app's actions are handed. They read `view.id`\n\t\t\t * to tell a trash bin or a share view from a plain folder; this is\n\t\t\t * a plain folder.\n\t\t\t */\n\t\t\tview: new View({\n\t\t\t\tid: 'files',\n\t\t\t\tname: t('nextcloud-vue', 'Files'),\n\t\t\t\t// The View constructor refuses anything but an SVG string here,\n\t\t\t\t// and throws from data(), which takes the whole tab down.\n\t\t\t\ticon: VIEW_ICON,\n\t\t\t\torder: 0,\n\t\t\t\tgetContents: async () => ({ folder: this.folder, contents: this.nodes }),\n\t\t\t}),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The `dropDetail` text: the string, or the text of the first variant\n\t\t * `{ when, text }` whose `when` is `true` or that has none.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t */\n\t\tdropDetailTemplate() {\n\t\t\tif (typeof this.dropDetail === 'string') {\n\t\t\t\treturn this.dropDetail\n\t\t\t}\n\t\t\tconst variants = Array.isArray(this.dropDetail) ? this.dropDetail : []\n\t\t\tconst chosen = variants.find((item) => item && typeof item.text === 'string' && (!('when' in item) || item.when === true))\n\t\t\treturn chosen ? chosen.text : ''\n\t\t},\n\n\t\t/**\n\t\t * `dropDetail` through the host translate with `{count}` filled, '' when\n\t\t * there is none or the count it needs is unknown.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-panel/specs/files-browser/spec.md#requirement-the-drop-state-fills-the-panel-and-says-where-the-files-go\n\t\t * @return {string}\n\t\t */\n\t\tdropDetailText() {\n\t\t\tconst template = this.dropDetailTemplate\n\t\t\tif (!template) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tlet text = this.cnTranslate(template)\n\t\t\t// `dropDetailValues`: named values such as the case number; a value\n\t\t\t// still unknown (an unresolved `@` token, or empty) leaves the line out.\n\t\t\t// @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t\tconst values = this.dropDetailValues && typeof this.dropDetailValues === 'object' ? this.dropDetailValues : {}\n\t\t\tfor (const [name, value] of Object.entries(values)) {\n\t\t\t\tconst shown = value === null || value === undefined ? '' : String(value)\n\t\t\t\tif (shown === '' || shown.startsWith('@')) {\n\t\t\t\t\treturn ''\n\t\t\t\t}\n\t\t\t\ttext = text.split(`{${name}}`).join(shown)\n\t\t\t}\n\t\t\tif (!text.includes('{count}')) {\n\t\t\t\treturn text\n\t\t\t}\n\t\t\treturn this.dragCount === null ? '' : text.replace(/\\{count\\}/g, String(this.dragCount))\n\t\t},\n\n\t\t/**\n\t\t * Whether this person may add to and change the open folder. Over\n\t\t * WebDAV the server answers each write on its own, so this is true;\n\t\t * with a `source` it is what the listing said.\n\t\t *\n\t\t * @return {boolean} True when upload, new folder, rename and delete are offered.\n\t\t */\n\t\tcanChange() {\n\t\t\tif (!this.source) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.folder !== null && this.folder.canChange === true\n\t\t},\n\n\t\t/**\n\t\t * The breadcrumb trail from the root to the open folder.\n\t\t *\n\t\t * @return {Array<{name: string, path: string}>} The crumbs.\n\t\t */\n\t\tcrumbs() {\n\t\t\treturn crumbsFor(this.rootPath, this.currentPath, this.rootLabel)\n\t\t},\n\n\t\t/**\n\t\t * Whether the open folder is the browser's root: the trail then ends on\n\t\t * the root itself (the board look draws no trail there).\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/board-files-root-crumb/specs/board-files-root-crumb/spec.md#requirement-the-board-files-bar-draws-no-trail-at-the-root\n\t\t */\n\t\tatRoot() {\n\t\t\tconst root = String(this.rootPath || '/').replace(/\\/+$/, '') || '/'\n\t\t\tconst last = this.crumbs[this.crumbs.length - 1]\n\t\t\treturn Boolean(last) && last.path === root\n\t\t},\n\n\t\t/**\n\t\t * The children in the chosen order, folders first the way the Files app\n\t\t * lists them.\n\t\t *\n\t\t * @return {Array<object>} The nodes.\n\t\t */\n\t\tsorted() {\n\t\t\tconst column = this.activeSortColumn\n\t\t\tif (column && !column.sortKey) {\n\t\t\t\t// A declared column has no meaning to the Files app's sorter, so\n\t\t\t\t// it sorts here, within the folder that is listed.\n\t\t\t\treturn sortNodesByColumn(this.nodes, column, this.sortAsc, this.resolvedRowData, (node) => this.isFolder(node))\n\t\t\t}\n\t\t\treturn sortNodes(this.nodes, {\n\t\t\t\tsortingMode: this.sortKey,\n\t\t\t\tsortingOrder: this.sortAsc ? 'asc' : 'desc',\n\t\t\t\tsortFoldersFirst: true,\n\t\t\t\tsortFavoritesFirst: false,\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The columns the host declared, resolved. This is the membership list:\n\t\t * a column exists because the host declared it, in the host's order.\n\t\t *\n\t\t * @return {Array<object>} The declared columns.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\tdeclaredColumns() {\n\t\t\treturn normaliseFileColumns(this.columns)\n\t\t},\n\n\t\t/**\n\t\t * The library's own word for each built-in column, used when the host\n\t\t * did not write a label.\n\t\t *\n\t\t * @return {object} Labels by column key.\n\t\t */\n\t\tbuiltInColumnLabels() {\n\t\t\treturn {\n\t\t\t\tname: t('nextcloud-vue', 'Name'),\n\t\t\t\tsize: t('nextcloud-vue', 'Size'),\n\t\t\t\tmodified: t('nextcloud-vue', 'Modified'),\n\t\t\t\towner: t('nextcloud-vue', 'Owner'),\n\t\t\t\ttype: t('nextcloud-vue', 'Type'),\n\t\t\t\ttags: t('nextcloud-vue', 'Tags'),\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The columns this browser renders: the host's declaration narrowed by\n\t\t * what this user chose to see.\n\t\t *\n\t\t * The user's stored choice only ever takes columns away. It is applied\n\t\t * by walking the declaration, so a key the host no longer declares is\n\t\t * passed over rather than rendered, and a preference written when a\n\t\t * different set was declared cannot bring an old column back.\n\t\t *\n\t\t * @return {Array<object>} The columns to render.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\trenderedColumns() {\n\t\t\treturn visibleFileColumns(this.declaredColumns, this.visibleColumnKeys)\n\t\t},\n\n\t\t/**\n\t\t * The declared columns by key, for grouping and facets.\n\t\t *\n\t\t * @return {object} Resolved columns by key.\n\t\t */\n\t\tcolumnsByKey() {\n\t\t\tconst byKey = {}\n\t\t\tthis.declaredColumns.forEach((column) => {\n\t\t\t\tbyKey[column.key] = column\n\t\t\t})\n\t\t\treturn byKey\n\t\t},\n\n\t\t/**\n\t\t * How many cells a row has, for a heading or message spanning the row.\n\t\t *\n\t\t * @return {number} The column count.\n\t\t */\n\t\tcolumnCount() {\n\t\t\treturn this.renderedColumns.length + 2 + (this.bulkEnabled ? 1 : 0)\n\t\t},\n\n\t\t/**\n\t\t * Whether the host gave bulk actions, which turns on the selection.\n\t\t *\n\t\t * @return {boolean} True with at least one bulk action.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tbulkEnabled() {\n\t\t\treturn Array.isArray(this.bulkActions) && this.bulkActions.length > 0\n\t\t},\n\n\t\t/**\n\t\t * The listed folders, in display order.\n\t\t *\n\t\t * @return {Array<object>} The folder nodes.\n\t\t */\n\t\tfolderNodes() {\n\t\t\treturn this.sorted.filter((node) => this.isFolder(node))\n\t\t},\n\n\t\t/**\n\t\t * The listed files, in display order, before the filter.\n\t\t *\n\t\t * @return {Array<object>} The file nodes.\n\t\t */\n\t\t/**\n\t\t * The fields `secondLine` names for this browser: the list itself, or\n\t\t * the fields of its first variant whose `when` is `true` or absent.\n\t\t * Null without `secondLine` or a matching variant.\n\t\t *\n\t\t * @return {Array<string>|null}\n\t\t * @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields\n\t\t */\n\t\tsecondLineFields() {\n\t\t\tconst list = Array.isArray(this.secondLine) ? this.secondLine : []\n\t\t\tif (list.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (list.every((item) => typeof item === 'string')) {\n\t\t\t\treturn list\n\t\t\t}\n\t\t\tconst variant = list.find((item) => item && typeof item === 'object' && Array.isArray(item.fields) && (!('when' in item) || item.when === true))\n\t\t\treturn variant ? variant.fields.filter((field) => typeof field === 'string') : null\n\t\t},\n\n\t\t/**\n\t\t * The bulk bar's count text.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-the-bulk-bar-names-what-is-selected\n\t\t */\n\t\tselectionCountText() {\n\t\t\tconst count = this.selectedIds.length\n\t\t\tconst template = count === 1 && this.selectionLabelOne ? this.selectionLabelOne : this.selectionLabel\n\t\t\tif (template) {\n\t\t\t\treturn this.cnTranslate(template).replace(/\\{count\\}/g, String(count))\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', '{count} selected', { count })\n\t\t},\n\n\t\t/**\n\t\t * The file the side cards describe: the last one selected, or null\n\t\t * without side cards or a selection.\n\t\t *\n\t\t * @return {object|null}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\t/** @return {boolean} Whether the side cards fill the page's side column now. */\n\t\tsideClaimed() {\n\t\t\treturn this.sideInPage && this.sideNode !== null\n\t\t},\n\n\t\t/** @return {boolean} Whether the side cards stand in the page's side column. */\n\t\tsideInPage() {\n\t\t\treturn this.sideCardsPlacement === 'page-side' && this.cnDetailSideColumn !== null && this.cnDetailSideColumn.available === true\n\t\t},\n\n\t\t/** @return {string} Where the side cards are teleported to in the page. */\n\t\tpageSideTarget() {\n\t\t\treturn this.cnDetailSideColumn?.target || 'body'\n\t\t},\n\n\t\tsideNode() {\n\t\t\tif (!Array.isArray(this.sideCards) || this.sideCards.length === 0 || this.selectedIds.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst id = this.selectedIds[this.selectedIds.length - 1]\n\t\t\treturn this.fileNodes.find((node) => String(node.fileid) === id) || null\n\t\t},\n\n\t\tfileNodes() {\n\t\t\treturn this.sorted.filter((node) => !this.isFolder(node))\n\t\t},\n\n\t\t/**\n\t\t * The review counts over the folder's files, or null without a summary.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\treview() {\n\t\t\treturn reviewSummary(this.reviewSummary, this.fileNodes, this.resolvedRowData)\n\t\t},\n\n\t\t/** @return {string} The summary's title, counts filled in. */\n\t\treviewTitle() {\n\t\t\treturn this.reviewText('title', t('nextcloud-vue', '{done} of {total} reviewed'))\n\t\t},\n\n\t\t/** @return {string} The summary's second line, or '' when nothing is open. */\n\t\treviewSubtitle() {\n\t\t\tif (!this.review || this.review.open === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.reviewText('subtitle', t('nextcloud-vue', '{open} still to review'))\n\t\t},\n\n\t\t/**\n\t\t * Whether any facet value is chosen.\n\t\t *\n\t\t * @return {boolean} True when the filter narrows the list.\n\t\t */\n\t\tfacetActive() {\n\t\t\treturn Object.values(this.facetSelections).some((values) => Array.isArray(values) && values.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The chips: per facet column, the values in use with their counts.\n\t\t *\n\t\t * @return {Array<{key: string, label: string, values: Array<{value: string, count: number, active: boolean}>}>} The facets.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tfacetGroups() {\n\t\t\tconst keys = Array.isArray(this.facets) ? this.facets : []\n\t\t\treturn keys\n\t\t\t\t.map((key) => this.columnsByKey[key])\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.map((column) => {\n\t\t\t\t\tconst chosen = this.facetSelections[column.key] || []\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkey: column.key,\n\t\t\t\t\t\tlabel: this.columnLabel(column),\n\t\t\t\t\t\tvalues: facetCounts(this.fileNodes, column, this.resolvedRowData)\n\t\t\t\t\t\t\t.map((entry) => ({ ...entry, active: chosen.includes(entry.value) })),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.filter((facet) => facet.values.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The files the filter keeps.\n\t\t *\n\t\t * @return {Array<object>} The file nodes.\n\t\t */\n\t\tfilteredFiles() {\n\t\t\tif (!this.facetActive) {\n\t\t\t\treturn this.fileNodes\n\t\t\t}\n\t\t\treturn this.fileNodes.filter((node) => nodeMatchesFacets(node, this.facetSelections, this.columnsByKey, this.resolvedRowData))\n\t\t},\n\n\t\t/**\n\t\t * What the table body renders, in order: folders, then the files,\n\t\t * under a heading per group when the host groups.\n\t\t *\n\t\t * @return {Array<{key: string, group?: object, node?: object}>} The rows.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tdisplayRows() {\n\t\t\tconst rows = this.folderNodes.map((node) => ({ key: node.source, node }))\n\t\t\tconst column = this.groupBy ? this.columnsByKey[this.groupBy] : null\n\t\t\tif (!column) {\n\t\t\t\tthis.filteredFiles.forEach((node) => rows.push({ key: node.source, node }))\n\t\t\t\treturn rows\n\t\t\t}\n\t\t\tgroupNodes(this.filteredFiles, column, this.resolvedRowData).forEach((group) => {\n\t\t\t\tconst label = group.value === null ? this.groupEmptyLabel : group.value\n\t\t\t\trows.push({ key: `group-${group.value === null ? '' : group.value}`, group: { label, count: group.nodes.length } })\n\t\t\t\tgroup.nodes.forEach((node) => rows.push({ key: node.source, node }))\n\t\t\t})\n\t\t\treturn rows\n\t\t},\n\n\t\t/**\n\t\t * The ids of the files a select-all takes: the files the filter keeps.\n\t\t *\n\t\t * @return {string[]} File ids as strings.\n\t\t */\n\t\tselectableIds() {\n\t\t\treturn this.filteredFiles.map((node) => String(node.fileid))\n\t\t},\n\n\t\t/**\n\t\t * Whether every selectable file is selected.\n\t\t *\n\t\t * @return {boolean} True when all are.\n\t\t */\n\t\tallSelected() {\n\t\t\treturn this.selectableIds.length > 0 && this.selectableIds.every((id) => this.selectedIds.includes(id))\n\t\t},\n\n\t\t/**\n\t\t * Whether some file is selected.\n\t\t *\n\t\t * @return {boolean} True when one or more are.\n\t\t */\n\t\tsomeSelected() {\n\t\t\treturn this.selectedIds.length > 0\n\t\t},\n\n\t\t/**\n\t\t * The column the table is currently sorted on, or null when the sort\n\t\t * key belongs to no declared column.\n\t\t *\n\t\t * @return {(object|null)} The active column.\n\t\t */\n\t\tactiveSortColumn() {\n\t\t\treturn this.declaredColumns.find((column) => this.sortTokenOf(column) === this.sortKey) || null\n\t\t},\n\n\t\t/**\n\t\t * Whether the Columns chooser is offered: only when the host said where\n\t\t * to store the answer, because a chooser that forgets is worse than no\n\t\t * chooser.\n\t\t *\n\t\t * @return {boolean} True when the chooser renders.\n\t\t */\n\t\tcolumnsChooserEnabled() {\n\t\t\treturn this.preferenceApp !== '' && this.declaredColumns.length > 0\n\t\t},\n\n\t\t/**\n\t\t * What the Files app and its plugins offer to create in this folder.\n\t\t *\n\t\t * Read at render, not cached: a plugin's script may register its entry\n\t\t * after this component mounted.\n\t\t *\n\t\t * @return {Array<object>} The entries, in the plugins' order.\n\t\t */\n\t\tnewMenuEntries() {\n\t\t\tif (this.folder === null || this.source) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn getNewFileMenuEntries(this.folder)\n\t\t\t\t\t.filter((entry) => typeof entry.handler === 'function')\n\t\t\t\t\t.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Tell the page whether the side cards stand in its side column now,\n\t\t * so its generic cards stand aside meanwhile.\n\t\t */\n\t\tsideClaimed: {\n\t\t\timmediate: true,\n\t\t\thandler(on) {\n\t\t\t\tthis.cnDetailSideColumn?.claim?.(this.$.uid, on)\n\t\t\t},\n\t\t},\n\n\t\trootPath(next) {\n\t\t\tthis.currentPath = next\n\t\t\tthis.refresh()\n\t\t},\n\n\t\t// A selection belongs to the folder it was made in.\n\t\tcurrentPath() {\n\t\t\tthis.selectedIds = []\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.loadColumnChoice()\n\t\tthis.refresh()\n\t\t// Another surface on the page changed the folder: the page's Refresh,\n\t\t// a dialog that filed a document, or a Files action whose work ends\n\t\t// after its own call returned (the delete confirmation, an upload).\n\t\tfor (const channel of FOLDER_CHANGED_CHANNELS) {\n\t\t\tsubscribe(channel, this.onFolderChanged)\n\t\t}\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.cnDetailSideColumn?.claim?.(this.$.uid, false)\n\t\tfor (const channel of FOLDER_CHANGED_CHANNELS) {\n\t\t\tunsubscribe(channel, this.onFolderChanged)\n\t\t}\n\t\tclearTimeout(this._folderChangedTimer)\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tpreventMiddleClickAutoscroll,\n\n\t\t/**\n\t\t * Hold the file input element from its function ref.\n\t\t *\n\t\t * @param {HTMLInputElement|null} el The element.\n\t\t * @return {void}\n\t\t */\n\t\tfileInputRef(el) {\n\t\t\tthis.fileInputEl = el || null\n\t\t},\n\n\t\t/**\n\t\t * The DAV path of a user-relative path.\n\t\t *\n\t\t * @param {string} path The user-relative path.\n\t\t * @return {string} The path under the DAV files root.\n\t\t */\n\t\tdavPath(path) {\n\t\t\treturn `${getRootPath()}${path}`\n\t\t},\n\n\t\t/**\n\t\t * List the open folder over DAV, with the same PROPFIND the Files app sends.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync refresh() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\tif (this.source) {\n\t\t\t\tawait this.refreshFromSource()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst client = getClient()\n\t\t\t\tconst { data } = await client.getDirectoryContents(this.davPath(this.currentPath), {\n\t\t\t\t\tdetails: true,\n\t\t\t\t\tdata: this.propfindBody(),\n\t\t\t\t\tincludeSelf: true,\n\t\t\t\t})\n\t\t\t\tconst stats = Array.isArray(data) ? data : []\n\t\t\t\tconst nodes = stats.map((stat) => resultToNode(stat))\n\t\t\t\tconst self = nodes.find((node) => node.path === this.currentPath) || nodes[0] || null\n\t\t\t\tthis.folder = self\n\t\t\t\tthis.nodes = nodes.filter((node) => node !== self)\n\t\t\t\t// One call per folder, not one per file: the host's projection\n\t\t\t\t// is asked for the whole listing at once.\n\t\t\t\tawait this.resolveRowData(this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst status = err?.response?.status ?? err?.status\n\t\t\t\tthis.error = status === 404\n\t\t\t\t\t? t('nextcloud-vue', 'This folder no longer exists')\n\t\t\t\t\t: (status === 403 ? t('nextcloud-vue', 'You cannot see this folder') : t('nextcloud-vue', 'The folder could not be read'))\n\t\t\t\tthis.folder = null\n\t\t\t\tthis.nodes = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * List the open folder through the `source`.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync refreshFromSource() {\n\t\t\ttry {\n\t\t\t\tconst { folder, nodes } = await this.source.list(this.currentPath)\n\t\t\t\tthis.folder = folder\n\t\t\t\tthis.nodes = nodes\n\t\t\t\tawait this.resolveRowData(this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst atRoot = (this.currentPath.replace(/\\/+$/, '') || '/') === (this.rootPath.replace(/\\/+$/, '') || '/')\n\t\t\t\tthis.error = err?.status === 404\n\t\t\t\t\t? (atRoot ? t('nextcloud-vue', 'You cannot see these files') : t('nextcloud-vue', 'This folder no longer exists'))\n\t\t\t\t\t: (err?.status === 403 ? t('nextcloud-vue', 'You cannot see this folder') : t('nextcloud-vue', 'The folder could not be read'))\n\t\t\t\tthis.folder = null\n\t\t\t\tthis.nodes = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Where a file downloads from, through the `source`.\n\t\t *\n\t\t * @param {object} node The row.\n\t\t * @return {string|null} The url.\n\t\t */\n\t\tsourceDownloadUrl(node) {\n\t\t\treturn this.source && typeof this.source.downloadUrl === 'function' ? this.source.downloadUrl(node) : null\n\t\t},\n\n\t\t/**\n\t\t * Open the delete dialog on a row.\n\t\t *\n\t\t * @param {object} node The row.\n\t\t * @return {void}\n\t\t */\n\t\taskRemove(node) {\n\t\t\tthis.removing = node\n\t\t\tthis.removeError = ''\n\t\t},\n\n\t\t/**\n\t\t * Delete the row named in the dialog, through the `source`.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync remove() {\n\t\t\tconst node = this.removing\n\t\t\tif (node === null || !this.source) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this.source.remove(node)\n\t\t\t\tthis.removing = null\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.removeError = err?.message || t('nextcloud-vue', '{action} did not succeed', { action: this.deleteLabel })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a folder below the root.\n\t\t *\n\t\t * @param {string} path The user-relative path.\n\t\t * @return {void}\n\t\t */\n\t\tnavigate(path) {\n\t\t\tconst root = this.rootPath.replace(/\\/+$/, '') || '/'\n\t\t\tif (path !== root && !path.startsWith(root === '/' ? '/' : `${root}/`)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentPath = path\n\t\t\tthis.refresh()\n\t\t},\n\n\t\t/**\n\t\t * Whether a node is a folder.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {boolean} true for a folder.\n\t\t */\n\t\tisFolder(node) {\n\t\t\treturn node.type === FileType.Folder\n\t\t},\n\n\t\t/**\n\t\t * A row was clicked: enter a folder, or open a file the way the Files\n\t\t * app would (its `view` action, which hands over to the Viewer).\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync open(node) {\n\t\t\tif (this.isFolder(node)) {\n\t\t\t\tthis.navigate(node.path)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.source) {\n\t\t\t\tconst url = this.sourceDownloadUrl(node)\n\t\t\t\tif (url) {\n\t\t\t\t\twindow.open(url, '_blank', 'noopener,noreferrer')\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst view = this.actionsFor(node).find((action) => action.id === 'view')\n\t\t\tif (view) {\n\t\t\t\tawait this.run(view, node)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (node.fileid) {\n\t\t\t\twindow.open(this.permalink(node), '_blank', 'noopener,noreferrer')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Row click: a ctrl/cmd/shift click opens the node's permalink in a new\n\t\t * tab, like a link would; a plain click opens it in place (`open`).\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @param {MouseEvent} [event] The click event.\n\t\t * @return {void}\n\t\t */\n\t\tonRowClick(node, event) {\n\t\t\tif (isNewTabClick(event)) {\n\t\t\t\tthis.openInNewTab(node)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.open(node)\n\t\t},\n\n\t\t/**\n\t\t * Row middle click: open the node's permalink in a new tab.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void}\n\t\t */\n\t\tonRowAuxClick(node, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\tthis.openInNewTab(node)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a node's permalink (a file or a folder in the Files app) in a new tab.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\topenInNewTab(node) {\n\t\t\tif (this.source) {\n\t\t\t\tif (this.isFolder(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst url = this.sourceDownloadUrl(node)\n\t\t\t\tif (url) {\n\t\t\t\t\twindow.open(url, '_blank', 'noopener,noreferrer')\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (node.fileid) {\n\t\t\t\twindow.open(this.permalink(node), '_blank', 'noopener,noreferrer')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The action context the Files app hands its actions for one node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {object} The context.\n\t\t */\n\t\tcontextFor(node) {\n\t\t\treturn { nodes: [node], view: this.view, folder: this.folder, contents: this.nodes }\n\t\t},\n\n\t\t/**\n\t\t * The registered actions that apply to a node, in the Files app's order.\n\t\t *\n\t\t * Inline actions (a sharing badge, an unread-comments dot) are status\n\t\t * marks the Files app paints beside the name, not menu items; a\n\t\t * sub-action lives under its parent's own menu; and the actions that\n\t\t * need the Files page are named in `ACTIONS_NEEDING_THE_FILES_PAGE`.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Array<object>} The actions.\n\t\t */\n\t\tactionsFor(node) {\n\t\t\tif (this.source) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tlet actions\n\t\t\ttry {\n\t\t\t\tactions = getFileActions()\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst context = this.contextFor(node)\n\t\t\treturn actions\n\t\t\t\t.filter((action) => !action.parent && !ACTIONS_NEEDING_THE_FILES_PAGE.includes(action.id))\n\t\t\t\t.filter((action) => typeof action.inline !== 'function' || action.inline(context) !== true)\n\t\t\t\t.filter((action) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn typeof action.enabled !== 'function' || action.enabled(context) === true\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n\t\t},\n\n\t\t/**\n\t\t * An action's label for a node, in the words the Files app uses.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {string} The label.\n\t\t */\n\t\t/**\n\t\t * A host action's label in the user's language.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-a-declared-row-action-reads-in-the-users-language\n\t\t * @param {object} action The manifest-declared action.\n\t\t * @return {string} The label.\n\t\t */\n\t\thostLabel(action) {\n\t\t\treturn this.cnTranslate(String(action?.label ?? ''))\n\t\t},\n\n\t\t/**\n\t\t * The second line under a file's name, or '' without `nameSecondary`,\n\t\t * for a folder, or when a value in it is empty.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {string}\n\t\t */\n\t\tnameSecondaryOf(node) {\n\t\t\tconst fields = this.secondLineFields\n\t\t\tif ((!this.nameSecondary && fields === null) || this.isFolder(node)) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst byId = this.resolvedRowData && typeof this.resolvedRowData === 'object' ? this.resolvedRowData : {}\n\t\t\tconst entry = byId[node.fileid] ?? byId[String(node.fileid)] ?? {}\n\t\t\tconst owner = node.attributes ? node.attributes['owner-display-name'] : undefined\n\t\t\tconst object = {\n\t\t\t\t...entry,\n\t\t\t\tname: node.basename,\n\t\t\t\t// A template drops an object value, so the Date is handed over as ISO text.\n\t\t\t\tmodified: node.mtime instanceof Date ? node.mtime.toISOString() : node.mtime,\n\t\t\t\tsize: this.formatSize(node.size),\n\t\t\t\ttype: this.typeLabelOf(node),\n\t\t\t\t...(owner ? { owner } : {}),\n\t\t\t}\n\t\t\tif (fields !== null) {\n\t\t\t\treturn fields\n\t\t\t\t\t.map((field) => fillTemplate(`{${field}}`, object))\n\t\t\t\t\t.filter((text) => text !== '')\n\t\t\t\t\t.join(' · ')\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(this.nameSecondary), object)\n\t\t},\n\n\t\t/**\n\t\t * A file's type as a reader names it: the application for common\n\t\t * office types (\"PDF\", \"Word\", \"Excel\"), \"Email\" for a mail, \"Image\"\n\t\t * for a picture, else the extension in capitals.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {string} The label, or ''.\n\t\t * @spec openspec/changes/files-browser-second-line-size-type/specs/files-browser-second-line-size-type/spec.md#requirement-a-files-second-line-can-name-its-type-and-size\n\t\t */\n\t\ttypeLabelOf(node) {\n\t\t\tconst mime = String(node?.mime || '')\n\t\t\tif (mime === 'application/pdf') {\n\t\t\t\treturn 'PDF'\n\t\t\t}\n\t\t\tif (/msword|wordprocessingml/.test(mime)) {\n\t\t\t\treturn 'Word'\n\t\t\t}\n\t\t\tif (/ms-excel|spreadsheetml/.test(mime)) {\n\t\t\t\treturn 'Excel'\n\t\t\t}\n\t\t\tif (/ms-powerpoint|presentationml/.test(mime)) {\n\t\t\t\treturn 'PowerPoint'\n\t\t\t}\n\t\t\tif (mime === 'message/rfc822' || mime === 'application/vnd.ms-outlook') {\n\t\t\t\treturn t('nextcloud-vue', 'Email')\n\t\t\t}\n\t\t\tif (mime.startsWith('image/')) {\n\t\t\t\treturn t('nextcloud-vue', 'Image')\n\t\t\t}\n\t\t\tconst match = /\\.([a-z0-9]+)$/i.exec(String(node?.basename || ''))\n\t\t\treturn match ? match[1].toUpperCase() : ''\n\t\t},\n\n\t\t/**\n\t\t * A review summary line: the host's template through its translate, else\n\t\t * the library's, with the counts filled in.\n\t\t *\n\t\t * @param {string} key `title` or `subtitle`.\n\t\t * @param {string} fallback The library's line, already translated.\n\t\t * @return {string}\n\t\t */\n\t\treviewText(key, fallback) {\n\t\t\tconst own = this.reviewSummary && typeof this.reviewSummary[key] === 'string' && this.reviewSummary[key] !== ''\n\t\t\t\t? this.cnTranslate(this.reviewSummary[key])\n\t\t\t\t: fallback\n\t\t\tconst counts = this.review || { done: 0, total: 0, open: 0 }\n\t\t\treturn own.replace(/\\{(done|total|open)\\}/g, (match, name) => String(counts[name]))\n\t\t},\n\n\t\t/**\n\t\t * Whether a review value is one of the summary's open values.\n\t\t *\n\t\t * @param {string} value The value.\n\t\t * @return {boolean}\n\t\t */\n\t\tisOpenValue(value) {\n\t\t\tconst open = this.reviewSummary ? this.reviewSummary.open : undefined\n\t\t\tconst list = (Array.isArray(open) ? open : [open]).filter((v) => v !== undefined && v !== null)\n\t\t\treturn list.some((v) => String(v).toLowerCase() === String(value).toLowerCase())\n\t\t},\n\n\t\t/**\n\t\t * Whether a file's row button is the primary one: the row-data field\n\t\t * `primaryWhen.key` holds one of `primaryWhen.values`.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {boolean}\n\t\t */\n\t\trowButtonPrimary(node) {\n\t\t\tconst when = this.rowButton && this.rowButton.primaryWhen\n\t\t\tif (!when || typeof when.key !== 'string' || !Array.isArray(when.values)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst raw = fileColumnValue({ key: when.key, source: 'row' }, node, this.resolvedRowData)\n\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn when.values.some((v) => String(v).toLowerCase() === String(raw).toLowerCase())\n\t\t},\n\n\t\thostActionApplies,\n\n\t\t/**\n\t\t * Re-read the folder once after a burst of change signals. One upload\n\t\t * of ten files answers ten `files:node:created`, and one PROPFIND\n\t\t * covers them all.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-the-files-browser-re-reads-when-the-page-says-files-changed\n\t\t * @return {void}\n\t\t */\n\t\tonFolderChanged() {\n\t\t\tclearTimeout(this._folderChangedTimer)\n\t\t\tthis._folderChangedTimer = setTimeout(() => this.refresh(), FOLDER_CHANGED_DEBOUNCE_MS)\n\t\t},\n\n\t\tlabelOf(action, node) {\n\t\t\ttry {\n\t\t\t\treturn action.displayName(this.contextFor(node))\n\t\t\t} catch {\n\t\t\t\treturn action.id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * An action's icon for a node, as inline SVG.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {string} The SVG, or the empty string.\n\t\t */\n\t\ticonOf(action, node) {\n\t\t\ttry {\n\t\t\t\treturn action.iconSvgInline(this.contextFor(node)) || ''\n\t\t\t} catch {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run a registered action on a node, then re-read the folder: most of\n\t\t * them change it (a delete, a rename, a move), and the ones that do\n\t\t * not cost one PROPFIND.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync run(action, node) {\n\t\t\ttry {\n\t\t\t\tconst result = await action.exec(this.contextFor(node))\n\t\t\t\tif (result === false) {\n\t\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\t\tshowError(t('nextcloud-vue', '{action} did not succeed', { action: this.labelOf(action, node) }))\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\tshowError(err?.message || t('nextcloud-vue', '{action} did not succeed', { action: this.labelOf(action, node) }))\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\t/**\n\t\t\t * @event changed The folder's contents changed through this browser:\n\t\t\t * an upload, a new folder, or an action that ran.\n\t\t\t */\n\t\t\tthis.$emit('changed')\n\t\t},\n\n\t\t/**\n\t\t * Run a New menu entry the Files app or a plugin registered, then re-read.\n\t\t *\n\t\t * The `newFolder` entry the Files app registers opens its own inline\n\t\t * rename in the Files list, which is not here, so that one is answered\n\t\t * by this component's dialog instead.\n\t\t *\n\t\t * @param {object} entry The entry.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync runNewEntry(entry) {\n\t\t\tif (entry.id === 'newFolder') {\n\t\t\t\tthis.askNewFolder()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait entry.handler(this.folder, this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\tshowError(err?.message || t('nextcloud-vue', '{action} did not succeed', { action: entry.displayName }))\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\tthis.$emit('changed')\n\t\t},\n\n\t\t/**\n\t\t * Open the new-folder dialog.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\taskNewFolder() {\n\t\t\tthis.newFolderName = ''\n\t\t\tthis.newFolderError = ''\n\t\t\tthis.newFolderOpen = true\n\t\t},\n\n\t\t/**\n\t\t * Create the folder named in the dialog, over DAV.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync createFolder() {\n\t\t\tconst name = this.newFolderName.trim()\n\t\t\tif (name === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.nodes.some((node) => node.basename === name)) {\n\t\t\t\tthis.newFolderError = t('nextcloud-vue', 'A file or folder with that name is already here')\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.source.createFolder(this.currentPath, name)\n\t\t\t\t} else {\n\t\t\t\t\tawait getClient().createDirectory(this.davPath(joinPath(this.currentPath, name)))\n\t\t\t\t}\n\t\t\t\tthis.newFolderOpen = false\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.newFolderError = err?.message || t('nextcloud-vue', 'The folder could not be created')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open the rename dialog on a node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\taskRename(node) {\n\t\t\tthis.renaming = node\n\t\t\tthis.renameName = node.basename\n\t\t\tthis.renameError = ''\n\t\t},\n\n\t\t/**\n\t\t * Rename the node named in the dialog, as a DAV move within its folder.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync rename() {\n\t\t\tconst node = this.renaming\n\t\t\tconst name = this.renameName.trim()\n\t\t\tif (node === null || name === '' || name === node.basename) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (name.includes('/')) {\n\t\t\t\tthis.renameError = t('nextcloud-vue', 'A name cannot contain a slash')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.nodes.some((other) => other !== node && other.basename === name)) {\n\t\t\t\tthis.renameError = t('nextcloud-vue', 'A file or folder with that name is already here')\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.source.rename(node, name)\n\t\t\t\t} else {\n\t\t\t\t\tawait getClient().moveFile(this.davPath(node.path), this.davPath(joinPath(this.currentPath, name)))\n\t\t\t\t}\n\t\t\t\tthis.renaming = null\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.renameError = err?.message || t('nextcloud-vue', 'The name could not be changed')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open the file picker.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tpickFiles() {\n\t\t\tthis.fileInputEl?.click()\n\t\t},\n\n\t\t/**\n\t\t * Files were picked.\n\t\t *\n\t\t * @param {Event} event The change event.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onFilesPicked(event) {\n\t\t\tconst files = event.target?.files\n\t\t\tif (files?.length) {\n\t\t\t\tawait this.uploadFiles(files)\n\t\t\t}\n\t\t\tif (this.fileInputEl) {\n\t\t\t\tthis.fileInputEl.value = ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Files were dropped.\n\t\t *\n\t\t * @param {DragEvent} event The drop.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onDrop(event) {\n\t\t\tthis.dragging = false\n\t\t\tthis.dragDepth = 0\n\t\t\tthis.dropStatus = ''\n\t\t\tif (!this.canChange) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst files = event.dataTransfer?.files\n\t\t\tif (files?.length) {\n\t\t\t\tawait this.uploadFiles(files)\n\t\t\t\tif (this.dropOverlay) {\n\t\t\t\t\tthis.dropStatus = n('nextcloud-vue', '%n file added', '%n files added', files.length)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Something is dragged into the browser: show the drop state when it\n\t\t * carries files, and say so once.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {void}\n\t\t */\n\t\tonDragEnter(event) {\n\t\t\tif (!this.canChange || !this.carriesFiles(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.dragDepth++\n\t\t\tif (!this.dragging) {\n\t\t\t\tthis.dragging = true\n\t\t\t\tthis.dragCount = this.draggedFileCount(event)\n\t\t\t\tthis.dropStatus = this.dropOverlay ? [this.cnTranslate(this.dropLabel), this.dropDetailText].filter(Boolean).join(' ') : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Keep the drop state while files move over the browser.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {void}\n\t\t */\n\t\tonDragOver(event) {\n\t\t\tif (this.canChange && this.carriesFiles(event)) {\n\t\t\t\tthis.dragging = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Something left the browser, or one of its children. The drop state\n\t\t * ends only when the drag has left the browser itself.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonDragLeave() {\n\t\t\tthis.dragDepth = Math.max(0, this.dragDepth - 1)\n\t\t\tif (this.dragDepth === 0) {\n\t\t\t\tthis.dragging = false\n\t\t\t\tthis.dropStatus = ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * How many files a drag carries, or null when the browser does not\n\t\t * say (it lists the items only once they are dropped in some browsers).\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {number|null}\n\t\t */\n\t\tdraggedFileCount(event) {\n\t\t\tconst items = event?.dataTransfer?.items\n\t\t\tif (!items || typeof items.length !== 'number') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst count = Array.from(items).filter((item) => item && item.kind === 'file').length\n\t\t\treturn count > 0 ? count : null\n\t\t},\n\n\t\t/**\n\t\t * Whether a drag carries files (not text or a link from the page).\n\t\t * A drag whose types cannot be read counts as files, as before.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {boolean}\n\t\t */\n\t\tcarriesFiles(event) {\n\t\t\tconst types = event?.dataTransfer?.types\n\t\t\tif (!types) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn Array.from(types).includes('Files')\n\t\t},\n\n\t\t/**\n\t\t * PUT each file into the open folder over DAV, with a progress row\n\t\t * each, then re-read the folder once.\n\t\t *\n\t\t * @param {FileList|File[]} files The files.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync uploadFiles(files) {\n\t\t\tif (this.folder === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// A PUT through axios rather than the DAV client: the client's\n\t\t\t// putFileContents refuses a browser File (\"Cannot calculate data\n\t\t\t// length\"), and fetch reports no upload progress anyway. axios\n\t\t\t// carries the session and the request token, and its XHR reports\n\t\t\t// progress per file. If-None-Match: * refuses to overwrite.\n\t\t\tconst batch = [...files].map((file) => ({ key: `u${++uploadSeq}`, name: file.name, progress: 0, error: '', file }))\n\t\t\tthis.uploads = [...this.uploads, ...batch]\n\t\t\tfor (const upload of batch) {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.uploadThroughSource(upload)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait axios.put(`${getRemoteURL()}${this.davPath(joinPath(this.currentPath, upload.name))}`, upload.file, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type': upload.file.type || 'application/octet-stream',\n\t\t\t\t\t\t\t'If-None-Match': '*',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonUploadProgress: (progress) => {\n\t\t\t\t\t\t\tif (progress?.total) {\n\t\t\t\t\t\t\t\tupload.progress = Math.round((progress.loaded / progress.total) * 100)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\tupload.progress = 100\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst status = err?.response?.status ?? err?.status\n\t\t\t\t\tupload.error = status === 412\n\t\t\t\t\t\t? t('nextcloud-vue', 'A file with that name is already here')\n\t\t\t\t\t\t: (err?.message || t('nextcloud-vue', 'The upload failed'))\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\tthis.$emit('changed')\n\t\t\t// Finished rows leave the list; failed ones stay with their reason.\n\t\t\twindow.setTimeout(() => {\n\t\t\t\tthis.uploads = this.uploads.filter((upload) => upload.error !== '' || batch.every((b) => b.key !== upload.key))\n\t\t\t}, 1500)\n\t\t},\n\n\t\t/**\n\t\t * Store one upload through the `source`, keeping its progress row.\n\t\t *\n\t\t * @param {object} upload The progress row, carrying the file.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync uploadThroughSource(upload) {\n\t\t\ttry {\n\t\t\t\tawait this.source.upload(this.currentPath, upload.file, (percent) => {\n\t\t\t\t\tupload.progress = percent\n\t\t\t\t})\n\t\t\t\tupload.progress = 100\n\t\t\t} catch (err) {\n\t\t\t\tupload.error = err?.status === 409\n\t\t\t\t\t? t('nextcloud-vue', 'A file with that name is already here')\n\t\t\t\t\t: (err?.message || t('nextcloud-vue', 'The upload failed'))\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Change the sort column, or flip the order on the same one.\n\t\t *\n\t\t * @param {string} key `basename`, `size` or `mtime`.\n\t\t * @return {void}\n\t\t */\n\t\t/**\n\t\t * The PROPFIND this browser sends: the Files app's own body, plus one\n\t\t * `<prop>` for every DAV property a declared `attribute` column reads,\n\t\t * so that value is on the node when the folder lists rather than one\n\t\t * request later.\n\t\t *\n\t\t * @return {string} The PROPFIND body.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\tpropfindBody() {\n\t\t\tconst base = getDefaultPropfind()\n\t\t\tconst extra = attributePropertiesFor(this.declaredColumns)\n\t\t\tif (extra.length === 0) {\n\t\t\t\treturn base\n\t\t\t}\n\t\t\tconst props = extra.map((name) => {\n\t\t\t\tconst match = /^\\{(.+)\\}(.+)$/.exec(name)\n\t\t\t\tif (!match) {\n\t\t\t\t\treturn `<d:${name} />`\n\t\t\t\t}\n\t\t\t\treturn `<x-cn:${match[2]} xmlns:x-cn=\"${match[1]}\" />`\n\t\t\t}).join('')\n\t\t\t// Spliced into the existing <d:prop> rather than appended after it:\n\t\t\t// a second <d:prop> block is not a PROPFIND any server answers.\n\t\t\treturn base.includes('</d:prop>')\n\t\t\t\t? base.replace('</d:prop>', `${props}</d:prop>`)\n\t\t\t\t: base\n\t\t},\n\n\t\t/**\n\t\t * The token a column sorts under: the Files app's own sorting mode for\n\t\t * a built-in, the column key for anything else.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {string} The sort token.\n\t\t */\n\t\tsortTokenOf(column) {\n\t\t\treturn (column && (column.sortKey || column.key)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The label a column's header shows: what the host wrote, else the\n\t\t * library's own word for a built-in, else the key.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {string} The header text.\n\t\t */\n\t\tcolumnLabel(column) {\n\t\t\tif (column && typeof column.label === 'string' && column.label !== '') {\n\t\t\t\treturn this.cnTranslate(column.label)\n\t\t\t}\n\t\t\treturn this.builtInColumnLabels[column && column.key] || (column && column.key) || ''\n\t\t},\n\n\t\t/**\n\t\t * One cell's value.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @param {object} node The node.\n\t\t * @return {(Array|object|string|number|boolean|undefined)} The value.\n\t\t */\n\t\tcellValue(column, node) {\n\t\t\treturn fileColumnValue(column, node, this.resolvedRowData)\n\t\t},\n\n\t\t/**\n\t\t * The tone a column or card field draws a value in: its `colorMap`\n\t\t * entry for the value (case-insensitive), read from the `colorKey` field\n\t\t * of the row when given, else from the value itself. '' without one.\n\t\t *\n\t\t * @param {object} column A resolved column or a side card field.\n\t\t * @param {object} node The node.\n\t\t * @return {string} A badge variant (`success`, `warning`, `error`, ...) or ''.\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-a-row-column-can-draw-its-values-in-tones\n\t\t */\n\t\ttoneOf(column, node) {\n\t\t\tconst map = column && column.colorMap\n\t\t\tif (!map || typeof map !== 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst raw = column.colorKey\n\t\t\t\t? fileColumnValue({ key: column.colorKey, source: 'row' }, node, this.resolvedRowData)\n\t\t\t\t: this.cellValue(column, node)\n\t\t\tif (raw === null || raw === undefined || typeof raw === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst wanted = String(raw).toLowerCase()\n\t\t\tconst hit = Object.keys(map).find((key) => key.toLowerCase() === wanted)\n\t\t\treturn hit ? String(map[hit]) : ''\n\t\t},\n\n\t\t/**\n\t\t * The widget props a cell gets: the column's own, and for a `badge`\n\t\t * its tone as the variant.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @param {object} node The node.\n\t\t * @return {object|null}\n\t\t */\n\t\tcellWidgetProps(column, node) {\n\t\t\tif (column.widget !== 'badge') {\n\t\t\t\treturn column.widgetProps || null\n\t\t\t}\n\t\t\tconst tone = this.toneOf(column, node)\n\t\t\treturn { ...(column.widgetProps || {}), ...(tone ? { variant: tone } : {}) }\n\t\t},\n\n\t\t/**\n\t\t * The side cards for a file, resolved: the title with `{name}` filled\n\t\t * in, the fields that have a value with their tone, and the actions.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Array<{id: string, title: string, fields: Array<object>, actions: Array<object>}>}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\tsideCardsFor(node) {\n\t\t\treturn this.sideCards\n\t\t\t\t.filter((card) => card && card.id)\n\t\t\t\t.map((card) => ({\n\t\t\t\t\tid: String(card.id),\n\t\t\t\t\ttitle: this.cnTranslate(String(card.title || '')).replace(/\\{name\\}/g, node.basename),\n\t\t\t\t\tfields: (Array.isArray(card.fields) ? card.fields : [])\n\t\t\t\t\t\t.filter((field) => field && field.key)\n\t\t\t\t\t\t.map((field) => {\n\t\t\t\t\t\t\tconst column = { ...field, source: field.source || 'row' }\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tkey: String(field.key),\n\t\t\t\t\t\t\t\tlabel: this.cnTranslate(String(field.label || field.key)),\n\t\t\t\t\t\t\t\tvalue: this.cellValue(column, node),\n\t\t\t\t\t\t\t\tformatter: field.formatter,\n\t\t\t\t\t\t\t\tformatterOptions: field.formatterOptions,\n\t\t\t\t\t\t\t\ttone: this.toneOf(column, node),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter((field) => field.value !== null && field.value !== undefined && field.value !== ''),\n\t\t\t\t\tactions: (Array.isArray(card.actions) ? card.actions : [])\n\t\t\t\t\t\t.filter((action) => action && action.id && hostActionApplies(action, node, this.rowValueOf(node))),\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Whether a user currently sees a column, for the chooser's ticks.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {boolean} True when it renders.\n\t\t */\n\t\tisColumnVisible(column) {\n\t\t\treturn this.renderedColumns.some((c) => c.key === column.key)\n\t\t},\n\n\t\t/**\n\t\t * Tick or untick a column for this user and remember it.\n\t\t *\n\t\t * The stored value is always rebuilt from the host's declaration, never\n\t\t * from the previous stored value, so a key the host has since dropped\n\t\t * cannot survive a toggle and reappear later.\n\t\t *\n\t\t * @param {object} column The column being toggled.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\ttoggleColumn(column) {\n\t\t\tconst next = this.declaredColumns\n\t\t\t\t.filter((c) => (c.key === column.key ? !this.isColumnVisible(c) : this.isColumnVisible(c)))\n\t\t\t\t.map((c) => c.key)\n\t\t\tthis.visibleColumnKeys = next\n\t\t\tthis.saveColumnChoice(next)\n\t\t},\n\n\t\t/**\n\t\t * Read this user's column choice. A stored key the host no longer\n\t\t * declares is dropped on the way in as well as on the way out, so the\n\t\t * chooser never lists a column that cannot render.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadColumnChoice() {\n\t\t\tif (!this.columnsChooserEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst stored = await readUserPreference(this.preferenceApp, this.preferenceKey, null)\n\t\t\tif (!Array.isArray(stored)) {\n\t\t\t\tthis.visibleColumnKeys = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst declared = new Set(this.declaredColumns.map((c) => c.key))\n\t\t\tthis.visibleColumnKeys = stored.filter((key) => declared.has(key))\n\t\t},\n\n\t\t/**\n\t\t * Store this user's column choice.\n\t\t *\n\t\t * @param {string[]} keys The visible column keys.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveColumnChoice(keys) {\n\t\t\tif (!this.columnsChooserEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait writeUserPreference(this.preferenceApp, this.preferenceKey, keys)\n\t\t},\n\n\t\t/**\n\t\t * Resolve the host's per-file data for this folder's nodes. Called once\n\t\t * per listing, so a projection of ninety files is one request.\n\t\t *\n\t\t * @param {Array<object>} nodes The listed nodes.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync resolveRowData(nodes) {\n\t\t\tif (this.rowData === null || this.rowData === undefined) {\n\t\t\t\tthis.resolvedRowData = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (typeof this.rowData !== 'function') {\n\t\t\t\tthis.resolvedRowData = this.rowData\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.resolvedRowData = await this.rowData(nodes)\n\t\t\t} catch {\n\t\t\t\t// A projection that could not be fetched leaves those cells\n\t\t\t\t// empty. It is not a reason to say the folder failed to list:\n\t\t\t\t// the files are there and the host's extra columns are not.\n\t\t\t\tthis.resolvedRowData = null\n\t\t\t}\n\t\t},\n\n\t\tsortBy(key) {\n\t\t\tif (this.sortKey === key) {\n\t\t\t\tthis.sortAsc = !this.sortAsc\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.sortKey = key\n\t\t\t// Size and modified read most usefully largest and newest first;\n\t\t\t// everything else, including every declared column, starts at A.\n\t\t\tthis.sortAsc = key !== 'size' && key !== 'mtime'\n\t\t},\n\n\t\t/**\n\t\t * The `aria-sort` value for a column header.\n\t\t *\n\t\t * @param {string} key The column's sort key.\n\t\t * @return {string|null} `ascending`, `descending` or null.\n\t\t */\n\t\tariaSort(key) {\n\t\t\tif (this.sortKey !== key) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.sortAsc ? 'ascending' : 'descending'\n\t\t},\n\n\t\t/**\n\t\t * The arrow beside the sorted column's name.\n\t\t *\n\t\t * @param {string} key The column's sort key.\n\t\t * @return {object} The icon component.\n\t\t */\n\t\tsortIcon(key) {\n\t\t\treturn this.sortKey === key && !this.sortAsc ? ChevronDown : ChevronUp\n\t\t},\n\n\t\t/**\n\t\t * A file's size the way the Files app prints it.\n\t\t *\n\t\t * @param {number|undefined} size The size in bytes.\n\t\t * @return {string} The size, or the empty string.\n\t\t */\n\t\tformatSize(size) {\n\t\t\treturn typeof size === 'number' ? formatFileSize(size, true) : ''\n\t\t},\n\n\t\t/**\n\t\t * The theme's own icon for a node's mime type, or null off Nextcloud.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string|null} The icon url.\n\t\t */\n\t\tmimeIconFor(node) {\n\t\t\tconst getIconUrl = typeof window !== 'undefined' ? window.OC?.MimeType?.getIconUrl : null\n\t\t\tif (typeof getIconUrl !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn getIconUrl(this.isFolder(node) ? 'dir' : (node.mime || '')) || null\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A small preview for a raster image, from the core preview endpoint.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string|null} The url, or null.\n\t\t */\n\t\tpreviewUrlFor(node) {\n\t\t\tconst mime = node.mime || ''\n\t\t\tif (!node.fileid || this.isFolder(node) || !/^image\\//i.test(mime) || /svg/i.test(mime) || this.previewFailed[node.fileid]) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (this.source) {\n\t\t\t\treturn typeof this.source.previewUrl === 'function' ? this.source.previewUrl(node) : null\n\t\t\t}\n\t\t\treturn generateUrl('/core/preview?fileId={fileId}&x=64&y=64&a=1', { fileId: node.fileid })\n\t\t},\n\n\t\t/**\n\t\t * Remember a preview that did not load.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\tonPreviewError(node) {\n\t\t\tthis.previewFailed = { ...this.previewFailed, [node.fileid]: true }\n\t\t},\n\n\t\t/**\n\t\t * The Files app opened on a folder, for the crumbs above the root.\n\t\t *\n\t\t * @param {string} path The user-relative folder path.\n\t\t * @return {string} The url.\n\t\t */\n\t\tfilesAppUrl(path) {\n\t\t\treturn generateUrl('/apps/files/files?dir={dir}', { dir: path })\n\t\t},\n\n\t\t/**\n\t\t * The Files app's permalink for a node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string} The url.\n\t\t */\n\t\tpermalink(node) {\n\t\t\treturn generateUrl('/f/{fileid}', { fileid: node.fileid })\n\t\t},\n\n\t\t/**\n\t\t * Whether a file is selected.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {boolean} True when selected.\n\t\t */\n\t\tisSelected(node) {\n\t\t\treturn this.selectedIds.includes(String(node.fileid))\n\t\t},\n\n\t\t/**\n\t\t * Select or deselect one file.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @param {boolean} checked Whether it is now selected.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleSelected(node, checked) {\n\t\t\tconst id = String(node.fileid)\n\t\t\tconst rest = this.selectedIds.filter((entry) => entry !== id)\n\t\t\tthis.selectedIds = checked ? [...rest, id] : rest\n\t\t},\n\n\t\t/**\n\t\t * Select every file the filter keeps, or none.\n\t\t *\n\t\t * @param {boolean} checked Whether to select all.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleAll(checked) {\n\t\t\tthis.selectedIds = checked ? [...this.selectableIds] : []\n\t\t},\n\n\t\t/** Drop the selection. */\n\t\tclearSelection() {\n\t\t\tthis.selectedIds = []\n\t\t},\n\n\t\t/**\n\t\t * Run one of the host's bulk actions on the selected files, then drop\n\t\t * the selection. An `open-modal` action's props gain `files` and\n\t\t * `fileIds`; a `handler` action's args gain the selected nodes.\n\t\t *\n\t\t * @param {object} action The declared bulk action.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\trunBulkAction(action) {\n\t\t\tif (!action || typeof action !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst nodes = this.fileNodes.filter((node) => this.selectedIds.includes(String(node.fileid)))\n\t\t\tconst type = action.type || 'handler'\n\t\t\tlet wrapped = action\n\t\t\tif (type === 'open-modal') {\n\t\t\t\tconst files = nodes.map((node) => ({ fileId: node.fileid, fileName: node.basename, path: node.path }))\n\t\t\t\twrapped = { ...action, props: { ...(action.props || {}), files, fileIds: files.map((file) => file.fileId) } }\n\t\t\t} else if (type === 'handler') {\n\t\t\t\twrapped = { ...action, args: [...(action.args || []), nodes] }\n\t\t\t}\n\t\t\tthis.selectedIds = []\n\t\t\tif (typeof this.cnDispatchAction === 'function') {\n\t\t\t\tthis.cnDispatchAction(wrapped)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdispatchAction(wrapped, { router: this.$router || null })\n\t\t},\n\n\t\t/**\n\t\t * Choose or drop one facet value.\n\t\t *\n\t\t * @param {string} key The column key.\n\t\t * @param {string} value The value.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleFacet(key, value) {\n\t\t\tconst chosen = this.facetSelections[key] || []\n\t\t\tconst next = chosen.includes(value) ? chosen.filter((entry) => entry !== value) : [...chosen, value]\n\t\t\tthis.facetSelections = { ...this.facetSelections, [key]: next }\n\t\t},\n\n\t\t/** Drop every facet choice. */\n\t\tclearFacets() {\n\t\t\tthis.facetSelections = {}\n\t\t},\n\n\t\t/**\n\t\t * The host's own row actions that belong on this file: those whose\n\t\t * `visibleIf` (extension, mime) holds for it, or that name none.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {Array<object>} The actions to offer.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\thostActionsFor(node) {\n\t\t\treturn this.rowActions.filter((action) => hostActionApplies(action, node, this.rowValueOf(node)))\n\t\t},\n\n\t\t/**\n\t\t * A reader of the host's row fields for one file, for `visibleIf.row`.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {(key: string) => unknown} `(key) => value` over the row the host gave for the file.\n\t\t * @spec openspec/changes/files-browser-action-visible-if-row/specs/files-browser/spec.md#requirement-a-host-action-can-be-offered-by-a-field-of-the-files-row\n\t\t */\n\t\trowValueOf(node) {\n\t\t\treturn (key) => fileColumnValue({ key, source: 'row' }, node, this.resolvedRowData)\n\t\t},\n\n\t\t/**\n\t\t * Run one of the host's declared actions on a file.\n\t\t *\n\t\t * An `open-modal` action gets the node merged onto its props as\n\t\t * `fileId`, `fileName` and `path`, the same way a widget's row action\n\t\t * hands a modal its row; a `handler` action gets the node appended to\n\t\t * its args. Everything else is dispatched as declared.\n\t\t *\n\t\t * @param {object} action The declared action.\n\t\t * @param {object} node The file it was clicked on.\n\t\t * @return {void}\n\t\t */\n\t\trunHostAction(action, node) {\n\t\t\tif (!action || typeof action !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = action.type || 'handler'\n\t\t\tlet wrapped = action\n\t\t\t// A New-menu entry carries no row, only the folder it was opened in.\n\t\t\tconst context = node === null\n\t\t\t\t? { path: this.currentPath }\n\t\t\t\t: { fileId: node.fileid, fileName: node.basename, path: node.path }\n\t\t\tif (type === 'open-modal') {\n\t\t\t\twrapped = { ...action, props: { ...(action.props || {}), ...context, ...this.rowPropsOf(action, node) } }\n\t\t\t} else if (type === 'handler') {\n\t\t\t\twrapped = { ...action, args: [...(action.args || []), node ?? this.folder] }\n\t\t\t}\n\t\t\tif (typeof this.cnDispatchAction === 'function') {\n\t\t\t\tthis.cnDispatchAction(wrapped)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdispatchAction(wrapped, { router: this.$router || null })\n\t\t},\n\n\t\t/**\n\t\t * The clicked file's row-data fields an action asks for as modal props\n\t\t * (`rowProps: { prop: field }`), or none.\n\t\t *\n\t\t * @param {object} action The declared action.\n\t\t * @param {object|null} node The file, or null for a New-menu entry.\n\t\t * @return {object} The props.\n\t\t * @spec openspec/changes/files-review-row-when/specs/files-review-row-when/spec.md#requirement-a-modal-action-can-carry-fields-of-the-clicked-files-row-data\n\t\t */\n\t\trowPropsOf(action, node) {\n\t\t\tconst wanted = action && action.rowProps\n\t\t\tif (node === null || !wanted || typeof wanted !== 'object') {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst byId = this.resolvedRowData && typeof this.resolvedRowData === 'object' ? this.resolvedRowData : {}\n\t\t\tconst entry = byId[node.fileid] ?? byId[String(node.fileid)] ?? {}\n\t\t\tconst out = {}\n\t\t\tfor (const [prop, field] of Object.entries(wanted)) {\n\t\t\t\tconst value = readPath(entry, String(field))\n\t\t\t\tif (value !== undefined && value !== null && value !== '') {\n\t\t\t\t\tout[prop] = value\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * A click on a linked row opens the file where it lives.\n\t\t *\n\t\t * @param {object} item The linked item.\n\t\t * @return {void}\n\t\t */\n\t\topenLinked(item) {\n\t\t\tif (item.href && typeof window !== 'undefined') {\n\t\t\t\twindow.open(item.href, '_blank', 'noopener')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A middle click on a linked row opens it like a click does.\n\t\t *\n\t\t * @param {object} item The linked item.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void}\n\t\t */\n\t\tonLinkedAuxClick(item, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\tthis.openLinked(item)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The current user's id, for callers resolving a root path.\n\t\t *\n\t\t * @return {string} The uid, or the empty string.\n\t\t */\n\t\tcurrentUid() {\n\t\t\treturn getCurrentUser()?.uid || ''\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-files-browser {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmin-width: 0;\n\tposition: relative;\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-files-browser--dragging {\n\toutline: 2px dashed var(--color-primary-element);\n\toutline-offset: 4px;\n}\n\n/* With a `dropDetail` the drop state fills the panel it sits in, as the\n board draws it (DqZaakDocumentenSlepen), not only the list's own height. */\n.cn-files-browser--dragging.cn-files-browser--drop-panel {\n\tmin-height: max(320px, 100%);\n}\n\n.cn-files-browser__drop-detail {\n\tmax-width: 520px;\n\tfont-size: 14px;\n\tcolor: var(--color-main-text);\n}\n\n.cn-files-browser__drop-overlay {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 2;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 10px;\n\tpadding: 24px;\n\tbox-sizing: border-box;\n\tborder: 2px dashed var(--color-primary-element);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text, var(--color-main-text));\n\ttext-align: center;\n\tpointer-events: none;\n}\n\n.cn-files-browser__drop-icon {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 56px;\n\theight: 56px;\n\tborder-radius: 50%;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-primary-element);\n}\n\n.cn-files-browser__drop-label {\n\tfont-size: 20px;\n\tfont-weight: 700;\n}\n\n.cn-files-browser__drop-hint {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding-top: 12px;\n\tborder-top: 1px solid var(--color-border);\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__bar {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tmin-width: 0;\n}\n\n.cn-files-browser__crumbs {\n\tmin-width: 0;\n\tflex: 1 1 auto;\n}\n\n/* The crumbs give way, the controls do not: a long crumb (a folder named\n after a uuid) shrank the upload button to \"Bestanden...\" while the crumbs\n kept their width. */\n.cn-files-browser__bar > :not(.cn-files-browser__crumbs) {\n\tflex-shrink: 0;\n}\n\n.cn-files-browser__file-input {\n\tdisplay: none;\n}\n\n.cn-files-browser__uploads {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-files-browser__upload {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-files-browser__upload-name {\n\tfont-size: 13px;\n}\n\n.cn-files-browser__upload-error {\n\tcolor: var(--color-error);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__loading {\n\tpadding: 24px 0;\n}\n\n/* `sideCards`: the list and, while a file is selected, a column of cards. */\n.cn-files-browser__body--with-side {\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 1fr) minmax(240px, 300px);\n\talign-items: start;\n\tgap: 16px;\n}\n\n@media (max-width: 900px) {\n\t.cn-files-browser__body--with-side {\n\t\tgrid-template-columns: minmax(0, 1fr);\n\t}\n}\n\n.cn-files-browser__side {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n/* In the detail page's side column the cards take its gap and its card\n anatomy, as the page's own side cards are drawn. */\n.cn-files-browser__side--in-page {\n\tgap: calc(5 * var(--default-grid-baseline));\n}\n\n.cn-files-browser__side--in-page .cn-files-browser__side-card {\n\tpadding: var(--cn-board-card-padding, 16px 18px);\n\tborder-radius: var(--cn-board-card-radius, var(--border-radius-large));\n}\n\n.cn-files-browser__side-card {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tpadding: 16px 18px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tbackground: var(--color-main-background);\n}\n\n.cn-files-browser__side-title {\n\tmargin: 0;\n\tfont-size: 15px;\n\tfont-weight: 700;\n\toverflow-wrap: anywhere;\n}\n\n.cn-files-browser__side-facts {\n\tdisplay: grid;\n\tgrid-template-columns: max-content minmax(0, 1fr);\n\tgap: 6px 12px;\n\tmargin: 0;\n\tfont-size: 14px;\n}\n\n/* Core's apps.css draws every dt/dd inline-block with a fixed, end-aligned dt.\n @spec openspec/changes/files-side-facts-core-dl/specs/files-side-facts-core-dl/spec.md#requirement-a-file-side-cards-facts-are-not-drawn-by-cores-dl-rules */\n.cn-files-browser__side-facts dt,\n.cn-files-browser__side-facts dd {\n\tdisplay: block;\n\twidth: auto;\n\tpadding: 0;\n\ttext-align: start;\n\twhite-space: normal;\n}\n\n.cn-files-browser__side-facts dt {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__side-facts dd {\n\tmargin: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-files-browser__side-actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n\n/* A value drawn in a tone (`colorMap` on a column that is not a badge): the\n text in the tone's colour, as the boards write a restricted level. */\n.cn-files-browser__tone {\n\tfont-weight: 600;\n}\n\n.cn-files-browser__tone--success {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-files-browser__tone--warning {\n\tcolor: var(--color-warning-text, var(--color-warning));\n}\n\n.cn-files-browser__tone--error {\n\tcolor: var(--color-error-text, var(--color-error));\n}\n\n.cn-files-browser__tone--primary,\n.cn-files-browser__tone--info {\n\tcolor: var(--color-primary-element-light-text, var(--color-primary-element));\n}\n\n.cn-files-browser__table {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n}\n\n.cn-files-browser__table th {\n\ttext-align: start;\n\tfont-weight: normal;\n\tcolor: var(--color-text-maxcontrast);\n\tpadding: 4px 8px;\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-files-browser__sort {\n\tbackground: none;\n\tborder: none;\n\tpadding: 0;\n\tfont: inherit;\n\tcolor: inherit;\n\tcursor: pointer;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 2px;\n}\n\n.cn-files-browser__sort:hover,\n.cn-files-browser__sort:focus-visible {\n\tcolor: var(--color-main-text);\n}\n\n.cn-files-browser__row {\n\tcursor: pointer;\n}\n\n.cn-files-browser__row:hover,\n.cn-files-browser__row:focus-within {\n\tbackground-color: var(--color-background-hover);\n}\n\n.cn-files-browser__table td {\n\tpadding: 4px 8px;\n\tborder-bottom: 1px solid var(--color-border);\n\tvertical-align: middle;\n}\n\n.cn-files-browser__col-icon {\n\twidth: 48px;\n}\n\n.cn-files-browser__col-size {\n\twidth: 96px;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-mtime {\n\twidth: 140px;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-select {\n\twidth: 36px;\n\ttext-align: center;\n}\n\n.cn-files-browser__select {\n\twidth: 18px;\n\theight: 18px;\n\tmargin: 0;\n\taccent-color: var(--color-primary-element);\n}\n\n.cn-files-browser__bulk-bar {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 8px 12px;\n\tborder-radius: var(--border-radius-large);\n\tbackground: var(--color-primary-element-light);\n}\n\n.cn-files-browser__bulk-count {\n\tfont-weight: 600;\n\tmargin-inline-end: 8px;\n}\n\n.cn-files-browser__review {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tmargin-block-end: 12px;\n\tpadding: 14px 16px;\n\tborder-radius: 10px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-files-browser__review-head {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: baseline;\n\tjustify-content: space-between;\n\tgap: 8px;\n}\n\n.cn-files-browser__review-title {\n\tfont-size: 15px;\n}\n\n.cn-files-browser__review-sub {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__review-bar {\n\tdisplay: flex;\n\theight: 8px;\n\toverflow: hidden;\n\tborder-radius: 4px;\n\tbackground: var(--color-border);\n}\n\n.cn-files-browser__review-legend {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px 18px;\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 14px;\n\tlist-style: none;\n}\n\n.cn-files-browser__review-legend li {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-files-browser__review-dot {\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 5px;\n}\n\n.cn-files-browser__review-part--success {\n\tbackground: var(--color-success-text, var(--color-success));\n}\n\n.cn-files-browser__review-part--warning {\n\tbackground: var(--color-warning);\n}\n\n.cn-files-browser__review-part--error {\n\tbackground: var(--color-error-text, var(--color-error));\n}\n\n.cn-files-browser__review-part--info {\n\tbackground: var(--color-primary-element);\n}\n\n.cn-files-browser__review-part--default {\n\tbackground: var(--color-border-dark);\n}\n\n.cn-files-browser__row-button {\n\tdisplay: inline-flex;\n\tmargin-inline-end: 8px;\n\tvertical-align: middle;\n}\n\n.cn-files-browser__facets {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px 16px;\n}\n\n.cn-files-browser__facet {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n}\n\n.cn-files-browser__facet-chip {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tmin-height: 32px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-pill);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-files-browser__facet-chip--active {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element-light);\n}\n\n.cn-files-browser__group-heading {\n\tpadding: 12px 8px 4px;\n\ttext-align: start;\n\tfont-weight: 700;\n}\n\n.cn-files-browser__group-count {\n\tmargin-inline-start: 6px;\n\tfont-weight: 400;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__no-match {\n\tpadding: 16px 8px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-actions {\n\twidth: 48px;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__col-actions:has(.cn-files-browser__row-button) {\n\twidth: auto;\n}\n\n/* The row button and the row menu stand side by side on one line, not\n stacked (DqZaakDocumenten: Beoordelen, then the menu, 14px apart).\n @spec openspec/changes/files-row-button-beside-menu/specs/files-row-button-beside-menu/spec.md#requirement-a-files-row-button-stands-beside-the-row-menu */\n.cn-files-browser__col-actions > .cn-files-browser__row-button,\n.cn-files-browser__col-actions > .cn-files-browser__row-menu {\n\tdisplay: inline-flex;\n\tvertical-align: middle;\n}\n\n.cn-files-browser__col-actions > .cn-files-browser__row-button + .cn-files-browser__row-menu {\n\tmargin-inline-start: 14px;\n}\n\n.cn-files-browser__col-name {\n\tmin-width: 0;\n}\n\n.cn-files-browser__name {\n\tdisplay: block;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__name-secondary {\n\tdisplay: block;\n\toverflow: hidden;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__footnote {\n\tmargin: 0;\n\tpadding-top: 12px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__row--linked {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__note {\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: block;\n\tfont-size: var(--font-size-small, 13px);\n}\n\n.cn-files-browser__note-link {\n\tcolor: inherit;\n\ttext-decoration: underline;\n}\n\n.cn-files-browser__row--folder .cn-files-browser__name {\n\tfont-weight: 600;\n}\n\n.cn-files-browser__mime,\n.cn-files-browser__thumb {\n\twidth: 32px;\n\theight: 32px;\n\tdisplay: block;\n}\n\n.cn-files-browser__thumb {\n\tobject-fit: cover;\n\tborder-radius: var(--border-radius, 4px);\n}\n\n.cn-files-browser__new-folder {\n\tpadding: 8px 0;\n}\n\n.hidden-visually {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["CnCellRenderer","CnIcon","CnEmptyContent","t","n","axios"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnFilesBrowser.vue2.js","sources":["../../../../src/components/CnFilesBrowser/CnFilesBrowser.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tclass=\"cn-files-browser\"\n\t\t:class=\"{ 'cn-files-browser--dragging': dragging, 'cn-files-browser--drop-panel': dropOverlay && dropDetailTemplate !== '' }\"\n\t\tdata-testid=\"cn-files-browser\"\n\t\t@dragenter.prevent=\"onDragEnter\"\n\t\t@dragover.prevent=\"onDragOver\"\n\t\t@dragleave.prevent=\"onDragLeave\"\n\t\t@drop.prevent=\"onDrop\">\n\t\t<!-- The drop state, drawn on the browser itself when the host names it\n\t\t (`dropOverlay`): a dashed frame and one centred line over the list,\n\t\t so it is plain where the files go. The overlay is decoration for\n\t\t sighted users; the live region below says the same thing to a\n\t\t screen reader, and the upload button stays the way in for anyone\n\t\t who cannot drag. -->\n\t\t<div v-if=\"dropOverlay && dragging\"\n\t\t\tclass=\"cn-files-browser__drop-overlay\"\n\t\t\taria-hidden=\"true\"\n\t\t\tdata-testid=\"cn-files-browser-drop-overlay\">\n\t\t\t<span class=\"cn-files-browser__drop-icon\"><Upload :size=\"28\" /></span>\n\t\t\t<strong class=\"cn-files-browser__drop-label\">{{ cnTranslate(dropLabel) }}</strong>\n\t\t\t<span v-if=\"dropDetailText\"\n\t\t\t\tclass=\"cn-files-browser__drop-detail\"\n\t\t\t\tdata-testid=\"cn-files-browser-drop-detail\">{{ dropDetailText }}</span>\n\t\t</div>\n\t\t<p v-if=\"dropOverlay\"\n\t\t\tclass=\"hidden-visually\"\n\t\t\taria-live=\"polite\"\n\t\t\tdata-testid=\"cn-files-browser-drop-status\">\n\t\t\t{{ dropStatus }}\n\t\t</p>\n\t\t<!-- The bar: where you are, and what you can add. The crumbs are the\n\t\t Files app's own breadcrumb component; the New menu lists what the\n\t\t Files app and its plugins registered for this folder (a new folder,\n\t\t a template, a file request) beside a plain upload. -->\n\t\t<div class=\"cn-files-browser__bar\">\n\t\t\t<NcBreadcrumbs class=\"cn-files-browser__crumbs\" :class=\"{ 'cn-files-browser__crumbs--at-root': atRoot }\">\n\t\t\t\t<!-- The whole trail from the user's files root, as the Files app\n\t\t\t\t draws it. A crumb above the browser's root links into the Files\n\t\t\t\t app (the browser never leaves its root); the root and everything\n\t\t\t\t beneath it navigate in place. NcBreadcrumbs draws its first\n\t\t\t\t crumb as a home icon and keeps the name for screen readers;\n\t\t\t\t forceIconText puts the name beside the icon. -->\n\t\t\t\t<NcBreadcrumb\n\t\t\t\t\tv-for=\"(crumb, index) in crumbs\"\n\t\t\t\t\t:key=\"crumb.path\"\n\t\t\t\t\t:name=\"crumb.name\"\n\t\t\t\t\t:forceIconText=\"index === 0\"\n\t\t\t\t\t:disableDrop=\"true\"\n\t\t\t\t\t:href=\"crumb.aboveRoot ? filesAppUrl(crumb.path) : undefined\"\n\t\t\t\t\t:target=\"crumb.aboveRoot ? '_blank' : undefined\"\n\t\t\t\t\t:data-above-root=\"crumb.aboveRoot ? 'true' : undefined\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-crumb\"\n\t\t\t\t\t@click=\"crumb.aboveRoot ? undefined : navigate(crumb.path)\" />\n\t\t\t</NcBreadcrumbs>\n\t\t\t<!-- The Columns chooser hides declared columns for this user. It\n\t\t\t cannot add one: it is built by walking the host's declaration,\n\t\t\t so a column the host removed is not listed and cannot be\n\t\t\t ticked back on however the stored preference reads. -->\n\t\t\t<NcActions v-if=\"columnsChooserEnabled\"\n\t\t\t\t:menuName=\"columnsLabel\"\n\t\t\t\t:forceMenu=\"true\"\n\t\t\t\tdata-testid=\"cn-files-browser-columns\">\n\t\t\t\t<NcActionCheckbox\n\t\t\t\t\tv-for=\"column in declaredColumns\"\n\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t:modelValue=\"isColumnVisible(column)\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-column-${column.key}`\"\n\t\t\t\t\t@update:modelValue=\"toggleColumn(column)\">\n\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t</NcActionCheckbox>\n\t\t\t</NcActions>\n\t\t\t<NcActions v-if=\"canChange && newMenu\"\n\t\t\t\t:menuName=\"newLabel\"\n\t\t\t\t:forceMenu=\"true\"\n\t\t\t\t:forceName=\"true\"\n\t\t\t\t:variant=\"uploadButton ? 'secondary' : 'primary'\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-new\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Plus :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t<NcActionButton :closeAfterClick=\"true\" data-testid=\"cn-files-browser-upload\" @click=\"pickFiles\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<Upload :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ uploadLabel }}\n\t\t\t\t</NcActionButton>\n\t\t\t\t<NcActionButton\n\t\t\t\t\tv-for=\"entry in newMenuEntries\"\n\t\t\t\t\t:key=\"entry.id\"\n\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-new-${entry.id}`\"\n\t\t\t\t\t@click=\"runNewEntry(entry)\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcIconSvgWrapper v-if=\"entry.iconSvgInline\" :svg=\"entry.iconSvgInline\" />\n\t\t\t\t\t\t<span v-else-if=\"entry.iconClass\" :class=\"entry.iconClass\" />\n\t\t\t\t\t\t<Plus v-else :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ entry.displayName }}\n\t\t\t\t</NcActionButton>\n\t\t\t\t<!-- The host's own entries, after the Files app's. -->\n\t\t\t\t<NcActionButton\n\t\t\t\t\tv-for=\"action in newActions\"\n\t\t\t\t\t:key=\"`host-${action.id}`\"\n\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t:data-testid=\"`cn-files-browser-new-host-${action.id}`\"\n\t\t\t\t\t@click=\"runHostAction(action, null)\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<CnIcon :name=\"action.icon || 'Plus'\" :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t</NcActionButton>\n\t\t\t</NcActions>\n\t\t\t<!-- The host's own buttons in the bar (\"Vraag een bestand aan een\n\t\t\t partij\", DqZaakDocumenten), dispatched like a New-menu entry with\n\t\t\t the current folder; `#header-actions` adds anything else. -->\n\t\t\t<NcButton v-for=\"action in headerActions\"\n\t\t\t\t:key=\"`header-${action.id}`\"\n\t\t\t\t:variant=\"action.variant === 'primary' ? 'primary' : 'secondary'\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\t:data-testid=\"`cn-files-browser-header-action-${action.id}`\"\n\t\t\t\t@click=\"runHostAction(action, null)\">\n\t\t\t\t<template v-if=\"action.icon\" #icon>\n\t\t\t\t\t<CnIcon :name=\"action.icon\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ hostLabel(action) }}\n\t\t\t</NcButton>\n\t\t\t<!-- New folder as its own button, when the host names it\n\t\t\t (`folderButton`): a bar without the New menu still creates\n\t\t\t folders. -->\n\t\t\t<NcButton v-if=\"folderButton && canChange\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-new-folder-button\"\n\t\t\t\t@click=\"askNewFolder\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<FolderPlusOutline :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ newFolderLabel }}\n\t\t\t</NcButton>\n\t\t\t<!-- @slot header-actions Buttons in the bar, before the upload button. -->\n\t\t\t<slot name=\"header-actions\" />\n\t\t\t<!-- A plain upload as its own button, when the host names it\n\t\t\t (`uploadButton`). It takes the primary place and the New\n\t\t\t menu steps back beside it. -->\n\t\t\t<NcButton v-if=\"uploadButton && canChange\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"folder === null\"\n\t\t\t\tdata-testid=\"cn-files-browser-upload-button\"\n\t\t\t\t@click=\"pickFiles\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<Upload :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ uploadButtonLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- `:ref` (dynamic), not `ref`: a static ref on a vnode with only static\n\t\t bindings is hoisted, and a hoisted vnode has no owner instance to\n\t\t hold the ref, which throws in a production build. -->\n\t\t<input\n\t\t\t:ref=\"fileInputRef\"\n\t\t\ttype=\"file\"\n\t\t\tmultiple\n\t\t\tclass=\"cn-files-browser__file-input\"\n\t\t\t:aria-label=\"uploadLabel\"\n\t\t\t@change=\"onFilesPicked\">\n\n\t\t<ul v-if=\"uploads.length > 0\" class=\"cn-files-browser__uploads\" data-testid=\"cn-files-browser-uploads\">\n\t\t\t<li v-for=\"upload in uploads\" :key=\"upload.key\" class=\"cn-files-browser__upload\">\n\t\t\t\t<span class=\"cn-files-browser__upload-name\">{{ upload.name }}</span>\n\t\t\t\t<NcProgressBar :value=\"upload.progress\" :error=\"upload.error !== ''\" />\n\t\t\t\t<span v-if=\"upload.error\" class=\"cn-files-browser__upload-error\" role=\"alert\">{{ upload.error }}</span>\n\t\t\t</li>\n\t\t</ul>\n\n\t\t<!-- The review summary (`reviewSummary`): how many files are reviewed,\n\t\t a bar in the review tones and a legend with the count per value. -->\n\t\t<div v-if=\"review && review.total > 0 && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__review\"\n\t\t\tdata-testid=\"cn-files-browser-review\">\n\t\t\t<div class=\"cn-files-browser__review-head\">\n\t\t\t\t<strong class=\"cn-files-browser__review-title\">{{ reviewTitle }}</strong>\n\t\t\t\t<span v-if=\"reviewSubtitle\" class=\"cn-files-browser__review-sub\">{{ reviewSubtitle }}</span>\n\t\t\t</div>\n\t\t\t<span class=\"cn-files-browser__review-bar\" role=\"img\" :aria-label=\"reviewTitle\">\n\t\t\t\t<span v-for=\"segment in review.segments\"\n\t\t\t\t\tv-show=\"segment.count > 0 && !isOpenValue(segment.value)\"\n\t\t\t\t\t:key=\"segment.value\"\n\t\t\t\t\t:class=\"`cn-files-browser__review-part cn-files-browser__review-part--${segment.tone}`\"\n\t\t\t\t\t:style=\"{ width: `${segment.share}%` }\" />\n\t\t\t</span>\n\t\t\t<ul class=\"cn-files-browser__review-legend\">\n\t\t\t\t<li v-for=\"segment in review.segments\" :key=\"segment.value\" data-testid=\"cn-files-browser-review-entry\">\n\t\t\t\t\t<span :class=\"`cn-files-browser__review-dot cn-files-browser__review-part--${segment.tone}`\" aria-hidden=\"true\" />\n\t\t\t\t\t{{ hostLabel(segment) }}\n\t\t\t\t\t<strong>{{ segment.count }}</strong>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<!-- The host's filter: per declared column, a chip per value in use\n\t\t with how many files carry it. Chips narrow the list. -->\n\t\t<div v-if=\"facetGroups.length > 0 && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__facets\"\n\t\t\tdata-testid=\"cn-files-browser-facets\">\n\t\t\t<div v-for=\"facet in facetGroups\"\n\t\t\t\t:key=\"facet.key\"\n\t\t\t\tclass=\"cn-files-browser__facet\"\n\t\t\t\trole=\"group\"\n\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Filter by {column}', { column: facet.label })\">\n\t\t\t\t<button v-for=\"option in facet.values\"\n\t\t\t\t\t:key=\"option.value\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-files-browser__facet-chip\"\n\t\t\t\t\t:class=\"{ 'cn-files-browser__facet-chip--active': option.active }\"\n\t\t\t\t\t:aria-pressed=\"option.active ? 'true' : 'false'\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-facet-chip\"\n\t\t\t\t\t@click=\"toggleFacet(facet.key, option.value)\">\n\t\t\t\t\t{{ option.value }}\n\t\t\t\t\t<strong class=\"cn-files-browser__facet-count\">{{ option.count }}</strong>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<NcButton v-if=\"facetActive\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\tdata-testid=\"cn-files-browser-facets-clear\"\n\t\t\t\t@click=\"clearFacets\">\n\t\t\t\t{{ t('nextcloud-vue', 'Clear filters') }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- The host's bulk actions, once something is selected. -->\n\t\t<div v-if=\"bulkEnabled && selectedIds.length > 0\"\n\t\t\tclass=\"cn-files-browser__bulk-bar\"\n\t\t\trole=\"toolbar\"\n\t\t\t:aria-label=\"t('nextcloud-vue', 'Actions for the selected files')\"\n\t\t\tdata-testid=\"cn-files-browser-bulk-bar\">\n\t\t\t<span class=\"cn-files-browser__bulk-count\" aria-live=\"polite\" data-testid=\"cn-files-browser-bulk-count\">\n\t\t\t\t{{ selectionCountText }}\n\t\t\t</span>\n\t\t\t<NcButton v-for=\"action in bulkActions\"\n\t\t\t\t:key=\"action.id\"\n\t\t\t\t:data-testid=\"`cn-files-browser-bulk-action-${action.id}`\"\n\t\t\t\t@click=\"runBulkAction(action)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<CnIcon :name=\"action.icon || 'CheckboxMultipleMarkedOutline'\" :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ hostLabel(action) }}\n\t\t\t</NcButton>\n\t\t\t<NcButton v-if=\"showClearSelection\"\n\t\t\t\tvariant=\"tertiary\"\n\t\t\t\tdata-testid=\"cn-files-browser-bulk-clear\"\n\t\t\t\t@click=\"clearSelection\">\n\t\t\t\t{{ t('nextcloud-vue', 'Clear selection') }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<NcLoadingIcon v-if=\"loading\" :size=\"32\" class=\"cn-files-browser__loading\" />\n\n\t\t<CnEmptyContent v-else-if=\"error !== ''\"\n\t\t\terror\n\t\t\t:name=\"error\"\n\t\t\tclass=\"cn-files-browser__state\">\n\t\t\t<template #icon>\n\t\t\t\t<AlertCircleOutline :size=\"44\" />\n\t\t\t</template>\n\t\t\t<template #action>\n\t\t\t\t<NcButton @click=\"refresh\">\n\t\t\t\t\t{{ retryLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</CnEmptyContent>\n\n\t\t<CnEmptyContent\n\t\t\tv-else-if=\"sorted.length === 0 && linkedItems.length === 0\"\n\t\t\t:name=\"emptyLabel\"\n\t\t\t:description=\"canChange ? emptyHint : ''\"\n\t\t\tclass=\"cn-files-browser__state\">\n\t\t\t<template #icon>\n\t\t\t\t<FolderOutline :size=\"44\" />\n\t\t\t</template>\n\t\t</CnEmptyContent>\n\n\t\t<!-- The table. Its rows are @nextcloud/files nodes read over DAV, and\n\t\t each row's menu is the list of actions the Files app registered on\n\t\t this page, offered under the same names and icons the Files app\n\t\t uses. What cannot run away from the Files page (the details\n\t\t sidebar) is left out, and Show in Files covers it. -->\n\t\t<div v-else\n\t\t\tclass=\"cn-files-browser__body\"\n\t\t\t:class=\"{ 'cn-files-browser__body--with-side': sideNode !== null && !sideInPage }\">\n\t\t\t<table class=\"cn-files-browser__table\" data-testid=\"cn-files-browser-table\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th v-if=\"bulkEnabled\" class=\"cn-files-browser__col-select\" scope=\"col\">\n\t\t\t\t\t\t\t<input type=\"checkbox\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__select\"\n\t\t\t\t\t\t\t\t:checked=\"allSelected\"\n\t\t\t\t\t\t\t\t:indeterminate.prop=\"someSelected && !allSelected\"\n\t\t\t\t\t\t\t\t:disabled=\"selectableIds.length === 0\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Select all files')\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-select-all\"\n\t\t\t\t\t\t\t\t@change=\"toggleAll($event.target.checked)\">\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th class=\"cn-files-browser__col-icon\" scope=\"col\">\n\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ t('nextcloud-vue', 'Type') }}</span>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\"\n\t\t\t\t\t\t\t:aria-sort=\"ariaSort(sortTokenOf(column))\"\n\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-header-${column.key}`\">\n\t\t\t\t\t\t\t<button v-if=\"column.sortable !== false\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__sort\"\n\t\t\t\t\t\t\t\t@click=\"sortBy(sortTokenOf(column))\">\n\t\t\t\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t\t\t\t\t<component :is=\"sortIcon(sortTokenOf(column))\" v-if=\"sortKey === sortTokenOf(column)\" :size=\"16\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<template v-else>\n\t\t\t\t\t\t\t\t{{ columnLabel(column) }}\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t\t<th class=\"cn-files-browser__col-actions\" scope=\"col\" :style=\"actionsColumnStyle\">\n\t\t\t\t\t\t\t<span class=\"hidden-visually\">{{ t('nextcloud-vue', 'Actions') }}</span>\n\t\t\t\t\t\t</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t<!-- A heading row per group when the host groups on a column; the\n\t\t\t\t destructured entry is either a group or a node. -->\n\t\t\t\t\t<template v-for=\"{ key, group, node } in displayRows\" :key=\"key\">\n\t\t\t\t\t\t<tr v-if=\"group\"\n\t\t\t\t\t\t\tclass=\"cn-files-browser__group\"\n\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-group\">\n\t\t\t\t\t\t\t<th :colspan=\"columnCount\" scope=\"rowgroup\" class=\"cn-files-browser__group-heading\">\n\t\t\t\t\t\t\t\t{{ group.label }}\n\t\t\t\t\t\t\t\t<span class=\"cn-files-browser__group-count\">{{ group.count }}</span>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t:key=\"key\"\n\t\t\t\t\t\t\tclass=\"cn-files-browser__row\"\n\t\t\t\t\t\t\t:class=\"{ 'cn-files-browser__row--folder': isFolder(node) }\"\n\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-row\"\n\t\t\t\t\t\t\t:data-name=\"node.basename\"\n\t\t\t\t\t\t\t@click=\"onRowClick(node, $event)\"\n\t\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t\t@auxclick=\"onRowAuxClick(node, $event)\">\n\t\t\t\t\t\t\t<td v-if=\"bulkEnabled\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__col-select\"\n\t\t\t\t\t\t\t\t@click.stop\n\t\t\t\t\t\t\t\t@auxclick.stop>\n\t\t\t\t\t\t\t\t<input v-if=\"!isFolder(node)\"\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__select\"\n\t\t\t\t\t\t\t\t\t:checked=\"isSelected(node)\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Select {name}', { name: node.basename })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-select\"\n\t\t\t\t\t\t\t\t\t@change=\"toggleSelected(node, $event.target.checked)\">\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"cn-files-browser__col-icon\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tv-if=\"previewUrlFor(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__thumb\"\n\t\t\t\t\t\t\t\t\t:src=\"previewUrlFor(node)\"\n\t\t\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t\t\t\tloading=\"lazy\"\n\t\t\t\t\t\t\t\t\t@error=\"onPreviewError(node)\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tv-else-if=\"mimeIconFor(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__mime\"\n\t\t\t\t\t\t\t\t\t:src=\"mimeIconFor(node)\"\n\t\t\t\t\t\t\t\t\talt=\"\">\n\t\t\t\t\t\t\t\t<FolderOutline v-else-if=\"isFolder(node)\" :size=\"32\" />\n\t\t\t\t\t\t\t\t<FileOutline v-else :size=\"32\" />\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\"\n\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-cell-${column.key}`\">\n\t\t\t\t\t\t\t\t<span v-if=\"column.key === 'name'\" class=\"cn-files-browser__name\">{{ node.basename }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"column.key === 'name' && nameSecondaryOf(node)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__name-secondary\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-name-secondary\">{{ nameSecondaryOf(node) }}</span>\n\t\t\t\t\t\t\t\t<template v-else-if=\"column.key === 'size'\">\n\t\t\t\t\t\t\t\t\t{{ isFolder(node) ? '' : formatSize(node.size) }}\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<NcDateTime v-else-if=\"column.key === 'modified'\" :timestamp=\"node.mtime\" :ignoreSeconds=\"true\" />\n\t\t\t\t\t\t\t\t<!-- Everything the host declared renders through the same\n\t\t\t\t\t\t\t cell renderer the tables use, so a `formatter` means\n\t\t\t\t\t\t\t here what it means there. -->\n\t\t\t\t\t\t\t\t<CnCellRenderer v-else\n\t\t\t\t\t\t\t\t\t:class=\"column.widget !== 'badge' && toneOf(column, node) ? `cn-files-browser__tone cn-files-browser__tone--${toneOf(column, node)}` : null\"\n\t\t\t\t\t\t\t\t\t:value=\"cellValue(column, node)\"\n\t\t\t\t\t\t\t\t\t:formatter=\"column.formatter || null\"\n\t\t\t\t\t\t\t\t\t:formatterOptions=\"column.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t:widget=\"column.widget || null\"\n\t\t\t\t\t\t\t\t\t:widgetProps=\"cellWidgetProps(column, node)\"\n\t\t\t\t\t\t\t\t\t:row=\"node\" />\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"cn-files-browser__col-actions\" @click.stop @auxclick.stop>\n\t\t\t\t\t\t\t\t<!-- The host's one visible button on a file (\"Beoordelen\"),\n\t\t\t\t\t\t\t\t primary while the row still asks for it. -->\n\t\t\t\t\t\t\t\t<NcButton v-if=\"rowButton && !isFolder(node) && hostActionApplies(rowButton, node)\"\n\t\t\t\t\t\t\t\t\t:variant=\"rowButtonPrimary(node) ? 'primary' : 'secondary'\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__row-button\"\n\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', '{action}: {name}', { action: hostLabel(rowButton), name: node.basename })\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-row-button\"\n\t\t\t\t\t\t\t\t\t@click=\"runHostAction(rowButton, node)\">\n\t\t\t\t\t\t\t\t\t{{ hostLabel(rowButton) }}\n\t\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t\t\t<NcActions class=\"cn-files-browser__row-menu\" :forceMenu=\"true\" :ariaLabel=\"t('nextcloud-vue', 'Actions for {name}', { name: node.basename })\">\n\t\t\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\t\t\tv-for=\"action in actionsFor(node)\"\n\t\t\t\t\t\t\t\t\t\t:key=\"action.id\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-action-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t@click=\"run(action, node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper :svg=\"iconOf(action, node)\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ labelOf(action, node) }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<!-- The host's own actions on a file (never on a folder): declared\n\t\t\t\t\t\t\t\t in its manifest, dispatched through the page's action runner\n\t\t\t\t\t\t\t\t with the node's file id, name and path merged in. -->\n\t\t\t\t\t\t\t\t\t<template v-if=\"!isFolder(node)\">\n\t\t\t\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\t\t\t\tv-for=\"action in hostActionsFor(node)\"\n\t\t\t\t\t\t\t\t\t\t\t:key=\"`host-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-host-action-${action.id}`\"\n\t\t\t\t\t\t\t\t\t\t\t@click=\"runHostAction(action, node)\">\n\t\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t\t<CnIcon :name=\"action.icon || 'FileDocumentEditOutline'\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t<NcActionSeparator v-if=\"actionsFor(node).length > 0 || (!isFolder(node) && hostActionsFor(node).length > 0)\" />\n\t\t\t\t\t\t\t\t\t<!-- The Files app's own rename is its list's inline input,\n\t\t\t\t\t\t\t\t which is not here; this one is a dialog over a DAV move. -->\n\t\t\t\t\t\t\t\t\t<!-- With a `source`, the Files app's actions (which act over\n\t\t\t\t\t\t\t\t WebDAV) are not offered; download and delete go through\n\t\t\t\t\t\t\t\t the source instead. -->\n\t\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\t\tv-if=\"source && sourceDownloadUrl(node)\"\n\t\t\t\t\t\t\t\t\t\t:href=\"sourceDownloadUrl(node)\"\n\t\t\t\t\t\t\t\t\t\t:download=\"node.basename\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-download\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<Download :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ downloadLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t\t<NcActionButton v-if=\"source && canChange\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-delete\"\n\t\t\t\t\t\t\t\t\t\t@click=\"askRemove(node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<TrashCanOutline :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ deleteLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<NcActionButton v-if=\"canChange\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-action-rename\"\n\t\t\t\t\t\t\t\t\t\t@click=\"askRename(node)\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<Pencil :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ renameLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\t\tv-if=\"node.fileid && !source\"\n\t\t\t\t\t\t\t\t\t\t:href=\"permalink(node)\"\n\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\">\n\t\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t{{ showInFilesLabel }}\n\t\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t</NcActions>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</template>\n\t\t\t\t\t<tr v-if=\"facetActive && filteredFiles.length === 0\" class=\"cn-files-browser__no-match-row\">\n\t\t\t\t\t\t<td :colspan=\"columnCount\" class=\"cn-files-browser__no-match\" data-testid=\"cn-files-browser-no-match\">\n\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'No files match the filter.') }}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<!-- Rows that are not nodes of this folder: documents the host\n\t\t\t\t joined from elsewhere (another object's folder). Open and\n\t\t\t\t download only; nothing here can change the file. -->\n\t\t\t\t\t<tr\n\t\t\t\t\t\tv-for=\"item in linkedItems\"\n\t\t\t\t\t\t:key=\"`linked-${item.id}`\"\n\t\t\t\t\t\tclass=\"cn-files-browser__row cn-files-browser__row--linked\"\n\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-row\"\n\t\t\t\t\t\t:data-name=\"item.name\"\n\t\t\t\t\t\t@click=\"openLinked(item)\"\n\t\t\t\t\t\t@mousedown=\"preventMiddleClickAutoscroll\"\n\t\t\t\t\t\t@auxclick=\"onLinkedAuxClick(item, $event)\">\n\t\t\t\t\t\t<td v-if=\"bulkEnabled\" class=\"cn-files-browser__col-select\" />\n\t\t\t\t\t\t<td class=\"cn-files-browser__col-icon\">\n\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\tv-if=\"mimeIconFor({ mime: item.mime })\"\n\t\t\t\t\t\t\t\tclass=\"cn-files-browser__mime\"\n\t\t\t\t\t\t\t\t:src=\"mimeIconFor({ mime: item.mime })\"\n\t\t\t\t\t\t\t\talt=\"\">\n\t\t\t\t\t\t\t<FileOutline v-else :size=\"32\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<!-- A linked item is not a node of this folder, so it can only\n\t\t\t\t\t answer for name, size and modified. It still walks the same\n\t\t\t\t\t column list, or a declared column set would shift every\n\t\t\t\t\t linked row one cell out of line with its header. -->\n\t\t\t\t\t\t<td v-for=\"column in renderedColumns\"\n\t\t\t\t\t\t\t:key=\"column.key\"\n\t\t\t\t\t\t\t:class=\"`cn-files-browser__col-${column.key}`\">\n\t\t\t\t\t\t\t<template v-if=\"column.key === 'name'\">\n\t\t\t\t\t\t\t\t<span class=\"cn-files-browser__name\">{{ item.name }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"item.note\" class=\"cn-files-browser__note\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\tv-if=\"item.noteHref\"\n\t\t\t\t\t\t\t\t\t\t:href=\"item.noteHref\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-files-browser__note-link\"\n\t\t\t\t\t\t\t\t\t\t@click.stop>{{ item.note }}</a>\n\t\t\t\t\t\t\t\t\t<template v-else>{{ item.note }}</template>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else-if=\"column.key === 'size'\">\n\t\t\t\t\t\t\t\t{{ item.size ? formatSize(item.size) : '' }}\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<NcDateTime v-else-if=\"column.key === 'modified' && item.mtime\" :timestamp=\"item.mtime\" :ignoreSeconds=\"true\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"cn-files-browser__col-actions\" @click.stop @auxclick.stop>\n\t\t\t\t\t\t\t<NcActions class=\"cn-files-browser__row-menu\" :forceMenu=\"true\" :ariaLabel=\"t('nextcloud-vue', 'Actions for {name}', { name: item.name })\">\n\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\tv-if=\"item.href\"\n\t\t\t\t\t\t\t\t\t:href=\"item.href\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-open\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<OpenInNew :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ openLinkedLabel }}\n\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\t\tv-if=\"item.downloadHref\"\n\t\t\t\t\t\t\t\t\t:href=\"item.downloadHref\"\n\t\t\t\t\t\t\t\t\t:download=\"item.name\"\n\t\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"cn-files-browser-linked-download\">\n\t\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t\t<Download :size=\"20\" />\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t{{ downloadLabel }}\n\t\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t</NcActions>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<!-- `sideCards`: cards about the last selected file, beside the list,\n\t\t\t or in the detail page's side column (`sideCardsPlacement`). -->\n\t\t\t<Teleport v-if=\"sideNode !== null\"\n\t\t\t\t:to=\"pageSideTarget\"\n\t\t\t\t:disabled=\"!sideInPage\"\n\t\t\t\tdefer>\n\t\t\t\t<aside\n\t\t\t\t\tclass=\"cn-files-browser__side\"\n\t\t\t\t\t:class=\"{ 'cn-files-browser__side--in-page': sideInPage }\"\n\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'About {name}', { name: sideNode.basename })\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-side\">\n\t\t\t\t\t<section v-for=\"card in sideCardsFor(sideNode)\"\n\t\t\t\t\t\t:key=\"card.id\"\n\t\t\t\t\t\tclass=\"cn-files-browser__side-card\"\n\t\t\t\t\t\t:data-testid=\"`cn-files-browser-side-card-${card.id}`\">\n\t\t\t\t\t\t<h3 class=\"cn-files-browser__side-title\">\n\t\t\t\t\t\t\t{{ card.title }}\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<dl v-if=\"card.fields.length > 0\" class=\"cn-files-browser__side-facts\">\n\t\t\t\t\t\t\t<template v-for=\"field in card.fields\" :key=\"field.key\">\n\t\t\t\t\t\t\t\t<dt>{{ field.label }}</dt>\n\t\t\t\t\t\t\t\t<dd :class=\"field.tone ? `cn-files-browser__tone cn-files-browser__tone--${field.tone}` : ''\">\n\t\t\t\t\t\t\t\t\t<CnCellRenderer\n\t\t\t\t\t\t\t\t\t\t:value=\"field.value\"\n\t\t\t\t\t\t\t\t\t\t:formatter=\"field.formatter || null\"\n\t\t\t\t\t\t\t\t\t\t:formatterOptions=\"field.formatterOptions || null\"\n\t\t\t\t\t\t\t\t\t\t:row=\"sideNode\" />\n\t\t\t\t\t\t\t\t</dd>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</dl>\n\t\t\t\t\t\t<div v-if=\"card.actions.length > 0\" class=\"cn-files-browser__side-actions\">\n\t\t\t\t\t\t\t<NcButton v-for=\"action in card.actions\"\n\t\t\t\t\t\t\t\t:key=\"action.id\"\n\t\t\t\t\t\t\t\t:data-testid=\"`cn-files-browser-side-action-${action.id}`\"\n\t\t\t\t\t\t\t\t@click=\"runHostAction(action, sideNode)\">\n\t\t\t\t\t\t\t\t<template v-if=\"action.icon\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon :name=\"action.icon\" :size=\"20\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ hostLabel(action) }}\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</section>\n\t\t\t\t</aside>\n\t\t\t</Teleport>\n\t\t</div>\n\n\t\t<p v-if=\"dropHint && canChange && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__drop-hint\"\n\t\t\tdata-testid=\"cn-files-browser-drop-hint\">\n\t\t\t<Upload :size=\"16\" />\n\t\t\t{{ dropHintLabel }}\n\t\t</p>\n\t\t<!-- The host's own line under the list (\"Elk bestand wordt bij het\n\t\t uploaden op virussen gescand\", DqDocumentenBeheer), apart from\n\t\t the drop hint. -->\n\t\t<p v-if=\"footnote && !loading && error === ''\"\n\t\t\tclass=\"cn-files-browser__footnote\"\n\t\t\tdata-testid=\"cn-files-browser-footnote\">\n\t\t\t{{ cnTranslate(footnote) }}\n\t\t</p>\n\n\t\t<NcDialog\n\t\t\tv-if=\"renaming !== null\"\n\t\t\t:name=\"renameLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-rename\"\n\t\t\t@closing=\"renaming = null\">\n\t\t\t<form class=\"cn-files-browser__new-folder\" @submit.prevent=\"rename\">\n\t\t\t\t<NcTextField\n\t\t\t\t\tv-model=\"renameName\"\n\t\t\t\t\t:label=\"t('nextcloud-vue', 'New name')\"\n\t\t\t\t\t:error=\"renameError !== ''\"\n\t\t\t\t\t:helperText=\"renameError\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-rename-name\" />\n\t\t\t</form>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"renaming = null\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\t:disabled=\"renameName.trim() === '' || renameName.trim() === renaming.basename\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-rename-confirm\"\n\t\t\t\t\t@click=\"rename\">\n\t\t\t\t\t{{ renameLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\n\t\t<NcDialog\n\t\t\tv-if=\"removing !== null\"\n\t\t\t:name=\"deleteLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-delete\"\n\t\t\t@closing=\"removing = null\">\n\t\t\t<p>{{ t('nextcloud-vue', 'Delete {name}? This cannot be undone here.', { name: removing.basename }) }}</p>\n\t\t\t<p v-if=\"removeError\" class=\"cn-files-browser__upload-error\" role=\"alert\">\n\t\t\t\t{{ removeError }}\n\t\t\t</p>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"removing = null\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"error\" data-testid=\"cn-files-browser-delete-confirm\" @click=\"remove\">\n\t\t\t\t\t{{ deleteLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\n\t\t<NcDialog\n\t\t\tv-if=\"newFolderOpen\"\n\t\t\t:name=\"newFolderLabel\"\n\t\t\tsize=\"small\"\n\t\t\tdata-testid=\"cn-files-browser-new-folder\"\n\t\t\t@closing=\"newFolderOpen = false\">\n\t\t\t<form class=\"cn-files-browser__new-folder\" @submit.prevent=\"createFolder\">\n\t\t\t\t<NcTextField\n\t\t\t\t\tv-model=\"newFolderName\"\n\t\t\t\t\t:label=\"t('nextcloud-vue', 'Folder name')\"\n\t\t\t\t\t:error=\"newFolderError !== ''\"\n\t\t\t\t\t:helperText=\"newFolderError\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-new-folder-name\" />\n\t\t\t</form>\n\t\t\t<template #actions>\n\t\t\t\t<NcButton @click=\"newFolderOpen = false\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton variant=\"primary\"\n\t\t\t\t\t:disabled=\"newFolderName.trim() === ''\"\n\t\t\t\t\tdata-testid=\"cn-files-browser-new-folder-create\"\n\t\t\t\t\t@click=\"createFolder\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Create') }}\n\t\t\t\t</NcButton>\n\t\t\t</template>\n\t\t</NcDialog>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\n/**\n * CnFilesBrowser — a folder of Nextcloud files, on any page, built from the\n * Files app's own primitives rather than a copy of its screen.\n *\n * WHAT IS BORROWED, AND FROM WHERE.\n *\n * - The rows are `@nextcloud/files` nodes read over WebDAV with the same\n * PROPFIND the Files app sends, so a node here carries what a node there\n * carries: id, mime, size, mtime, permissions, attributes.\n * - Each row's menu is `getFileActions()`: the actions the Files app and its\n * plugins registered on this page (download, delete, rename, favourite, move\n * and copy, sharing status, tags, lock, open in Files…). They are run with\n * the same context the Files app hands them, so a plugin's action does what\n * it does in the Files app. The host page has to load those scripts: it\n * dispatches `LoadAdditionalScriptsEvent` and asks for the Files app's `init`\n * script server-side. On a page that did not, the menu holds only Show in\n * Files, which is the honest fallback.\n * - The New menu is `getNewFileMenuEntries(folder)`: new folder, a template,\n * a file request, whatever the plugins offer for this folder, beside a plain\n * upload that PUTs over DAV.\n * - The crumbs are NcBreadcrumbs, the icons are the theme's own mime icons\n * through `OC.MimeType`, and image previews come from the core preview\n * endpoint.\n *\n * WHAT IS NOT. The Files app's list itself (its column filters, selection bar\n * and inline rename) is a Vue app bound to the Files router and its own stores,\n * and so is its details sidebar on Nextcloud 34. Neither can be mounted here.\n * The actions that need them are left out of the menu by name\n * (`ACTIONS_NEEDING_THE_FILES_PAGE`), and Show in Files opens the Files app on\n * the file for the rest.\n *\n * THE REGISTRY IS VERSIONED. `@nextcloud/files` keeps its registries under\n * `window._nc_files_scope.v4_0`; a page's plugins register into the copy the\n * server ships, and this component reads through its own bundled copy. Both\n * have to be the same major, which is why this library depends on 4.x: a 3.x\n * copy read `window._nc_fileactions`, which the server's plugins never write,\n * and saw nothing while the page held thirty actions.\n */\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { FileType, formatFileSize, getFileActions, getNewFileMenuEntries, sortNodes, View } from '@nextcloud/files'\nimport { getClient, getDefaultPropfind, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { NcActionButton, NcActionCheckbox, NcActionLink, NcActions, NcActionSeparator, NcBreadcrumb, NcBreadcrumbs, NcButton, NcDateTime, NcDialog, NcIconSvgWrapper, NcLoadingIcon, NcProgressBar, NcTextField } from '@nextcloud/vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Download from 'vue-material-design-icons/Download.vue'\nimport FileOutline from 'vue-material-design-icons/FileOutline.vue'\nimport FolderOutline from 'vue-material-design-icons/FolderOutline.vue'\nimport FolderPlusOutline from 'vue-material-design-icons/FolderPlusOutline.vue'\nimport OpenInNew from 'vue-material-design-icons/OpenInNew.vue'\nimport Pencil from 'vue-material-design-icons/Pencil.vue'\nimport Plus from 'vue-material-design-icons/Plus.vue'\nimport TrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue'\nimport Upload from 'vue-material-design-icons/Upload.vue'\nimport CnCellRenderer from '../CnCellRenderer/CnCellRenderer.vue'\nimport CnEmptyContent from '../CnEmptyContent/CnEmptyContent.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\nimport { readUserPreference, writeUserPreference } from '../../composables/useUserPreferences.js'\nimport { dispatchAction } from '../../utils/actionsDispatcher.js'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { isNewTabClick, isRowMiddleClick, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'\nimport { ACTIONS_NEEDING_THE_FILES_PAGE, crumbsFor, hostActionApplies, joinPath } from './filesBrowser.js'\nimport {\n\tattributePropertiesFor,\n\tfacetCounts,\n\tfileColumnValue,\n\tgroupNodes,\n\tnodeMatchesFacets,\n\tnormaliseFileColumns,\n\tsortNodesByColumn,\n\tvisibleFileColumns,\n} from './filesBrowserColumns.js'\nimport { reviewSummary } from './filesReview.js'\n\nlet uploadSeq = 0\n\n/** A folder glyph, the icon the Files app's View constructor requires. */\nconst VIEW_ICON = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\"/></svg>'\n\n// Event-bus channels that mean the open folder may have changed: the page's\n// Refresh signal, and the node events the Files app's actions and uploader emit.\nconst FOLDER_CHANGED_CHANNELS = ['cn:page:refresh', 'files:node:created', 'files:node:deleted', 'files:node:updated', 'files:node:moved']\n\nconst FOLDER_CHANGED_DEBOUNCE_MS = 300\n\nexport default {\n\tname: 'CnFilesBrowser',\n\n\tcomponents: {\n\t\tAlertCircleOutline,\n\t\tCnCellRenderer,\n\t\tCnIcon,\n\t\tDownload,\n\t\tFileOutline,\n\t\tFolderOutline,\n\t\tFolderPlusOutline,\n\t\tNcActionButton,\n\t\tNcActionCheckbox,\n\t\tNcActionLink,\n\t\tNcActionSeparator,\n\t\tNcActions,\n\t\tNcBreadcrumb,\n\t\tNcBreadcrumbs,\n\t\tNcButton,\n\t\tNcDateTime,\n\t\tNcDialog,\n\t\tCnEmptyContent,\n\t\tNcIconSvgWrapper,\n\t\tNcLoadingIcon,\n\t\tNcProgressBar,\n\t\tNcTextField,\n\t\tOpenInNew,\n\t\tPencil,\n\t\tPlus,\n\t\tTrashCanOutline,\n\t\tUpload,\n\t},\n\n\tinject: {\n\t\t// The page's pre-bound action runner (CnPageRenderer provides it);\n\t\t// absent outside a page tree, in which case the bare dispatcher runs.\n\t\tcnDispatchAction: { default: null },\n\t\t// The host app's translate function (CnAppRoot provides it). A row\n\t\t// action or column the manifest declares is authored in English as\n\t\t// the catalogue key, and read through this in the user's language.\n\t\tcnTranslate: { default: () => (key) => key },\n\t\t// The detail page's side column (CnDetailPage), for side cards placed there.\n\t\tcnDetailSideColumn: { default: null },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * Where the folder is read from and written to. Null (the default)\n\t\t * is WebDAV under the signed-in person's files root, with the Files\n\t\t * app's own actions and New menu. An object from\n\t\t * `createOpenRegisterSource()` reads one OpenRegister object's folder\n\t\t * through OpenRegister's files API instead, under the object's access\n\t\t * rule: `rootPath` is then `/`, the Files app's actions and New menu\n\t\t * are not offered (they act over WebDAV), and upload, new folder,\n\t\t * rename and delete appear only when the listing says the person may\n\t\t * change the folder.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tsource: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label of the delete action and its dialog, with a `source`. */\n\t\tdeleteLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Delete'),\n\t\t},\n\n\t\t/**\n\t\t * The host's own actions on each file row, declared the way a\n\t\t * manifest declares any action (`open-modal`, `handler`, ...), and\n\t\t * dispatched through the page's action runner with the node's\n\t\t * `fileId`, `fileName` and `path` merged into an `open-modal` action's\n\t\t * props (or appended as the node to a `handler` action's args). Folders\n\t\t * get none. `icon` is an MDI icon name. `visibleIf` offers the action\n\t\t * only on some files: `extension` (a list, no case) and `mime` (a list;\n\t\t * `image/` or `image/*` names the family), each that is named must hold.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array, visibleIf?: {extension?: string[], mime?: string[]}}>}\n\t\t */\n\t\trowActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own entries in the New menu, after the ones the Files\n\t\t * app and its plugins register. Each is dispatched like a row action\n\t\t * (`type: 'open-modal' | 'handler' | …`) through the page's\n\t\t * `cnDispatchAction`, carrying the current folder rather than a row,\n\t\t * so a host can offer \"new from template\" or \"request a file from a\n\t\t * party\" here.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\tnewActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own buttons in the bar, before the upload button (\"Vraag\n\t\t * een bestand aan een partij\", DqZaakDocumenten). Each is dispatched\n\t\t * like a New-menu entry, with the current folder; `variant:\n\t\t * 'primary'` draws it as the primary button.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, variant?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\theaderActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * One visible button on every file row (\"Beoordelen\"), dispatched like a\n\t\t * row action. `primaryWhen: { key, values }` draws it as the primary\n\t\t * button while the row-data field `key` holds one of `values` (a file\n\t\t * still to review), and secondary otherwise. `visibleIf` works as on a\n\t\t * row action.\n\t\t *\n\t\t * @type {{id: string, label: string, type?: string, target?: string, props?: object, handler?: string, args?: Array, primaryWhen?: {key: string, values: Array<string>}, visibleIf?: object}|null}\n\t\t */\n\t\trowButton: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * A review summary above the list (DqZaakDocumenten \"4 van 7\n\t\t * beoordeeld\"): `{ key, open, values: [{ value, label?, tone? }], title?,\n\t\t * subtitle? }`. `key` is the row-data field with the review state, `open`\n\t\t * the value (or values) of a file still to review; a file without a\n\t\t * listed value counts as open. `tone` is `success`, `warning`, `error`,\n\t\t * `info` or `default`. `title` and `subtitle` take `{done}`, `{total}` and\n\t\t * `{open}`, through the host's translate; they default to the library's\n\t\t * \"{done} of {total} reviewed\" and \"{open} still to review\".\n\t\t *\n\t\t * @type {{key: string, open?: string|Array<string>, values: Array<{value: string, label?: string, tone?: string}>, title?: string, subtitle?: string}|null}\n\t\t */\n\t\treviewSummary: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Rows that are not nodes of this folder: files the host joined from\n\t\t * another object's folder. Rendered after the folder's own rows with\n\t\t * open and download only. `note` (and its optional `noteHref`) says\n\t\t * where the file lives.\n\t\t *\n\t\t * @type {Array<{id: string|number, name: string, mime?: string, size?: number, mtime?: Date|number, href?: string, downloadHref?: string, note?: string, noteHref?: string}>}\n\t\t */\n\t\tlinkedItems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Label of a linked row's open action.\n\t\t */\n\t\topenLinkedLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Open'),\n\t\t},\n\n\t\t/**\n\t\t * Label of a linked row's download action.\n\t\t */\n\t\tdownloadLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Download'),\n\t\t},\n\n\t\t/**\n\t\t * The folder this browser is rooted at, relative to the current user's\n\t\t * files root (`/Open Registers/Cases/<uuid>`). The browser never\n\t\t * navigates above it. Resolve it with `resolveObjectFolder()` for an\n\t\t * OpenRegister object.\n\t\t */\n\t\trootPath: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/**\n\t\t * What the root crumb reads. Null shows the folder's own name, which\n\t\t * is what the Files app shows; pass a label when the folder on disk is\n\t\t * a uuid and the host knows a better name.\n\t\t */\n\t\trootLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label of the New menu. */\n\t\tnewLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'New'),\n\t\t},\n\n\t\t/** Label of the upload entry in the New menu. */\n\t\tuploadLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Upload files'),\n\t\t},\n\n\t\t/** Label of the new-folder entry and its dialog. */\n\t\tnewFolderLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'New folder'),\n\t\t},\n\n\t\t/** Label of the rename action and its dialog. */\n\t\trenameLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Rename'),\n\t\t},\n\n\t\t/** Label of the link that opens the file in the Files app. */\n\t\tshowInFilesLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Show in Files'),\n\t\t},\n\n\t\t/**\n\t\t * Show a primary upload button beside the New menu, which then steps\n\t\t * back to a secondary button. Off (the default) keeps the upload\n\t\t * inside the New menu only.\n\t\t */\n\t\tuploadButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Whether the bar has the New menu (upload, new folder, the Files\n\t\t * app's entries and `newActions`). `false` leaves it out, so the bar\n\t\t * holds the host's `headerActions` buttons and, with `uploadButton`,\n\t\t * the upload button (DqZaakDocumenten).\n\t\t *\n\t\t * @spec openspec/changes/files-browser-toolbar-actions/specs/files-browser/spec.md#requirement-the-host-chooses-whether-the-bar-has-a-new-menu\n\t\t */\n\t\tnewMenu: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Show New folder as a button in the bar, before the host's buttons.\n\t\t * With `newMenu: false` it keeps folder creation in reach.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-toolbar-actions/specs/files-browser/spec.md#requirement-the-host-can-put-new-folder-in-the-bar-as-a-button\n\t\t */\n\t\tfolderButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Label of the upload button `uploadButton` shows. */\n\t\tuploadButtonLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Add files'),\n\t\t},\n\n\t\t/**\n\t\t * Draw the drop state over the browser while files are dragged onto\n\t\t * it (a dashed frame and `dropLabel`, centred) and announce it to\n\t\t * screen readers. Off (the default) keeps the plain dashed outline and\n\t\t * announces nothing.\n\t\t */\n\t\tdropOverlay: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The line `dropOverlay` draws and announces, through the host translate. */\n\t\tdropLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Drop to add'),\n\t\t},\n\n\t\t/**\n\t\t * A second line under `dropLabel` in the drop state, through the host\n\t\t * translate: where the files go (\"{count} bestanden komen bij zaak\n\t\t * 2026-0082, als nog te beoordelen document.\"). `{count}` is the number\n\t\t * of files dragged when the browser can tell, and the line is left out\n\t\t * when it cannot. The overlay then also fills the panel.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-panel/specs/files-browser/spec.md#requirement-the-drop-state-fills-the-panel-and-says-where-the-files-go\n\t\t */\n\t\tdropDetail: {\n\t\t\ttype: [String, Array],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Named values filled into `dropDetail` as `{name}`, such as the case\n\t\t * number (`{ \"case\": \"@object.identifier\" }` in a detail page's props).\n\t\t * While a value is unknown the line is left out.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t */\n\t\tdropDetailValues: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Show a line under the list saying files can be dropped on it. */\n\t\tdropHint: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * A line of the host's own under the list, apart from the drop hint\n\t\t * (\"Elk bestand wordt bij het uploaden op virussen gescand en krijgt een\n\t\t * controlegetal\", DqDocumentenBeheer). Translated with the host's\n\t\t * catalogue.\n\t\t */\n\t\tfootnote: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A second line under each file's name (DqDocumentenBeheer \"Inwoner ·\n\t\t * 4 okt\", DqZaakDocumenten \"PDF · 1,2 MB · 14 januari 2026\"): a field\n\t\t * template read from the file's row data, plus `name`, `modified` (the\n\t\t * change date), `owner` (the owner's display name), `size` (formatted)\n\t\t * and `type` (\"PDF\", \"Word\", \"Email\", else the extension), e.g.\n\t\t * `\"{type} · {size} · {modified|date}\"`. A line with an empty\n\t\t * value is left out. Translated with the host's catalogue first.\n\t\t */\n\t\tnameSecondary: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The second line as a list of fields joined with \" · \", a field\n\t\t * without a value left out: the `nameSecondary` tokens without their\n\t\t * braces (`[\"type\", \"size\", \"modified|date\"]`, a row-data field such as\n\t\t * `\"senderName\"`). Or a list of variants `{ when, fields }`: the first\n\t\t * whose `when` is `true`, or that has no `when`, is used (a case type\n\t\t * flag read through `@context`). Takes precedence over `nameSecondary`.\n\t\t *\n\t\t * @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields\n\t\t */\n\t\tsecondLine: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The line `dropHint` shows. */\n\t\tdropHintLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Or drag files onto this list.'),\n\t\t},\n\n\t\t/** Title of the empty state. */\n\t\temptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'This folder is empty'),\n\t\t},\n\n\t\t/** Line under the empty state's title. */\n\t\temptyHint: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Drop files here, or use New'),\n\t\t},\n\n\t\t/** Label of the retry button on a failed listing. */\n\t\tretryLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Try again'),\n\t\t},\n\n\t\t/**\n\t\t * The columns this browser shows, in order. An entry is a built-in name\n\t\t * (`name`, `size`, `modified`, `owner`, `type`, `tags`) or an object\n\t\t * declaring its own: `{ key, label, source, attribute, formatter,\n\t\t * sortable }`, where `source` is `node` (a property of the node),\n\t\t * `attribute` (a DAV property, added to the PROPFIND before listing) or\n\t\t * `row` (a value from `rowData`).\n\t\t *\n\t\t * Declaring none keeps today's table: name, size and modified.\n\t\t *\n\t\t * This is the membership list. The Columns chooser lets a user hide any\n\t\t * of these; it never adds one, and a column removed from here is gone\n\t\t * for every user, whatever they had stored.\n\t\t *\n\t\t * @type {Array<string|object>}\n\t\t */\n\t\tcolumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The host's own per-file data for `source: 'row'` columns, keyed by\n\t\t * file id. Either an object, or a function of the listed nodes called\n\t\t * once per folder so the host can fetch its projection in one request.\n\t\t *\n\t\t * @type {object | ((nodes: Array<object>) => (object|Promise<object>))}\n\t\t */\n\t\trowData: {\n\t\t\ttype: [Object, Function],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The app id the Columns chooser stores this user's choice under. Unset\n\t\t * means the chooser is not offered and every declared column renders.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tpreferenceApp: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The key this browser's column choice is stored under, so two browsers\n\t\t * in one app remember separately.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tpreferenceKey: {\n\t\t\ttype: String,\n\t\t\tdefault: 'files-browser-columns',\n\t\t},\n\n\t\t/**\n\t\t * The host's actions on a selection of files, declared like\n\t\t * `rowActions`. With at least one, every file row (never a folder or a\n\t\t * linked row) gets a checkbox, the header a select-all, and a bar with\n\t\t * these actions shows while files are selected. An `open-modal`\n\t\t * action's props gain `files` (each `{ fileId, fileName, path }`) and\n\t\t * `fileIds`; a `handler` action's args gain the selected nodes. The\n\t\t * selection clears after an action and when another folder opens.\n\t\t *\n\t\t * @type {Array<{id: string, label: string, icon?: string, type?: string, target?: string, props?: object, handler?: string, args?: Array}>}\n\t\t */\n\t\tbulkActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The bulk bar's count, as a translatable template with `{count}`\n\t\t * (\"{count} documents selected\"); `selectionLabelOne` is used for one.\n\t\t * Empty reads \"{count} selected\".\n\t\t *\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-the-bulk-bar-names-what-is-selected\n\t\t */\n\t\tselectionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The bulk bar's count for one selected file, e.g. \"{count} document selected\". */\n\t\tselectionLabelOne: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the bulk bar ends in a \"Clear selection\" button. */\n\t\tshowClearSelection: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Cards beside the list about the last selected file:\n\t\t * `[{ id, title, fields: [{ key, label, source?, formatter?, formatterOptions?, colorMap?, colorKey? }], actions? }]`.\n\t\t * `title` may hold `{name}`, the file's name. A field reads `rowData`\n\t\t * (`source: 'row'`, the default) or the node (`source: 'node'`); a field\n\t\t * with no value is left out. `actions` are declared like `rowActions`\n\t\t * and run on that file. No side column while nothing is selected.\n\t\t *\n\t\t * @type {Array<{id: string, title: string, fields?: Array<object>, actions?: Array<object>}>}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\tsideCards: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Where the side cards stand: `beside` (default) next to the list, or\n\t\t * `page-side` in the detail page's side column, in place of its\n\t\t * generic cards while a file is selected. Without a page side column\n\t\t * they stay beside the list.\n\t\t */\n\t\tsideCardsPlacement: {\n\t\t\ttype: String,\n\t\t\tdefault: 'beside',\n\t\t},\n\n\t\t/**\n\t\t * The key of a declared column to group the files on: a heading row\n\t\t * per value, in the order each is first met, with its count. Files\n\t\t * with no value come last under `groupEmptyLabel`; folders stay above.\n\t\t * Empty (the default) does not group.\n\t\t */\n\t\tgroupBy: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The heading of the group of files with no value in the `groupBy` column. */\n\t\tgroupEmptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Other'),\n\t\t},\n\n\t\t/**\n\t\t * Keys of declared columns to filter on. Each gets a chip per value in\n\t\t * use among the folder's files (a list counts per entry) with how many\n\t\t * files carry it; chosen chips keep the files with any chosen value of\n\t\t * that column, across every column with a choice.\n\t\t *\n\t\t * @type {string[]}\n\t\t */\n\t\tfacets: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the toolbar's Columns chooser. */\n\t\tcolumnsLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Columns'),\n\t\t},\n\t},\n\n\temits: ['changed'],\n\n\tdata() {\n\t\treturn {\n\t\t\t/** The actions column's measured width while a row button stands in it, else null. */\n\t\t\tactionsColumnWidth: null,\n\t\t\tcurrentPath: this.rootPath,\n\t\t\t/** The open folder as a node, or null before the first listing. */\n\t\t\tfolder: null,\n\t\t\t/** The open folder's children as nodes. */\n\t\t\tnodes: [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t\tsortKey: 'basename',\n\t\t\tsortAsc: true,\n\t\t\t/** The host's per-file data for `row` columns, by file id. */\n\t\t\tresolvedRowData: null,\n\t\t\t/** File ids (as strings) of the selected files. */\n\t\t\tselectedIds: [],\n\t\t\t/** Chosen facet values by column key. */\n\t\t\tfacetSelections: {},\n\t\t\t/**\n\t\t\t * The column keys this user chose to see, or null while they have\n\t\t\t * chosen nothing. Never a source of membership: it is intersected\n\t\t\t * with the host's declaration, never added to it.\n\t\t\t */\n\t\t\tvisibleColumnKeys: null,\n\t\t\tdragging: false,\n\t\t\t/** The number of files the current drag carries, null when unknown. */\n\t\t\tdragCount: null,\n\t\t\t/** Nested dragenter/dragleave pairs, so a child does not end the drag. */\n\t\t\tdragDepth: 0,\n\t\t\t/** What the live region says: the drop label, then what was added. */\n\t\t\tdropStatus: '',\n\t\t\tuploads: [],\n\t\t\tpreviewFailed: {},\n\t\t\tnewFolderOpen: false,\n\t\t\tnewFolderName: '',\n\t\t\tnewFolderError: '',\n\t\t\t/** The node being renamed, or null. */\n\t\t\trenaming: null,\n\t\t\trenameName: '',\n\t\t\trenameError: '',\n\t\t\t/** The row being deleted (with a `source`), or null. */\n\t\t\tremoving: null,\n\t\t\tremoveError: '',\n\t\t\tfileInputEl: null,\n\t\t\t/**\n\t\t\t * The view the Files app's actions are handed. They read `view.id`\n\t\t\t * to tell a trash bin or a share view from a plain folder; this is\n\t\t\t * a plain folder.\n\t\t\t */\n\t\t\tview: new View({\n\t\t\t\tid: 'files',\n\t\t\t\tname: t('nextcloud-vue', 'Files'),\n\t\t\t\t// The View constructor refuses anything but an SVG string here,\n\t\t\t\t// and throws from data(), which takes the whole tab down.\n\t\t\t\ticon: VIEW_ICON,\n\t\t\t\torder: 0,\n\t\t\t\tgetContents: async () => ({ folder: this.folder, contents: this.nodes }),\n\t\t\t}),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The actions column's width. The table lays out fixed, so its columns\n\t\t * take their widths from the head; a row button (Beoordelen) beside the\n\t\t * row menu needs more than the menu's 48px, measured from the first row.\n\t\t *\n\t\t * @return {object} The head cell's style.\n\t\t * @spec openspec/changes/files-actions-column-fits-row-button/specs/files-actions-column-fits-row-button/spec.md#requirement-the-actions-column-fits-a-row-button\n\t\t */\n\t\tactionsColumnStyle() {\n\t\t\treturn this.actionsColumnWidth ? { width: this.actionsColumnWidth + 'px' } : {}\n\t\t},\n\n\t\t/**\n\t\t * The `dropDetail` text: the string, or the text of the first variant\n\t\t * `{ when, text }` whose `when` is `true` or that has none.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t */\n\t\tdropDetailTemplate() {\n\t\t\tif (typeof this.dropDetail === 'string') {\n\t\t\t\treturn this.dropDetail\n\t\t\t}\n\t\t\tconst variants = Array.isArray(this.dropDetail) ? this.dropDetail : []\n\t\t\tconst chosen = variants.find((item) => item && typeof item.text === 'string' && (!('when' in item) || item.when === true))\n\t\t\treturn chosen ? chosen.text : ''\n\t\t},\n\n\t\t/**\n\t\t * `dropDetail` through the host translate with `{count}` filled, '' when\n\t\t * there is none or the count it needs is unknown.\n\t\t *\n\t\t * @spec openspec/changes/files-drop-panel/specs/files-browser/spec.md#requirement-the-drop-state-fills-the-panel-and-says-where-the-files-go\n\t\t * @return {string}\n\t\t */\n\t\tdropDetailText() {\n\t\t\tconst template = this.dropDetailTemplate\n\t\t\tif (!template) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tlet text = this.cnTranslate(template)\n\t\t\t// `dropDetailValues`: named values such as the case number; a value\n\t\t\t// still unknown (an unresolved `@` token, or empty) leaves the line out.\n\t\t\t// @spec openspec/changes/files-drop-detail-values/specs/files-drop-detail-values/spec.md#requirement-the-drop-detail-line-can-name-the-record\n\t\t\tconst values = this.dropDetailValues && typeof this.dropDetailValues === 'object' ? this.dropDetailValues : {}\n\t\t\tfor (const [name, value] of Object.entries(values)) {\n\t\t\t\tconst shown = value === null || value === undefined ? '' : String(value)\n\t\t\t\tif (shown === '' || shown.startsWith('@')) {\n\t\t\t\t\treturn ''\n\t\t\t\t}\n\t\t\t\ttext = text.split(`{${name}}`).join(shown)\n\t\t\t}\n\t\t\tif (!text.includes('{count}')) {\n\t\t\t\treturn text\n\t\t\t}\n\t\t\treturn this.dragCount === null ? '' : text.replace(/\\{count\\}/g, String(this.dragCount))\n\t\t},\n\n\t\t/**\n\t\t * Whether this person may add to and change the open folder. Over\n\t\t * WebDAV the server answers each write on its own, so this is true;\n\t\t * with a `source` it is what the listing said.\n\t\t *\n\t\t * @return {boolean} True when upload, new folder, rename and delete are offered.\n\t\t */\n\t\tcanChange() {\n\t\t\tif (!this.source) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.folder !== null && this.folder.canChange === true\n\t\t},\n\n\t\t/**\n\t\t * The breadcrumb trail from the root to the open folder.\n\t\t *\n\t\t * @return {Array<{name: string, path: string}>} The crumbs.\n\t\t */\n\t\tcrumbs() {\n\t\t\treturn crumbsFor(this.rootPath, this.currentPath, this.rootLabel)\n\t\t},\n\n\t\t/**\n\t\t * Whether the open folder is the browser's root: the trail then ends on\n\t\t * the root itself (the board look draws no trail there).\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/board-files-root-crumb/specs/board-files-root-crumb/spec.md#requirement-the-board-files-bar-draws-no-trail-at-the-root\n\t\t */\n\t\tatRoot() {\n\t\t\tconst root = String(this.rootPath || '/').replace(/\\/+$/, '') || '/'\n\t\t\tconst last = this.crumbs[this.crumbs.length - 1]\n\t\t\treturn Boolean(last) && last.path === root\n\t\t},\n\n\t\t/**\n\t\t * The children in the chosen order, folders first the way the Files app\n\t\t * lists them.\n\t\t *\n\t\t * @return {Array<object>} The nodes.\n\t\t */\n\t\tsorted() {\n\t\t\tconst column = this.activeSortColumn\n\t\t\tif (column && !column.sortKey) {\n\t\t\t\t// A declared column has no meaning to the Files app's sorter, so\n\t\t\t\t// it sorts here, within the folder that is listed.\n\t\t\t\treturn sortNodesByColumn(this.nodes, column, this.sortAsc, this.resolvedRowData, (node) => this.isFolder(node))\n\t\t\t}\n\t\t\treturn sortNodes(this.nodes, {\n\t\t\t\tsortingMode: this.sortKey,\n\t\t\t\tsortingOrder: this.sortAsc ? 'asc' : 'desc',\n\t\t\t\tsortFoldersFirst: true,\n\t\t\t\tsortFavoritesFirst: false,\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * The columns the host declared, resolved. This is the membership list:\n\t\t * a column exists because the host declared it, in the host's order.\n\t\t *\n\t\t * @return {Array<object>} The declared columns.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\tdeclaredColumns() {\n\t\t\treturn normaliseFileColumns(this.columns)\n\t\t},\n\n\t\t/**\n\t\t * The library's own word for each built-in column, used when the host\n\t\t * did not write a label.\n\t\t *\n\t\t * @return {object} Labels by column key.\n\t\t */\n\t\tbuiltInColumnLabels() {\n\t\t\treturn {\n\t\t\t\tname: t('nextcloud-vue', 'Name'),\n\t\t\t\tsize: t('nextcloud-vue', 'Size'),\n\t\t\t\tmodified: t('nextcloud-vue', 'Modified'),\n\t\t\t\towner: t('nextcloud-vue', 'Owner'),\n\t\t\t\ttype: t('nextcloud-vue', 'Type'),\n\t\t\t\ttags: t('nextcloud-vue', 'Tags'),\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The columns this browser renders: the host's declaration narrowed by\n\t\t * what this user chose to see.\n\t\t *\n\t\t * The user's stored choice only ever takes columns away. It is applied\n\t\t * by walking the declaration, so a key the host no longer declares is\n\t\t * passed over rather than rendered, and a preference written when a\n\t\t * different set was declared cannot bring an old column back.\n\t\t *\n\t\t * @return {Array<object>} The columns to render.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\trenderedColumns() {\n\t\t\treturn visibleFileColumns(this.declaredColumns, this.visibleColumnKeys)\n\t\t},\n\n\t\t/**\n\t\t * The declared columns by key, for grouping and facets.\n\t\t *\n\t\t * @return {object} Resolved columns by key.\n\t\t */\n\t\tcolumnsByKey() {\n\t\t\tconst byKey = {}\n\t\t\tthis.declaredColumns.forEach((column) => {\n\t\t\t\tbyKey[column.key] = column\n\t\t\t})\n\t\t\treturn byKey\n\t\t},\n\n\t\t/**\n\t\t * How many cells a row has, for a heading or message spanning the row.\n\t\t *\n\t\t * @return {number} The column count.\n\t\t */\n\t\tcolumnCount() {\n\t\t\treturn this.renderedColumns.length + 2 + (this.bulkEnabled ? 1 : 0)\n\t\t},\n\n\t\t/**\n\t\t * Whether the host gave bulk actions, which turns on the selection.\n\t\t *\n\t\t * @return {boolean} True with at least one bulk action.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tbulkEnabled() {\n\t\t\treturn Array.isArray(this.bulkActions) && this.bulkActions.length > 0\n\t\t},\n\n\t\t/**\n\t\t * The listed folders, in display order.\n\t\t *\n\t\t * @return {Array<object>} The folder nodes.\n\t\t */\n\t\tfolderNodes() {\n\t\t\treturn this.sorted.filter((node) => this.isFolder(node))\n\t\t},\n\n\t\t/**\n\t\t * The listed files, in display order, before the filter.\n\t\t *\n\t\t * @return {Array<object>} The file nodes.\n\t\t */\n\t\t/**\n\t\t * The fields `secondLine` names for this browser: the list itself, or\n\t\t * the fields of its first variant whose `when` is `true` or absent.\n\t\t * Null without `secondLine` or a matching variant.\n\t\t *\n\t\t * @return {Array<string>|null}\n\t\t * @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields\n\t\t */\n\t\tsecondLineFields() {\n\t\t\tconst list = Array.isArray(this.secondLine) ? this.secondLine : []\n\t\t\tif (list.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (list.every((item) => typeof item === 'string')) {\n\t\t\t\treturn list\n\t\t\t}\n\t\t\tconst variant = list.find((item) => item && typeof item === 'object' && Array.isArray(item.fields) && (!('when' in item) || item.when === true))\n\t\t\treturn variant ? variant.fields.filter((field) => typeof field === 'string') : null\n\t\t},\n\n\t\t/**\n\t\t * The bulk bar's count text.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-the-bulk-bar-names-what-is-selected\n\t\t */\n\t\tselectionCountText() {\n\t\t\tconst count = this.selectedIds.length\n\t\t\tconst template = count === 1 && this.selectionLabelOne ? this.selectionLabelOne : this.selectionLabel\n\t\t\tif (template) {\n\t\t\t\treturn this.cnTranslate(template).replace(/\\{count\\}/g, String(count))\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', '{count} selected', { count })\n\t\t},\n\n\t\t/**\n\t\t * The file the side cards describe: the last one selected, or null\n\t\t * without side cards or a selection.\n\t\t *\n\t\t * @return {object|null}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\t/** @return {boolean} Whether the side cards fill the page's side column now. */\n\t\tsideClaimed() {\n\t\t\treturn this.sideInPage && this.sideNode !== null\n\t\t},\n\n\t\t/** @return {boolean} Whether the side cards stand in the page's side column. */\n\t\tsideInPage() {\n\t\t\treturn this.sideCardsPlacement === 'page-side' && this.cnDetailSideColumn !== null && this.cnDetailSideColumn.available === true\n\t\t},\n\n\t\t/** @return {string} Where the side cards are teleported to in the page. */\n\t\tpageSideTarget() {\n\t\t\treturn this.cnDetailSideColumn?.target || 'body'\n\t\t},\n\n\t\tsideNode() {\n\t\t\tif (!Array.isArray(this.sideCards) || this.sideCards.length === 0 || this.selectedIds.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst id = this.selectedIds[this.selectedIds.length - 1]\n\t\t\treturn this.fileNodes.find((node) => String(node.fileid) === id) || null\n\t\t},\n\n\t\tfileNodes() {\n\t\t\treturn this.sorted.filter((node) => !this.isFolder(node))\n\t\t},\n\n\t\t/**\n\t\t * The review counts over the folder's files, or null without a summary.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\treview() {\n\t\t\treturn reviewSummary(this.reviewSummary, this.fileNodes, this.resolvedRowData)\n\t\t},\n\n\t\t/** @return {string} The summary's title, counts filled in. */\n\t\treviewTitle() {\n\t\t\treturn this.reviewText('title', t('nextcloud-vue', '{done} of {total} reviewed'))\n\t\t},\n\n\t\t/** @return {string} The summary's second line, or '' when nothing is open. */\n\t\treviewSubtitle() {\n\t\t\tif (!this.review || this.review.open === 0) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.reviewText('subtitle', t('nextcloud-vue', '{open} still to review'))\n\t\t},\n\n\t\t/**\n\t\t * Whether any facet value is chosen.\n\t\t *\n\t\t * @return {boolean} True when the filter narrows the list.\n\t\t */\n\t\tfacetActive() {\n\t\t\treturn Object.values(this.facetSelections).some((values) => Array.isArray(values) && values.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The chips: per facet column, the values in use with their counts.\n\t\t *\n\t\t * @return {Array<{key: string, label: string, values: Array<{value: string, count: number, active: boolean}>}>} The facets.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tfacetGroups() {\n\t\t\tconst keys = Array.isArray(this.facets) ? this.facets : []\n\t\t\treturn keys\n\t\t\t\t.map((key) => this.columnsByKey[key])\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.map((column) => {\n\t\t\t\t\tconst chosen = this.facetSelections[column.key] || []\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkey: column.key,\n\t\t\t\t\t\tlabel: this.columnLabel(column),\n\t\t\t\t\t\tvalues: facetCounts(this.fileNodes, column, this.resolvedRowData)\n\t\t\t\t\t\t\t.map((entry) => ({ ...entry, active: chosen.includes(entry.value) })),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.filter((facet) => facet.values.length > 0)\n\t\t},\n\n\t\t/**\n\t\t * The files the filter keeps.\n\t\t *\n\t\t * @return {Array<object>} The file nodes.\n\t\t */\n\t\tfilteredFiles() {\n\t\t\tif (!this.facetActive) {\n\t\t\t\treturn this.fileNodes\n\t\t\t}\n\t\t\treturn this.fileNodes.filter((node) => nodeMatchesFacets(node, this.facetSelections, this.columnsByKey, this.resolvedRowData))\n\t\t},\n\n\t\t/**\n\t\t * What the table body renders, in order: folders, then the files,\n\t\t * under a heading per group when the host groups.\n\t\t *\n\t\t * @return {Array<{key: string, group?: object, node?: object}>} The rows.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\tdisplayRows() {\n\t\t\tconst rows = this.folderNodes.map((node) => ({ key: node.source, node }))\n\t\t\tconst column = this.groupBy ? this.columnsByKey[this.groupBy] : null\n\t\t\tif (!column) {\n\t\t\t\tthis.filteredFiles.forEach((node) => rows.push({ key: node.source, node }))\n\t\t\t\treturn rows\n\t\t\t}\n\t\t\tgroupNodes(this.filteredFiles, column, this.resolvedRowData).forEach((group) => {\n\t\t\t\tconst label = group.value === null ? this.groupEmptyLabel : group.value\n\t\t\t\trows.push({ key: `group-${group.value === null ? '' : group.value}`, group: { label, count: group.nodes.length } })\n\t\t\t\tgroup.nodes.forEach((node) => rows.push({ key: node.source, node }))\n\t\t\t})\n\t\t\treturn rows\n\t\t},\n\n\t\t/**\n\t\t * The ids of the files a select-all takes: the files the filter keeps.\n\t\t *\n\t\t * @return {string[]} File ids as strings.\n\t\t */\n\t\tselectableIds() {\n\t\t\treturn this.filteredFiles.map((node) => String(node.fileid))\n\t\t},\n\n\t\t/**\n\t\t * Whether every selectable file is selected.\n\t\t *\n\t\t * @return {boolean} True when all are.\n\t\t */\n\t\tallSelected() {\n\t\t\treturn this.selectableIds.length > 0 && this.selectableIds.every((id) => this.selectedIds.includes(id))\n\t\t},\n\n\t\t/**\n\t\t * Whether some file is selected.\n\t\t *\n\t\t * @return {boolean} True when one or more are.\n\t\t */\n\t\tsomeSelected() {\n\t\t\treturn this.selectedIds.length > 0\n\t\t},\n\n\t\t/**\n\t\t * The column the table is currently sorted on, or null when the sort\n\t\t * key belongs to no declared column.\n\t\t *\n\t\t * @return {(object|null)} The active column.\n\t\t */\n\t\tactiveSortColumn() {\n\t\t\treturn this.declaredColumns.find((column) => this.sortTokenOf(column) === this.sortKey) || null\n\t\t},\n\n\t\t/**\n\t\t * Whether the Columns chooser is offered: only when the host said where\n\t\t * to store the answer, because a chooser that forgets is worse than no\n\t\t * chooser.\n\t\t *\n\t\t * @return {boolean} True when the chooser renders.\n\t\t */\n\t\tcolumnsChooserEnabled() {\n\t\t\treturn this.preferenceApp !== '' && this.declaredColumns.length > 0\n\t\t},\n\n\t\t/**\n\t\t * What the Files app and its plugins offer to create in this folder.\n\t\t *\n\t\t * Read at render, not cached: a plugin's script may register its entry\n\t\t * after this component mounted.\n\t\t *\n\t\t * @return {Array<object>} The entries, in the plugins' order.\n\t\t */\n\t\tnewMenuEntries() {\n\t\t\tif (this.folder === null || this.source) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn getNewFileMenuEntries(this.folder)\n\t\t\t\t\t.filter((entry) => typeof entry.handler === 'function')\n\t\t\t\t\t.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Tell the page whether the side cards stand in its side column now,\n\t\t * so its generic cards stand aside meanwhile.\n\t\t */\n\t\tsideClaimed: {\n\t\t\timmediate: true,\n\t\t\thandler(on) {\n\t\t\t\tthis.cnDetailSideColumn?.claim?.(this.$.uid, on)\n\t\t\t},\n\t\t},\n\n\t\trootPath(next) {\n\t\t\tthis.currentPath = next\n\t\t\tthis.refresh()\n\t\t},\n\n\t\t// A selection belongs to the folder it was made in.\n\t\tcurrentPath() {\n\t\t\tthis.selectedIds = []\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.loadColumnChoice()\n\t\tthis.refresh()\n\t\t// Another surface on the page changed the folder: the page's Refresh,\n\t\t// a dialog that filed a document, or a Files action whose work ends\n\t\t// after its own call returned (the delete confirmation, an upload).\n\t\tfor (const channel of FOLDER_CHANGED_CHANNELS) {\n\t\t\tsubscribe(channel, this.onFolderChanged)\n\t\t}\n\t},\n\n\tupdated() {\n\t\tthis.measureActionsColumn()\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.cnDetailSideColumn?.claim?.(this.$.uid, false)\n\t\tfor (const channel of FOLDER_CHANGED_CHANNELS) {\n\t\t\tunsubscribe(channel, this.onFolderChanged)\n\t\t}\n\t\tclearTimeout(this._folderChangedTimer)\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Measure the first row's actions cell (padding, the row button, the\n\t\t * gap and the menu) and keep it as the column's width, so a fixed\n\t\t * table does not push the button past its card. Without a row button\n\t\t * the column keeps its own width.\n\t\t *\n\t\t * @spec openspec/changes/files-actions-column-fits-row-button/specs/files-actions-column-fits-row-button/spec.md#requirement-the-actions-column-fits-a-row-button\n\t\t */\n\t\tmeasureActionsColumn() {\n\t\t\tconst cell = this.$el && this.$el.querySelector ? this.$el.querySelector('tbody .cn-files-browser__col-actions') : null\n\t\t\tconst button = cell ? cell.querySelector('.cn-files-browser__row-button') : null\n\t\t\tif (!cell || !button) {\n\t\t\t\tif (this.actionsColumnWidth !== null) {\n\t\t\t\t\tthis.actionsColumnWidth = null\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst style = window.getComputedStyle(cell)\n\t\t\tconst content = [...cell.children].reduce((sum, child) => {\n\t\t\t\tconst childStyle = window.getComputedStyle(child)\n\t\t\t\treturn sum + child.offsetWidth + (parseFloat(childStyle.marginInlineStart) || 0) + (parseFloat(childStyle.marginInlineEnd) || 0)\n\t\t\t}, 0)\n\t\t\tconst width = Math.ceil(content + (parseFloat(style.paddingInlineStart) || 0) + (parseFloat(style.paddingInlineEnd) || 0))\n\t\t\tif (width > 0 && width !== this.actionsColumnWidth) {\n\t\t\t\tthis.actionsColumnWidth = width\n\t\t\t}\n\t\t},\n\n\t\tt,\n\n\t\tpreventMiddleClickAutoscroll,\n\n\t\t/**\n\t\t * Hold the file input element from its function ref.\n\t\t *\n\t\t * @param {HTMLInputElement|null} el The element.\n\t\t * @return {void}\n\t\t */\n\t\tfileInputRef(el) {\n\t\t\tthis.fileInputEl = el || null\n\t\t},\n\n\t\t/**\n\t\t * The DAV path of a user-relative path.\n\t\t *\n\t\t * @param {string} path The user-relative path.\n\t\t * @return {string} The path under the DAV files root.\n\t\t */\n\t\tdavPath(path) {\n\t\t\treturn `${getRootPath()}${path}`\n\t\t},\n\n\t\t/**\n\t\t * List the open folder over DAV, with the same PROPFIND the Files app sends.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync refresh() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\tif (this.source) {\n\t\t\t\tawait this.refreshFromSource()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst client = getClient()\n\t\t\t\tconst { data } = await client.getDirectoryContents(this.davPath(this.currentPath), {\n\t\t\t\t\tdetails: true,\n\t\t\t\t\tdata: this.propfindBody(),\n\t\t\t\t\tincludeSelf: true,\n\t\t\t\t})\n\t\t\t\tconst stats = Array.isArray(data) ? data : []\n\t\t\t\tconst nodes = stats.map((stat) => resultToNode(stat))\n\t\t\t\tconst self = nodes.find((node) => node.path === this.currentPath) || nodes[0] || null\n\t\t\t\tthis.folder = self\n\t\t\t\tthis.nodes = nodes.filter((node) => node !== self)\n\t\t\t\t// One call per folder, not one per file: the host's projection\n\t\t\t\t// is asked for the whole listing at once.\n\t\t\t\tawait this.resolveRowData(this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst status = err?.response?.status ?? err?.status\n\t\t\t\tthis.error = status === 404\n\t\t\t\t\t? t('nextcloud-vue', 'This folder no longer exists')\n\t\t\t\t\t: (status === 403 ? t('nextcloud-vue', 'You cannot see this folder') : t('nextcloud-vue', 'The folder could not be read'))\n\t\t\t\tthis.folder = null\n\t\t\t\tthis.nodes = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * List the open folder through the `source`.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync refreshFromSource() {\n\t\t\ttry {\n\t\t\t\tconst { folder, nodes } = await this.source.list(this.currentPath)\n\t\t\t\tthis.folder = folder\n\t\t\t\tthis.nodes = nodes\n\t\t\t\tawait this.resolveRowData(this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst atRoot = (this.currentPath.replace(/\\/+$/, '') || '/') === (this.rootPath.replace(/\\/+$/, '') || '/')\n\t\t\t\tthis.error = err?.status === 404\n\t\t\t\t\t? (atRoot ? t('nextcloud-vue', 'You cannot see these files') : t('nextcloud-vue', 'This folder no longer exists'))\n\t\t\t\t\t: (err?.status === 403 ? t('nextcloud-vue', 'You cannot see this folder') : t('nextcloud-vue', 'The folder could not be read'))\n\t\t\t\tthis.folder = null\n\t\t\t\tthis.nodes = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Where a file downloads from, through the `source`.\n\t\t *\n\t\t * @param {object} node The row.\n\t\t * @return {string|null} The url.\n\t\t */\n\t\tsourceDownloadUrl(node) {\n\t\t\treturn this.source && typeof this.source.downloadUrl === 'function' ? this.source.downloadUrl(node) : null\n\t\t},\n\n\t\t/**\n\t\t * Open the delete dialog on a row.\n\t\t *\n\t\t * @param {object} node The row.\n\t\t * @return {void}\n\t\t */\n\t\taskRemove(node) {\n\t\t\tthis.removing = node\n\t\t\tthis.removeError = ''\n\t\t},\n\n\t\t/**\n\t\t * Delete the row named in the dialog, through the `source`.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync remove() {\n\t\t\tconst node = this.removing\n\t\t\tif (node === null || !this.source) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this.source.remove(node)\n\t\t\t\tthis.removing = null\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.removeError = err?.message || t('nextcloud-vue', '{action} did not succeed', { action: this.deleteLabel })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a folder below the root.\n\t\t *\n\t\t * @param {string} path The user-relative path.\n\t\t * @return {void}\n\t\t */\n\t\tnavigate(path) {\n\t\t\tconst root = this.rootPath.replace(/\\/+$/, '') || '/'\n\t\t\tif (path !== root && !path.startsWith(root === '/' ? '/' : `${root}/`)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.currentPath = path\n\t\t\tthis.refresh()\n\t\t},\n\n\t\t/**\n\t\t * Whether a node is a folder.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {boolean} true for a folder.\n\t\t */\n\t\tisFolder(node) {\n\t\t\treturn node.type === FileType.Folder\n\t\t},\n\n\t\t/**\n\t\t * A row was clicked: enter a folder, or open a file the way the Files\n\t\t * app would (its `view` action, which hands over to the Viewer).\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync open(node) {\n\t\t\tif (this.isFolder(node)) {\n\t\t\t\tthis.navigate(node.path)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.source) {\n\t\t\t\tconst url = this.sourceDownloadUrl(node)\n\t\t\t\tif (url) {\n\t\t\t\t\twindow.open(url, '_blank', 'noopener,noreferrer')\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst view = this.actionsFor(node).find((action) => action.id === 'view')\n\t\t\tif (view) {\n\t\t\t\tawait this.run(view, node)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (node.fileid) {\n\t\t\t\twindow.open(this.permalink(node), '_blank', 'noopener,noreferrer')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Row click: a ctrl/cmd/shift click opens the node's permalink in a new\n\t\t * tab, like a link would; a plain click opens it in place (`open`).\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @param {MouseEvent} [event] The click event.\n\t\t * @return {void}\n\t\t */\n\t\tonRowClick(node, event) {\n\t\t\tif (isNewTabClick(event)) {\n\t\t\t\tthis.openInNewTab(node)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.open(node)\n\t\t},\n\n\t\t/**\n\t\t * Row middle click: open the node's permalink in a new tab.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void}\n\t\t */\n\t\tonRowAuxClick(node, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\tthis.openInNewTab(node)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a node's permalink (a file or a folder in the Files app) in a new tab.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\topenInNewTab(node) {\n\t\t\tif (this.source) {\n\t\t\t\tif (this.isFolder(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst url = this.sourceDownloadUrl(node)\n\t\t\t\tif (url) {\n\t\t\t\t\twindow.open(url, '_blank', 'noopener,noreferrer')\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (node.fileid) {\n\t\t\t\twindow.open(this.permalink(node), '_blank', 'noopener,noreferrer')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The action context the Files app hands its actions for one node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {object} The context.\n\t\t */\n\t\tcontextFor(node) {\n\t\t\treturn { nodes: [node], view: this.view, folder: this.folder, contents: this.nodes }\n\t\t},\n\n\t\t/**\n\t\t * The registered actions that apply to a node, in the Files app's order.\n\t\t *\n\t\t * Inline actions (a sharing badge, an unread-comments dot) are status\n\t\t * marks the Files app paints beside the name, not menu items; a\n\t\t * sub-action lives under its parent's own menu; and the actions that\n\t\t * need the Files page are named in `ACTIONS_NEEDING_THE_FILES_PAGE`.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Array<object>} The actions.\n\t\t */\n\t\tactionsFor(node) {\n\t\t\tif (this.source) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tlet actions\n\t\t\ttry {\n\t\t\t\tactions = getFileActions()\n\t\t\t} catch {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst context = this.contextFor(node)\n\t\t\treturn actions\n\t\t\t\t.filter((action) => !action.parent && !ACTIONS_NEEDING_THE_FILES_PAGE.includes(action.id))\n\t\t\t\t.filter((action) => typeof action.inline !== 'function' || action.inline(context) !== true)\n\t\t\t\t.filter((action) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn typeof action.enabled !== 'function' || action.enabled(context) === true\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n\t\t},\n\n\t\t/**\n\t\t * An action's label for a node, in the words the Files app uses.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {string} The label.\n\t\t */\n\t\t/**\n\t\t * A host action's label in the user's language.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-a-declared-row-action-reads-in-the-users-language\n\t\t * @param {object} action The manifest-declared action.\n\t\t * @return {string} The label.\n\t\t */\n\t\thostLabel(action) {\n\t\t\treturn this.cnTranslate(String(action?.label ?? ''))\n\t\t},\n\n\t\t/**\n\t\t * The second line under a file's name, or '' without `nameSecondary`,\n\t\t * for a folder, or when a value in it is empty.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {string}\n\t\t */\n\t\tnameSecondaryOf(node) {\n\t\t\tconst fields = this.secondLineFields\n\t\t\tif ((!this.nameSecondary && fields === null) || this.isFolder(node)) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst byId = this.resolvedRowData && typeof this.resolvedRowData === 'object' ? this.resolvedRowData : {}\n\t\t\tconst entry = byId[node.fileid] ?? byId[String(node.fileid)] ?? {}\n\t\t\tconst owner = node.attributes ? node.attributes['owner-display-name'] : undefined\n\t\t\tconst object = {\n\t\t\t\t...entry,\n\t\t\t\tname: node.basename,\n\t\t\t\t// A template drops an object value, so the Date is handed over as ISO text.\n\t\t\t\tmodified: node.mtime instanceof Date ? node.mtime.toISOString() : node.mtime,\n\t\t\t\tsize: this.formatSize(node.size),\n\t\t\t\ttype: this.typeLabelOf(node),\n\t\t\t\t...(owner ? { owner } : {}),\n\t\t\t}\n\t\t\tif (fields !== null) {\n\t\t\t\treturn fields\n\t\t\t\t\t.map((field) => fillTemplate(`{${field}}`, object))\n\t\t\t\t\t.filter((text) => text !== '')\n\t\t\t\t\t.join(' · ')\n\t\t\t}\n\t\t\treturn fillTemplate(this.cnTranslate(this.nameSecondary), object)\n\t\t},\n\n\t\t/**\n\t\t * A file's type as a reader names it: the application for common\n\t\t * office types (\"PDF\", \"Word\", \"Excel\"), \"Email\" for a mail, \"Image\"\n\t\t * for a picture, else the extension in capitals.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {string} The label, or ''.\n\t\t * @spec openspec/changes/files-browser-second-line-size-type/specs/files-browser-second-line-size-type/spec.md#requirement-a-files-second-line-can-name-its-type-and-size\n\t\t */\n\t\ttypeLabelOf(node) {\n\t\t\tconst mime = String(node?.mime || '')\n\t\t\tif (mime === 'application/pdf') {\n\t\t\t\treturn 'PDF'\n\t\t\t}\n\t\t\tif (/msword|wordprocessingml/.test(mime)) {\n\t\t\t\treturn 'Word'\n\t\t\t}\n\t\t\tif (/ms-excel|spreadsheetml/.test(mime)) {\n\t\t\t\treturn 'Excel'\n\t\t\t}\n\t\t\tif (/ms-powerpoint|presentationml/.test(mime)) {\n\t\t\t\treturn 'PowerPoint'\n\t\t\t}\n\t\t\tif (mime === 'message/rfc822' || mime === 'application/vnd.ms-outlook') {\n\t\t\t\treturn t('nextcloud-vue', 'Email')\n\t\t\t}\n\t\t\tif (mime.startsWith('image/')) {\n\t\t\t\treturn t('nextcloud-vue', 'Image')\n\t\t\t}\n\t\t\tconst match = /\\.([a-z0-9]+)$/i.exec(String(node?.basename || ''))\n\t\t\treturn match ? match[1].toUpperCase() : ''\n\t\t},\n\n\t\t/**\n\t\t * A review summary line: the host's template through its translate, else\n\t\t * the library's, with the counts filled in.\n\t\t *\n\t\t * @param {string} key `title` or `subtitle`.\n\t\t * @param {string} fallback The library's line, already translated.\n\t\t * @return {string}\n\t\t */\n\t\treviewText(key, fallback) {\n\t\t\tconst own = this.reviewSummary && typeof this.reviewSummary[key] === 'string' && this.reviewSummary[key] !== ''\n\t\t\t\t? this.cnTranslate(this.reviewSummary[key])\n\t\t\t\t: fallback\n\t\t\tconst counts = this.review || { done: 0, total: 0, open: 0 }\n\t\t\treturn own.replace(/\\{(done|total|open)\\}/g, (match, name) => String(counts[name]))\n\t\t},\n\n\t\t/**\n\t\t * Whether a review value is one of the summary's open values.\n\t\t *\n\t\t * @param {string} value The value.\n\t\t * @return {boolean}\n\t\t */\n\t\tisOpenValue(value) {\n\t\t\tconst open = this.reviewSummary ? this.reviewSummary.open : undefined\n\t\t\tconst list = (Array.isArray(open) ? open : [open]).filter((v) => v !== undefined && v !== null)\n\t\t\treturn list.some((v) => String(v).toLowerCase() === String(value).toLowerCase())\n\t\t},\n\n\t\t/**\n\t\t * Whether a file's row button is the primary one: the row-data field\n\t\t * `primaryWhen.key` holds one of `primaryWhen.values`.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {boolean}\n\t\t */\n\t\trowButtonPrimary(node) {\n\t\t\tconst when = this.rowButton && this.rowButton.primaryWhen\n\t\t\tif (!when || typeof when.key !== 'string' || !Array.isArray(when.values)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst raw = fileColumnValue({ key: when.key, source: 'row' }, node, this.resolvedRowData)\n\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn when.values.some((v) => String(v).toLowerCase() === String(raw).toLowerCase())\n\t\t},\n\n\t\thostActionApplies,\n\n\t\t/**\n\t\t * Re-read the folder once after a burst of change signals. One upload\n\t\t * of ten files answers ten `files:node:created`, and one PROPFIND\n\t\t * covers them all.\n\t\t *\n\t\t * @spec openspec/changes/files-browser-hears-the-page/specs/files-browser/spec.md#requirement-the-files-browser-re-reads-when-the-page-says-files-changed\n\t\t * @return {void}\n\t\t */\n\t\tonFolderChanged() {\n\t\t\tclearTimeout(this._folderChangedTimer)\n\t\t\tthis._folderChangedTimer = setTimeout(() => this.refresh(), FOLDER_CHANGED_DEBOUNCE_MS)\n\t\t},\n\n\t\tlabelOf(action, node) {\n\t\t\ttry {\n\t\t\t\treturn action.displayName(this.contextFor(node))\n\t\t\t} catch {\n\t\t\t\treturn action.id\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * An action's icon for a node, as inline SVG.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {string} The SVG, or the empty string.\n\t\t */\n\t\ticonOf(action, node) {\n\t\t\ttry {\n\t\t\t\treturn action.iconSvgInline(this.contextFor(node)) || ''\n\t\t\t} catch {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Run a registered action on a node, then re-read the folder: most of\n\t\t * them change it (a delete, a rename, a move), and the ones that do\n\t\t * not cost one PROPFIND.\n\t\t *\n\t\t * @param {object} action The action.\n\t\t * @param {object} node The node.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync run(action, node) {\n\t\t\ttry {\n\t\t\t\tconst result = await action.exec(this.contextFor(node))\n\t\t\t\tif (result === false) {\n\t\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\t\tshowError(t('nextcloud-vue', '{action} did not succeed', { action: this.labelOf(action, node) }))\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\tshowError(err?.message || t('nextcloud-vue', '{action} did not succeed', { action: this.labelOf(action, node) }))\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\t/**\n\t\t\t * @event changed The folder's contents changed through this browser:\n\t\t\t * an upload, a new folder, or an action that ran.\n\t\t\t */\n\t\t\tthis.$emit('changed')\n\t\t},\n\n\t\t/**\n\t\t * Run a New menu entry the Files app or a plugin registered, then re-read.\n\t\t *\n\t\t * The `newFolder` entry the Files app registers opens its own inline\n\t\t * rename in the Files list, which is not here, so that one is answered\n\t\t * by this component's dialog instead.\n\t\t *\n\t\t * @param {object} entry The entry.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync runNewEntry(entry) {\n\t\t\tif (entry.id === 'newFolder') {\n\t\t\t\tthis.askNewFolder()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait entry.handler(this.folder, this.nodes)\n\t\t\t} catch (err) {\n\t\t\t\tconst { showError } = await import('@nextcloud/dialogs')\n\t\t\t\tshowError(err?.message || t('nextcloud-vue', '{action} did not succeed', { action: entry.displayName }))\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\tthis.$emit('changed')\n\t\t},\n\n\t\t/**\n\t\t * Open the new-folder dialog.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\taskNewFolder() {\n\t\t\tthis.newFolderName = ''\n\t\t\tthis.newFolderError = ''\n\t\t\tthis.newFolderOpen = true\n\t\t},\n\n\t\t/**\n\t\t * Create the folder named in the dialog, over DAV.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync createFolder() {\n\t\t\tconst name = this.newFolderName.trim()\n\t\t\tif (name === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.nodes.some((node) => node.basename === name)) {\n\t\t\t\tthis.newFolderError = t('nextcloud-vue', 'A file or folder with that name is already here')\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.source.createFolder(this.currentPath, name)\n\t\t\t\t} else {\n\t\t\t\t\tawait getClient().createDirectory(this.davPath(joinPath(this.currentPath, name)))\n\t\t\t\t}\n\t\t\t\tthis.newFolderOpen = false\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.newFolderError = err?.message || t('nextcloud-vue', 'The folder could not be created')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open the rename dialog on a node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\taskRename(node) {\n\t\t\tthis.renaming = node\n\t\t\tthis.renameName = node.basename\n\t\t\tthis.renameError = ''\n\t\t},\n\n\t\t/**\n\t\t * Rename the node named in the dialog, as a DAV move within its folder.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync rename() {\n\t\t\tconst node = this.renaming\n\t\t\tconst name = this.renameName.trim()\n\t\t\tif (node === null || name === '' || name === node.basename) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (name.includes('/')) {\n\t\t\t\tthis.renameError = t('nextcloud-vue', 'A name cannot contain a slash')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.nodes.some((other) => other !== node && other.basename === name)) {\n\t\t\t\tthis.renameError = t('nextcloud-vue', 'A file or folder with that name is already here')\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.source.rename(node, name)\n\t\t\t\t} else {\n\t\t\t\t\tawait getClient().moveFile(this.davPath(node.path), this.davPath(joinPath(this.currentPath, name)))\n\t\t\t\t}\n\t\t\t\tthis.renaming = null\n\t\t\t\tawait this.refresh()\n\t\t\t\tthis.$emit('changed')\n\t\t\t} catch (err) {\n\t\t\t\tthis.renameError = err?.message || t('nextcloud-vue', 'The name could not be changed')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open the file picker.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tpickFiles() {\n\t\t\tthis.fileInputEl?.click()\n\t\t},\n\n\t\t/**\n\t\t * Files were picked.\n\t\t *\n\t\t * @param {Event} event The change event.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onFilesPicked(event) {\n\t\t\tconst files = event.target?.files\n\t\t\tif (files?.length) {\n\t\t\t\tawait this.uploadFiles(files)\n\t\t\t}\n\t\t\tif (this.fileInputEl) {\n\t\t\t\tthis.fileInputEl.value = ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Files were dropped.\n\t\t *\n\t\t * @param {DragEvent} event The drop.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onDrop(event) {\n\t\t\tthis.dragging = false\n\t\t\tthis.dragDepth = 0\n\t\t\tthis.dropStatus = ''\n\t\t\tif (!this.canChange) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst files = event.dataTransfer?.files\n\t\t\tif (files?.length) {\n\t\t\t\tawait this.uploadFiles(files)\n\t\t\t\tif (this.dropOverlay) {\n\t\t\t\t\tthis.dropStatus = n('nextcloud-vue', '%n file added', '%n files added', files.length)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Something is dragged into the browser: show the drop state when it\n\t\t * carries files, and say so once.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {void}\n\t\t */\n\t\tonDragEnter(event) {\n\t\t\tif (!this.canChange || !this.carriesFiles(event)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.dragDepth++\n\t\t\tif (!this.dragging) {\n\t\t\t\tthis.dragging = true\n\t\t\t\tthis.dragCount = this.draggedFileCount(event)\n\t\t\t\tthis.dropStatus = this.dropOverlay ? [this.cnTranslate(this.dropLabel), this.dropDetailText].filter(Boolean).join(' ') : ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Keep the drop state while files move over the browser.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {void}\n\t\t */\n\t\tonDragOver(event) {\n\t\t\tif (this.canChange && this.carriesFiles(event)) {\n\t\t\t\tthis.dragging = true\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Something left the browser, or one of its children. The drop state\n\t\t * ends only when the drag has left the browser itself.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonDragLeave() {\n\t\t\tthis.dragDepth = Math.max(0, this.dragDepth - 1)\n\t\t\tif (this.dragDepth === 0) {\n\t\t\t\tthis.dragging = false\n\t\t\t\tthis.dropStatus = ''\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * How many files a drag carries, or null when the browser does not\n\t\t * say (it lists the items only once they are dropped in some browsers).\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {number|null}\n\t\t */\n\t\tdraggedFileCount(event) {\n\t\t\tconst items = event?.dataTransfer?.items\n\t\t\tif (!items || typeof items.length !== 'number') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst count = Array.from(items).filter((item) => item && item.kind === 'file').length\n\t\t\treturn count > 0 ? count : null\n\t\t},\n\n\t\t/**\n\t\t * Whether a drag carries files (not text or a link from the page).\n\t\t * A drag whose types cannot be read counts as files, as before.\n\t\t *\n\t\t * @param {DragEvent} event The drag.\n\t\t * @return {boolean}\n\t\t */\n\t\tcarriesFiles(event) {\n\t\t\tconst types = event?.dataTransfer?.types\n\t\t\tif (!types) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn Array.from(types).includes('Files')\n\t\t},\n\n\t\t/**\n\t\t * PUT each file into the open folder over DAV, with a progress row\n\t\t * each, then re-read the folder once.\n\t\t *\n\t\t * @param {FileList|File[]} files The files.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync uploadFiles(files) {\n\t\t\tif (this.folder === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// A PUT through axios rather than the DAV client: the client's\n\t\t\t// putFileContents refuses a browser File (\"Cannot calculate data\n\t\t\t// length\"), and fetch reports no upload progress anyway. axios\n\t\t\t// carries the session and the request token, and its XHR reports\n\t\t\t// progress per file. If-None-Match: * refuses to overwrite.\n\t\t\tconst batch = [...files].map((file) => ({ key: `u${++uploadSeq}`, name: file.name, progress: 0, error: '', file }))\n\t\t\tthis.uploads = [...this.uploads, ...batch]\n\t\t\tfor (const upload of batch) {\n\t\t\t\tif (this.source) {\n\t\t\t\t\tawait this.uploadThroughSource(upload)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait axios.put(`${getRemoteURL()}${this.davPath(joinPath(this.currentPath, upload.name))}`, upload.file, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t'Content-Type': upload.file.type || 'application/octet-stream',\n\t\t\t\t\t\t\t'If-None-Match': '*',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonUploadProgress: (progress) => {\n\t\t\t\t\t\t\tif (progress?.total) {\n\t\t\t\t\t\t\t\tupload.progress = Math.round((progress.loaded / progress.total) * 100)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\tupload.progress = 100\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst status = err?.response?.status ?? err?.status\n\t\t\t\t\tupload.error = status === 412\n\t\t\t\t\t\t? t('nextcloud-vue', 'A file with that name is already here')\n\t\t\t\t\t\t: (err?.message || t('nextcloud-vue', 'The upload failed'))\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait this.refresh()\n\t\t\tthis.$emit('changed')\n\t\t\t// Finished rows leave the list; failed ones stay with their reason.\n\t\t\twindow.setTimeout(() => {\n\t\t\t\tthis.uploads = this.uploads.filter((upload) => upload.error !== '' || batch.every((b) => b.key !== upload.key))\n\t\t\t}, 1500)\n\t\t},\n\n\t\t/**\n\t\t * Store one upload through the `source`, keeping its progress row.\n\t\t *\n\t\t * @param {object} upload The progress row, carrying the file.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync uploadThroughSource(upload) {\n\t\t\ttry {\n\t\t\t\tawait this.source.upload(this.currentPath, upload.file, (percent) => {\n\t\t\t\t\tupload.progress = percent\n\t\t\t\t})\n\t\t\t\tupload.progress = 100\n\t\t\t} catch (err) {\n\t\t\t\tupload.error = err?.status === 409\n\t\t\t\t\t? t('nextcloud-vue', 'A file with that name is already here')\n\t\t\t\t\t: (err?.message || t('nextcloud-vue', 'The upload failed'))\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Change the sort column, or flip the order on the same one.\n\t\t *\n\t\t * @param {string} key `basename`, `size` or `mtime`.\n\t\t * @return {void}\n\t\t */\n\t\t/**\n\t\t * The PROPFIND this browser sends: the Files app's own body, plus one\n\t\t * `<prop>` for every DAV property a declared `attribute` column reads,\n\t\t * so that value is on the node when the folder lists rather than one\n\t\t * request later.\n\t\t *\n\t\t * @return {string} The PROPFIND body.\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\tpropfindBody() {\n\t\t\tconst base = getDefaultPropfind()\n\t\t\tconst extra = attributePropertiesFor(this.declaredColumns)\n\t\t\tif (extra.length === 0) {\n\t\t\t\treturn base\n\t\t\t}\n\t\t\tconst props = extra.map((name) => {\n\t\t\t\tconst match = /^\\{(.+)\\}(.+)$/.exec(name)\n\t\t\t\tif (!match) {\n\t\t\t\t\treturn `<d:${name} />`\n\t\t\t\t}\n\t\t\t\treturn `<x-cn:${match[2]} xmlns:x-cn=\"${match[1]}\" />`\n\t\t\t}).join('')\n\t\t\t// Spliced into the existing <d:prop> rather than appended after it:\n\t\t\t// a second <d:prop> block is not a PROPFIND any server answers.\n\t\t\treturn base.includes('</d:prop>')\n\t\t\t\t? base.replace('</d:prop>', `${props}</d:prop>`)\n\t\t\t\t: base\n\t\t},\n\n\t\t/**\n\t\t * The token a column sorts under: the Files app's own sorting mode for\n\t\t * a built-in, the column key for anything else.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {string} The sort token.\n\t\t */\n\t\tsortTokenOf(column) {\n\t\t\treturn (column && (column.sortKey || column.key)) || ''\n\t\t},\n\n\t\t/**\n\t\t * The label a column's header shows: what the host wrote, else the\n\t\t * library's own word for a built-in, else the key.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {string} The header text.\n\t\t */\n\t\tcolumnLabel(column) {\n\t\t\tif (column && typeof column.label === 'string' && column.label !== '') {\n\t\t\t\treturn this.cnTranslate(column.label)\n\t\t\t}\n\t\t\treturn this.builtInColumnLabels[column && column.key] || (column && column.key) || ''\n\t\t},\n\n\t\t/**\n\t\t * One cell's value.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @param {object} node The node.\n\t\t * @return {(Array|object|string|number|boolean|undefined)} The value.\n\t\t */\n\t\tcellValue(column, node) {\n\t\t\treturn fileColumnValue(column, node, this.resolvedRowData)\n\t\t},\n\n\t\t/**\n\t\t * The tone a column or card field draws a value in: its `colorMap`\n\t\t * entry for the value (case-insensitive), read from the `colorKey` field\n\t\t * of the row when given, else from the value itself. '' without one.\n\t\t *\n\t\t * @param {object} column A resolved column or a side card field.\n\t\t * @param {object} node The node.\n\t\t * @return {string} A badge variant (`success`, `warning`, `error`, ...) or ''.\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-a-row-column-can-draw-its-values-in-tones\n\t\t */\n\t\ttoneOf(column, node) {\n\t\t\tconst map = column && column.colorMap\n\t\t\tif (!map || typeof map !== 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst raw = column.colorKey\n\t\t\t\t? fileColumnValue({ key: column.colorKey, source: 'row' }, node, this.resolvedRowData)\n\t\t\t\t: this.cellValue(column, node)\n\t\t\tif (raw === null || raw === undefined || typeof raw === 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst wanted = String(raw).toLowerCase()\n\t\t\tconst hit = Object.keys(map).find((key) => key.toLowerCase() === wanted)\n\t\t\treturn hit ? String(map[hit]) : ''\n\t\t},\n\n\t\t/**\n\t\t * The widget props a cell gets: the column's own, and for a `badge`\n\t\t * its tone as the variant.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @param {object} node The node.\n\t\t * @return {object|null}\n\t\t */\n\t\tcellWidgetProps(column, node) {\n\t\t\tif (column.widget !== 'badge') {\n\t\t\t\treturn column.widgetProps || null\n\t\t\t}\n\t\t\tconst tone = this.toneOf(column, node)\n\t\t\treturn { ...(column.widgetProps || {}), ...(tone ? { variant: tone } : {}) }\n\t\t},\n\n\t\t/**\n\t\t * The side cards for a file, resolved: the title with `{name}` filled\n\t\t * in, the fields that have a value with their tone, and the actions.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {Array<{id: string, title: string, fields: Array<object>, actions: Array<object>}>}\n\t\t * @spec openspec/changes/files-browser-side-cards/specs/files-browser/spec.md#requirement-cards-beside-the-list-describe-the-selected-file\n\t\t */\n\t\tsideCardsFor(node) {\n\t\t\treturn this.sideCards\n\t\t\t\t.filter((card) => card && card.id)\n\t\t\t\t.map((card) => ({\n\t\t\t\t\tid: String(card.id),\n\t\t\t\t\ttitle: this.cnTranslate(String(card.title || '')).replace(/\\{name\\}/g, node.basename),\n\t\t\t\t\tfields: (Array.isArray(card.fields) ? card.fields : [])\n\t\t\t\t\t\t.filter((field) => field && field.key)\n\t\t\t\t\t\t.map((field) => {\n\t\t\t\t\t\t\tconst column = { ...field, source: field.source || 'row' }\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tkey: String(field.key),\n\t\t\t\t\t\t\t\tlabel: this.cnTranslate(String(field.label || field.key)),\n\t\t\t\t\t\t\t\tvalue: this.cellValue(column, node),\n\t\t\t\t\t\t\t\tformatter: field.formatter,\n\t\t\t\t\t\t\t\tformatterOptions: field.formatterOptions,\n\t\t\t\t\t\t\t\ttone: this.toneOf(column, node),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter((field) => field.value !== null && field.value !== undefined && field.value !== ''),\n\t\t\t\t\tactions: (Array.isArray(card.actions) ? card.actions : [])\n\t\t\t\t\t\t.filter((action) => action && action.id && hostActionApplies(action, node, this.rowValueOf(node))),\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Whether a user currently sees a column, for the chooser's ticks.\n\t\t *\n\t\t * @param {object} column A resolved column.\n\t\t * @return {boolean} True when it renders.\n\t\t */\n\t\tisColumnVisible(column) {\n\t\t\treturn this.renderedColumns.some((c) => c.key === column.key)\n\t\t},\n\n\t\t/**\n\t\t * Tick or untick a column for this user and remember it.\n\t\t *\n\t\t * The stored value is always rebuilt from the host's declaration, never\n\t\t * from the previous stored value, so a key the host has since dropped\n\t\t * cannot survive a toggle and reappear later.\n\t\t *\n\t\t * @param {object} column The column being toggled.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/files-browser-columns/specs/files-browser/spec.md\n\t\t */\n\t\ttoggleColumn(column) {\n\t\t\tconst next = this.declaredColumns\n\t\t\t\t.filter((c) => (c.key === column.key ? !this.isColumnVisible(c) : this.isColumnVisible(c)))\n\t\t\t\t.map((c) => c.key)\n\t\t\tthis.visibleColumnKeys = next\n\t\t\tthis.saveColumnChoice(next)\n\t\t},\n\n\t\t/**\n\t\t * Read this user's column choice. A stored key the host no longer\n\t\t * declares is dropped on the way in as well as on the way out, so the\n\t\t * chooser never lists a column that cannot render.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync loadColumnChoice() {\n\t\t\tif (!this.columnsChooserEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst stored = await readUserPreference(this.preferenceApp, this.preferenceKey, null)\n\t\t\tif (!Array.isArray(stored)) {\n\t\t\t\tthis.visibleColumnKeys = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst declared = new Set(this.declaredColumns.map((c) => c.key))\n\t\t\tthis.visibleColumnKeys = stored.filter((key) => declared.has(key))\n\t\t},\n\n\t\t/**\n\t\t * Store this user's column choice.\n\t\t *\n\t\t * @param {string[]} keys The visible column keys.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync saveColumnChoice(keys) {\n\t\t\tif (!this.columnsChooserEnabled) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tawait writeUserPreference(this.preferenceApp, this.preferenceKey, keys)\n\t\t},\n\n\t\t/**\n\t\t * Resolve the host's per-file data for this folder's nodes. Called once\n\t\t * per listing, so a projection of ninety files is one request.\n\t\t *\n\t\t * @param {Array<object>} nodes The listed nodes.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync resolveRowData(nodes) {\n\t\t\tif (this.rowData === null || this.rowData === undefined) {\n\t\t\t\tthis.resolvedRowData = null\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (typeof this.rowData !== 'function') {\n\t\t\t\tthis.resolvedRowData = this.rowData\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.resolvedRowData = await this.rowData(nodes)\n\t\t\t} catch {\n\t\t\t\t// A projection that could not be fetched leaves those cells\n\t\t\t\t// empty. It is not a reason to say the folder failed to list:\n\t\t\t\t// the files are there and the host's extra columns are not.\n\t\t\t\tthis.resolvedRowData = null\n\t\t\t}\n\t\t},\n\n\t\tsortBy(key) {\n\t\t\tif (this.sortKey === key) {\n\t\t\t\tthis.sortAsc = !this.sortAsc\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.sortKey = key\n\t\t\t// Size and modified read most usefully largest and newest first;\n\t\t\t// everything else, including every declared column, starts at A.\n\t\t\tthis.sortAsc = key !== 'size' && key !== 'mtime'\n\t\t},\n\n\t\t/**\n\t\t * The `aria-sort` value for a column header.\n\t\t *\n\t\t * @param {string} key The column's sort key.\n\t\t * @return {string|null} `ascending`, `descending` or null.\n\t\t */\n\t\tariaSort(key) {\n\t\t\tif (this.sortKey !== key) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.sortAsc ? 'ascending' : 'descending'\n\t\t},\n\n\t\t/**\n\t\t * The arrow beside the sorted column's name.\n\t\t *\n\t\t * @param {string} key The column's sort key.\n\t\t * @return {object} The icon component.\n\t\t */\n\t\tsortIcon(key) {\n\t\t\treturn this.sortKey === key && !this.sortAsc ? ChevronDown : ChevronUp\n\t\t},\n\n\t\t/**\n\t\t * A file's size the way the Files app prints it.\n\t\t *\n\t\t * @param {number|undefined} size The size in bytes.\n\t\t * @return {string} The size, or the empty string.\n\t\t */\n\t\tformatSize(size) {\n\t\t\treturn typeof size === 'number' ? formatFileSize(size, true) : ''\n\t\t},\n\n\t\t/**\n\t\t * The theme's own icon for a node's mime type, or null off Nextcloud.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string|null} The icon url.\n\t\t */\n\t\tmimeIconFor(node) {\n\t\t\tconst getIconUrl = typeof window !== 'undefined' ? window.OC?.MimeType?.getIconUrl : null\n\t\t\tif (typeof getIconUrl !== 'function') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn getIconUrl(this.isFolder(node) ? 'dir' : (node.mime || '')) || null\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A small preview for a raster image, from the core preview endpoint.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string|null} The url, or null.\n\t\t */\n\t\tpreviewUrlFor(node) {\n\t\t\tconst mime = node.mime || ''\n\t\t\tif (!node.fileid || this.isFolder(node) || !/^image\\//i.test(mime) || /svg/i.test(mime) || this.previewFailed[node.fileid]) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (this.source) {\n\t\t\t\treturn typeof this.source.previewUrl === 'function' ? this.source.previewUrl(node) : null\n\t\t\t}\n\t\t\treturn generateUrl('/core/preview?fileId={fileId}&x=64&y=64&a=1', { fileId: node.fileid })\n\t\t},\n\n\t\t/**\n\t\t * Remember a preview that did not load.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {void}\n\t\t */\n\t\tonPreviewError(node) {\n\t\t\tthis.previewFailed = { ...this.previewFailed, [node.fileid]: true }\n\t\t},\n\n\t\t/**\n\t\t * The Files app opened on a folder, for the crumbs above the root.\n\t\t *\n\t\t * @param {string} path The user-relative folder path.\n\t\t * @return {string} The url.\n\t\t */\n\t\tfilesAppUrl(path) {\n\t\t\treturn generateUrl('/apps/files/files?dir={dir}', { dir: path })\n\t\t},\n\n\t\t/**\n\t\t * The Files app's permalink for a node.\n\t\t *\n\t\t * @param {object} node The node.\n\t\t * @return {string} The url.\n\t\t */\n\t\tpermalink(node) {\n\t\t\treturn generateUrl('/f/{fileid}', { fileid: node.fileid })\n\t\t},\n\n\t\t/**\n\t\t * Whether a file is selected.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {boolean} True when selected.\n\t\t */\n\t\tisSelected(node) {\n\t\t\treturn this.selectedIds.includes(String(node.fileid))\n\t\t},\n\n\t\t/**\n\t\t * Select or deselect one file.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @param {boolean} checked Whether it is now selected.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleSelected(node, checked) {\n\t\t\tconst id = String(node.fileid)\n\t\t\tconst rest = this.selectedIds.filter((entry) => entry !== id)\n\t\t\tthis.selectedIds = checked ? [...rest, id] : rest\n\t\t},\n\n\t\t/**\n\t\t * Select every file the filter keeps, or none.\n\t\t *\n\t\t * @param {boolean} checked Whether to select all.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleAll(checked) {\n\t\t\tthis.selectedIds = checked ? [...this.selectableIds] : []\n\t\t},\n\n\t\t/** Drop the selection. */\n\t\tclearSelection() {\n\t\t\tthis.selectedIds = []\n\t\t},\n\n\t\t/**\n\t\t * Run one of the host's bulk actions on the selected files, then drop\n\t\t * the selection. An `open-modal` action's props gain `files` and\n\t\t * `fileIds`; a `handler` action's args gain the selected nodes.\n\t\t *\n\t\t * @param {object} action The declared bulk action.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\trunBulkAction(action) {\n\t\t\tif (!action || typeof action !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst nodes = this.fileNodes.filter((node) => this.selectedIds.includes(String(node.fileid)))\n\t\t\tconst type = action.type || 'handler'\n\t\t\tlet wrapped = action\n\t\t\tif (type === 'open-modal') {\n\t\t\t\tconst files = nodes.map((node) => ({ fileId: node.fileid, fileName: node.basename, path: node.path }))\n\t\t\t\twrapped = { ...action, props: { ...(action.props || {}), files, fileIds: files.map((file) => file.fileId) } }\n\t\t\t} else if (type === 'handler') {\n\t\t\t\twrapped = { ...action, args: [...(action.args || []), nodes] }\n\t\t\t}\n\t\t\tthis.selectedIds = []\n\t\t\tif (typeof this.cnDispatchAction === 'function') {\n\t\t\t\tthis.cnDispatchAction(wrapped)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdispatchAction(wrapped, { router: this.$router || null })\n\t\t},\n\n\t\t/**\n\t\t * Choose or drop one facet value.\n\t\t *\n\t\t * @param {string} key The column key.\n\t\t * @param {string} value The value.\n\t\t * @return {void}\n\t\t */\n\t\ttoggleFacet(key, value) {\n\t\t\tconst chosen = this.facetSelections[key] || []\n\t\t\tconst next = chosen.includes(value) ? chosen.filter((entry) => entry !== value) : [...chosen, value]\n\t\t\tthis.facetSelections = { ...this.facetSelections, [key]: next }\n\t\t},\n\n\t\t/** Drop every facet choice. */\n\t\tclearFacets() {\n\t\t\tthis.facetSelections = {}\n\t\t},\n\n\t\t/**\n\t\t * The host's own row actions that belong on this file: those whose\n\t\t * `visibleIf` (extension, mime) holds for it, or that name none.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {Array<object>} The actions to offer.\n\t\t * @spec openspec/changes/files-browser-hosts-a-documents-list/specs/files-browser/spec.md\n\t\t */\n\t\thostActionsFor(node) {\n\t\t\treturn this.rowActions.filter((action) => hostActionApplies(action, node, this.rowValueOf(node)))\n\t\t},\n\n\t\t/**\n\t\t * A reader of the host's row fields for one file, for `visibleIf.row`.\n\t\t *\n\t\t * @param {object} node The file.\n\t\t * @return {(key: string) => unknown} `(key) => value` over the row the host gave for the file.\n\t\t * @spec openspec/changes/files-browser-action-visible-if-row/specs/files-browser/spec.md#requirement-a-host-action-can-be-offered-by-a-field-of-the-files-row\n\t\t */\n\t\trowValueOf(node) {\n\t\t\treturn (key) => fileColumnValue({ key, source: 'row' }, node, this.resolvedRowData)\n\t\t},\n\n\t\t/**\n\t\t * Run one of the host's declared actions on a file.\n\t\t *\n\t\t * An `open-modal` action gets the node merged onto its props as\n\t\t * `fileId`, `fileName` and `path`, the same way a widget's row action\n\t\t * hands a modal its row; a `handler` action gets the node appended to\n\t\t * its args. Everything else is dispatched as declared.\n\t\t *\n\t\t * @param {object} action The declared action.\n\t\t * @param {object} node The file it was clicked on.\n\t\t * @return {void}\n\t\t */\n\t\trunHostAction(action, node) {\n\t\t\tif (!action || typeof action !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = action.type || 'handler'\n\t\t\tlet wrapped = action\n\t\t\t// A New-menu entry carries no row, only the folder it was opened in.\n\t\t\tconst context = node === null\n\t\t\t\t? { path: this.currentPath }\n\t\t\t\t: { fileId: node.fileid, fileName: node.basename, path: node.path }\n\t\t\tif (type === 'open-modal') {\n\t\t\t\twrapped = { ...action, props: { ...(action.props || {}), ...context, ...this.rowPropsOf(action, node) } }\n\t\t\t} else if (type === 'handler') {\n\t\t\t\twrapped = { ...action, args: [...(action.args || []), node ?? this.folder] }\n\t\t\t}\n\t\t\tif (typeof this.cnDispatchAction === 'function') {\n\t\t\t\tthis.cnDispatchAction(wrapped)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdispatchAction(wrapped, { router: this.$router || null })\n\t\t},\n\n\t\t/**\n\t\t * The clicked file's row-data fields an action asks for as modal props\n\t\t * (`rowProps: { prop: field }`), or none.\n\t\t *\n\t\t * @param {object} action The declared action.\n\t\t * @param {object|null} node The file, or null for a New-menu entry.\n\t\t * @return {object} The props.\n\t\t * @spec openspec/changes/files-review-row-when/specs/files-review-row-when/spec.md#requirement-a-modal-action-can-carry-fields-of-the-clicked-files-row-data\n\t\t */\n\t\trowPropsOf(action, node) {\n\t\t\tconst wanted = action && action.rowProps\n\t\t\tif (node === null || !wanted || typeof wanted !== 'object') {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst byId = this.resolvedRowData && typeof this.resolvedRowData === 'object' ? this.resolvedRowData : {}\n\t\t\tconst entry = byId[node.fileid] ?? byId[String(node.fileid)] ?? {}\n\t\t\tconst out = {}\n\t\t\tfor (const [prop, field] of Object.entries(wanted)) {\n\t\t\t\tconst value = readPath(entry, String(field))\n\t\t\t\tif (value !== undefined && value !== null && value !== '') {\n\t\t\t\t\tout[prop] = value\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * A click on a linked row opens the file where it lives.\n\t\t *\n\t\t * @param {object} item The linked item.\n\t\t * @return {void}\n\t\t */\n\t\topenLinked(item) {\n\t\t\tif (item.href && typeof window !== 'undefined') {\n\t\t\t\twindow.open(item.href, '_blank', 'noopener')\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A middle click on a linked row opens it like a click does.\n\t\t *\n\t\t * @param {object} item The linked item.\n\t\t * @param {MouseEvent} event The auxclick event.\n\t\t * @return {void}\n\t\t */\n\t\tonLinkedAuxClick(item, event) {\n\t\t\tif (isRowMiddleClick(event)) {\n\t\t\t\tthis.openLinked(item)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The current user's id, for callers resolving a root path.\n\t\t *\n\t\t * @return {string} The uid, or the empty string.\n\t\t */\n\t\tcurrentUid() {\n\t\t\treturn getCurrentUser()?.uid || ''\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-files-browser {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmin-width: 0;\n\tposition: relative;\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-files-browser--dragging {\n\toutline: 2px dashed var(--color-primary-element);\n\toutline-offset: 4px;\n}\n\n/* With a `dropDetail` the drop state fills the panel it sits in, as the\n board draws it (DqZaakDocumentenSlepen), not only the list's own height. */\n.cn-files-browser--dragging.cn-files-browser--drop-panel {\n\tmin-height: max(320px, 100%);\n}\n\n.cn-files-browser__drop-detail {\n\tmax-width: 520px;\n\tfont-size: 14px;\n\tcolor: var(--color-main-text);\n}\n\n.cn-files-browser__drop-overlay {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 2;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 10px;\n\tpadding: 24px;\n\tbox-sizing: border-box;\n\tborder: 2px dashed var(--color-primary-element);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element-light-text, var(--color-main-text));\n\ttext-align: center;\n\tpointer-events: none;\n}\n\n.cn-files-browser__drop-icon {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 56px;\n\theight: 56px;\n\tborder-radius: 50%;\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-primary-element);\n}\n\n.cn-files-browser__drop-label {\n\tfont-size: 20px;\n\tfont-weight: 700;\n}\n\n.cn-files-browser__drop-hint {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding-top: 12px;\n\tborder-top: 1px solid var(--color-border);\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__bar {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tmin-width: 0;\n}\n\n.cn-files-browser__crumbs {\n\tmin-width: 0;\n\tflex: 1 1 auto;\n}\n\n/* The crumbs give way, the controls do not: a long crumb (a folder named\n after a uuid) shrank the upload button to \"Bestanden...\" while the crumbs\n kept their width. */\n.cn-files-browser__bar > :not(.cn-files-browser__crumbs) {\n\tflex-shrink: 0;\n}\n\n.cn-files-browser__file-input {\n\tdisplay: none;\n}\n\n.cn-files-browser__uploads {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.cn-files-browser__upload {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-files-browser__upload-name {\n\tfont-size: 13px;\n}\n\n.cn-files-browser__upload-error {\n\tcolor: var(--color-error);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__loading {\n\tpadding: 24px 0;\n}\n\n/* `sideCards`: the list and, while a file is selected, a column of cards. */\n.cn-files-browser__body--with-side {\n\tdisplay: grid;\n\tgrid-template-columns: minmax(0, 1fr) minmax(240px, 300px);\n\talign-items: start;\n\tgap: 16px;\n}\n\n@media (max-width: 900px) {\n\t.cn-files-browser__body--with-side {\n\t\tgrid-template-columns: minmax(0, 1fr);\n\t}\n}\n\n.cn-files-browser__side {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n/* In the detail page's side column the cards take its gap and its card\n anatomy, as the page's own side cards are drawn. */\n.cn-files-browser__side--in-page {\n\tgap: calc(5 * var(--default-grid-baseline));\n}\n\n.cn-files-browser__side--in-page .cn-files-browser__side-card {\n\tpadding: var(--cn-board-card-padding, 16px 18px);\n\tborder-radius: var(--cn-board-card-radius, var(--border-radius-large));\n}\n\n.cn-files-browser__side-card {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tpadding: 16px 18px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tbackground: var(--color-main-background);\n}\n\n.cn-files-browser__side-title {\n\tmargin: 0;\n\tfont-size: 15px;\n\tfont-weight: 700;\n\toverflow-wrap: anywhere;\n}\n\n.cn-files-browser__side-facts {\n\tdisplay: grid;\n\tgrid-template-columns: max-content minmax(0, 1fr);\n\tgap: 6px 12px;\n\tmargin: 0;\n\tfont-size: 14px;\n}\n\n/* Core's apps.css draws every dt/dd inline-block with a fixed, end-aligned dt.\n @spec openspec/changes/files-side-facts-core-dl/specs/files-side-facts-core-dl/spec.md#requirement-a-file-side-cards-facts-are-not-drawn-by-cores-dl-rules */\n.cn-files-browser__side-facts dt,\n.cn-files-browser__side-facts dd {\n\tdisplay: block;\n\twidth: auto;\n\tpadding: 0;\n\ttext-align: start;\n\twhite-space: normal;\n}\n\n.cn-files-browser__side-facts dt {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__side-facts dd {\n\tmargin: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-files-browser__side-actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n\n/* A value drawn in a tone (`colorMap` on a column that is not a badge): the\n text in the tone's colour, as the boards write a restricted level. */\n.cn-files-browser__tone {\n\tfont-weight: 600;\n}\n\n.cn-files-browser__tone--success {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-files-browser__tone--warning {\n\tcolor: var(--color-warning-text, var(--color-warning));\n}\n\n.cn-files-browser__tone--error {\n\tcolor: var(--color-error-text, var(--color-error));\n}\n\n.cn-files-browser__tone--primary,\n.cn-files-browser__tone--info {\n\tcolor: var(--color-primary-element-light-text, var(--color-primary-element));\n}\n\n.cn-files-browser__table {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n}\n\n.cn-files-browser__table th {\n\ttext-align: start;\n\tfont-weight: normal;\n\tcolor: var(--color-text-maxcontrast);\n\tpadding: 4px 8px;\n\tborder-bottom: 1px solid var(--color-border);\n}\n\n.cn-files-browser__sort {\n\tbackground: none;\n\tborder: none;\n\tpadding: 0;\n\tfont: inherit;\n\tcolor: inherit;\n\tcursor: pointer;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 2px;\n}\n\n.cn-files-browser__sort:hover,\n.cn-files-browser__sort:focus-visible {\n\tcolor: var(--color-main-text);\n}\n\n.cn-files-browser__row {\n\tcursor: pointer;\n}\n\n.cn-files-browser__row:hover,\n.cn-files-browser__row:focus-within {\n\tbackground-color: var(--color-background-hover);\n}\n\n.cn-files-browser__table td {\n\tpadding: 4px 8px;\n\tborder-bottom: 1px solid var(--color-border);\n\tvertical-align: middle;\n}\n\n.cn-files-browser__col-icon {\n\twidth: 48px;\n}\n\n.cn-files-browser__col-size {\n\twidth: 96px;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-mtime {\n\twidth: 140px;\n\twhite-space: nowrap;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-select {\n\twidth: 36px;\n\ttext-align: center;\n}\n\n.cn-files-browser__select {\n\twidth: 18px;\n\theight: 18px;\n\tmargin: 0;\n\taccent-color: var(--color-primary-element);\n}\n\n.cn-files-browser__bulk-bar {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 8px 12px;\n\tborder-radius: var(--border-radius-large);\n\tbackground: var(--color-primary-element-light);\n}\n\n.cn-files-browser__bulk-count {\n\tfont-weight: 600;\n\tmargin-inline-end: 8px;\n}\n\n.cn-files-browser__review {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tmargin-block-end: 12px;\n\tpadding: 14px 16px;\n\tborder-radius: 10px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-files-browser__review-head {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: baseline;\n\tjustify-content: space-between;\n\tgap: 8px;\n}\n\n.cn-files-browser__review-title {\n\tfont-size: 15px;\n}\n\n.cn-files-browser__review-sub {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__review-bar {\n\tdisplay: flex;\n\theight: 8px;\n\toverflow: hidden;\n\tborder-radius: 4px;\n\tbackground: var(--color-border);\n}\n\n.cn-files-browser__review-legend {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px 18px;\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 14px;\n\tlist-style: none;\n}\n\n.cn-files-browser__review-legend li {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 8px;\n}\n\n.cn-files-browser__review-dot {\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 5px;\n}\n\n.cn-files-browser__review-part--success {\n\tbackground: var(--color-success-text, var(--color-success));\n}\n\n.cn-files-browser__review-part--warning {\n\tbackground: var(--color-warning);\n}\n\n.cn-files-browser__review-part--error {\n\tbackground: var(--color-error-text, var(--color-error));\n}\n\n.cn-files-browser__review-part--info {\n\tbackground: var(--color-primary-element);\n}\n\n.cn-files-browser__review-part--default {\n\tbackground: var(--color-border-dark);\n}\n\n.cn-files-browser__row-button {\n\tdisplay: inline-flex;\n\tvertical-align: middle;\n}\n\n.cn-files-browser__facets {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px 16px;\n}\n\n.cn-files-browser__facet {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 6px;\n}\n\n.cn-files-browser__facet-chip {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tmin-height: 32px;\n\tpadding: 0 12px;\n\tborder: 1px solid var(--color-border-dark);\n\tborder-radius: var(--border-radius-pill);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-files-browser__facet-chip--active {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element-light);\n}\n\n.cn-files-browser__group-heading {\n\tpadding: 12px 8px 4px;\n\ttext-align: start;\n\tfont-weight: 700;\n}\n\n.cn-files-browser__group-count {\n\tmargin-inline-start: 6px;\n\tfont-weight: 400;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__no-match {\n\tpadding: 16px 8px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__col-actions {\n\twidth: 48px;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__col-actions:has(.cn-files-browser__row-button) {\n\twidth: auto;\n}\n\n/* The row button and the row menu stand side by side on one line, not\n stacked (DqZaakDocumenten: Beoordelen, then the menu, 14px apart).\n @spec openspec/changes/files-row-button-beside-menu/specs/files-row-button-beside-menu/spec.md#requirement-a-files-row-button-stands-beside-the-row-menu */\n.cn-files-browser__col-actions > .cn-files-browser__row-button,\n.cn-files-browser__col-actions > .cn-files-browser__row-menu {\n\tdisplay: inline-flex;\n\tvertical-align: middle;\n}\n\n.cn-files-browser__col-actions > .cn-files-browser__row-button + .cn-files-browser__row-menu {\n\tmargin-inline-start: 14px;\n}\n\n.cn-files-browser__col-name {\n\tmin-width: 0;\n}\n\n.cn-files-browser__name {\n\tdisplay: block;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__name-secondary {\n\tdisplay: block;\n\toverflow: hidden;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.cn-files-browser__footnote {\n\tmargin: 0;\n\tpadding-top: 12px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-files-browser__row--linked {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-files-browser__note {\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: block;\n\tfont-size: var(--font-size-small, 13px);\n}\n\n.cn-files-browser__note-link {\n\tcolor: inherit;\n\ttext-decoration: underline;\n}\n\n.cn-files-browser__row--folder .cn-files-browser__name {\n\tfont-weight: 600;\n}\n\n.cn-files-browser__mime,\n.cn-files-browser__thumb {\n\twidth: 32px;\n\theight: 32px;\n\tdisplay: block;\n}\n\n.cn-files-browser__thumb {\n\tobject-fit: cover;\n\tborder-radius: var(--border-radius, 4px);\n}\n\n.cn-files-browser__new-folder {\n\tpadding: 8px 0;\n}\n\n.hidden-visually {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n\twhite-space: nowrap;\n}\n</style>\n"],"names":["CnCellRenderer","CnIcon","CnEmptyContent","t","n","axios"],"mappings":"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"}
|