You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 lines
30 KiB
1 lines
30 KiB
{"version":3,"file":"files_trashbin-init.mjs","sources":["../node_modules/@nextcloud/vue/dist/chunks/NcUserBubble-DPAmU2_J.mjs","../node_modules/@mdi/svg/svg/history.svg?raw","../node_modules/@mdi/svg/svg/trash-can-outline.svg?raw","../build/frontend/apps/files_trashbin/src/services/client.ts","../build/frontend/apps/files_trashbin/src/services/trashbin.ts","../build/frontend/apps/files_trashbin/src/files_views/columns.ts","../build/frontend/apps/files_trashbin/src/files_views/trashbinView.ts","../build/frontend/apps/files_trashbin/src/logger.ts","../build/frontend/apps/files_trashbin/src/files_actions/restoreAction.ts","../build/frontend/apps/files_trashbin/src/services/api.ts","../build/frontend/apps/files_trashbin/src/files_listActions/emptyTrashAction.ts","../build/frontend/apps/files_trashbin/src/files-init.ts"],"sourcesContent":["import '../assets/NcUserBubble-B3Jad98g.css';\nimport { createElementBlock, openBlock, renderSlot, defineComponent, mergeModels, useModel, computed, warn, watch, createBlock, resolveDynamicComponent, withCtx, mergeProps, createVNode, createElementVNode, createCommentVNode, normalizeStyle, toDisplayString } from \"vue\";\nimport { RouterLink } from \"vue-router\";\nimport { N as NcAvatar } from \"./NcAvatar-DmUGApWA.mjs\";\nimport { N as NcPopover } from \"./NcPopover-C-MTaPCs.mjs\";\nimport { _ as _export_sfc } from \"./_plugin-vue_export-helper-1tPrXgE0.mjs\";\nconst _sfc_main$1 = {};\nfunction _sfc_render(_ctx, _cache) {\n return openBlock(), createElementBlock(\"div\", null, [\n renderSlot(_ctx.$slots, \"trigger\")\n ]);\n}\nconst NcUserBubbleDiv = /* @__PURE__ */ _export_sfc(_sfc_main$1, [[\"render\", _sfc_render]]);\nconst _hoisted_1 = { class: \"user-bubble__name\" };\nconst _hoisted_2 = {\n key: 0,\n class: \"user-bubble__secondary\"\n};\nconst _sfc_main = /* @__PURE__ */ defineComponent({\n __name: \"NcUserBubble\",\n props: /* @__PURE__ */ mergeModels({\n avatarImage: { default: void 0 },\n user: { default: void 0 },\n displayName: { default: void 0 },\n showUserStatus: { type: Boolean },\n url: { default: void 0 },\n to: { default: void 0 },\n primary: { type: Boolean },\n size: { default: 20 },\n margin: { default: 2 }\n }, {\n \"open\": { type: Boolean },\n \"openModifiers\": {}\n }),\n emits: /* @__PURE__ */ mergeModels([\"click\"], [\"update:open\"]),\n setup(__props, { emit: __emit }) {\n const isOpen = useModel(__props, \"open\");\n const props = __props;\n const emit = __emit;\n const isAvatarUrl = computed(() => {\n if (!props.avatarImage) {\n return false;\n }\n try {\n const url = new URL(props.avatarImage);\n return !!url;\n } catch {\n return false;\n }\n });\n const isCustomAvatar = computed(() => !!props.avatarImage);\n const avatarStyle = computed(() => ({\n marginInlineStart: `${props.margin}px`\n }));\n const hasUrl = computed(() => {\n if (!props.url || props.url.trim() === \"\") {\n return false;\n }\n try {\n const url = new URL(props.url, props.url?.startsWith?.(\"/\") ? window.location.href : void 0);\n return !!url;\n } catch {\n warn(\"[NcUserBubble] Invalid URL passed\", { url: props.url });\n return false;\n }\n });\n const href = computed(() => hasUrl.value ? props.url : void 0);\n const contentComponent = computed(() => {\n if (hasUrl.value) {\n return \"a\";\n } else if (props.to) {\n return RouterLink;\n } else {\n return \"div\";\n }\n });\n const contentStyle = computed(() => ({\n height: `${props.size}px`,\n lineHeight: `${props.size}px`,\n borderRadius: `${props.size / 2}px`\n }));\n watch([() => props.displayName, () => props.user], () => {\n if (!props.displayName && !props.user) {\n warn(\"[NcUserBubble] At least `displayName` or `user` property should be set.\");\n }\n });\n return (_ctx, _cache) => {\n return openBlock(), createBlock(resolveDynamicComponent(!!_ctx.$slots.default ? NcPopover : NcUserBubbleDiv), {\n shown: isOpen.value,\n \"onUpdate:shown\": _cache[1] || (_cache[1] = ($event) => isOpen.value = $event),\n class: \"user-bubble__wrapper\",\n trigger: \"hover focus\"\n }, {\n trigger: withCtx(({ attrs }) => [\n (openBlock(), createBlock(resolveDynamicComponent(contentComponent.value), mergeProps({\n class: [\"user-bubble__content\", { \"user-bubble__content--primary\": _ctx.primary }],\n style: contentStyle.value,\n to: _ctx.to,\n href: href.value\n }, attrs, {\n onClick: _cache[0] || (_cache[0] = ($event) => emit(\"click\", $event))\n }), {\n default: withCtx(() => [\n createVNode(NcAvatar, {\n url: isCustomAvatar.value && isAvatarUrl.value ? _ctx.avatarImage : void 0,\n \"icon-class\": isCustomAvatar.value && !isAvatarUrl.value ? _ctx.avatarImage : void 0,\n user: _ctx.user,\n \"display-name\": _ctx.displayName,\n size: _ctx.size - _ctx.margin * 2,\n style: normalizeStyle(avatarStyle.value),\n \"disable-tooltip\": true,\n \"disable-menu\": true,\n \"hide-status\": !_ctx.showUserStatus,\n class: \"user-bubble__avatar\"\n }, null, 8, [\"url\", \"icon-class\", \"user\", \"display-name\", \"size\", \"style\", \"hide-status\"]),\n createElementVNode(\"span\", _hoisted_1, toDisplayString(_ctx.displayName || _ctx.user), 1),\n !!_ctx.$slots.name ? (openBlock(), createElementBlock(\"span\", _hoisted_2, [\n renderSlot(_ctx.$slots, \"name\", {}, void 0, true)\n ])) : createCommentVNode(\"\", true)\n ]),\n _: 2\n }, 1040, [\"class\", \"style\", \"to\", \"href\"]))\n ]),\n default: withCtx(() => [\n renderSlot(_ctx.$slots, \"default\", {}, void 0, true)\n ]),\n _: 3\n }, 40, [\"shown\"]);\n };\n }\n});\nconst NcUserBubble = /* @__PURE__ */ _export_sfc(_sfc_main, [[\"__scopeId\", \"data-v-ad356e41\"]]);\nexport {\n NcUserBubble as N\n};\n//# sourceMappingURL=NcUserBubble-DPAmU2_J.mjs.map\n","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" id=\\\"mdi-history\\\" viewBox=\\\"0 0 24 24\\\"><path d=\\\"M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3\\\" /></svg>\"","export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" id=\\\"mdi-trash-can-outline\\\" viewBox=\\\"0 0 24 24\\\"><path d=\\\"M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z\\\" /></svg>\"","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { getClient } from '@nextcloud/files/dav'\n\nexport const rootPath = `/trashbin/${getCurrentUser()?.uid}/trash`\n\nexport const client = getClient()\n","/*!\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { ContentsWithRoot, Folder, Node } from '@nextcloud/files'\nimport type { FileStat, ResponseDataDetailed } from 'webdav'\n\nimport { resultToNode as davResultToNode, getDavNameSpaces, getDavProperties } from '@nextcloud/files/dav'\nimport { generateUrl } from '@nextcloud/router'\nimport { client, rootPath } from './client.ts'\n\nconst data = `<?xml version=\"1.0\"?>\n<d:propfind ${getDavNameSpaces()}>\n\t<d:prop>\n\t\t<nc:trashbin-deletion-time />\n\t\t<nc:trashbin-original-location />\n\t\t<nc:trashbin-title />\n\t\t<nc:trashbin-deleted-by-id />\n\t\t<nc:trashbin-deleted-by-display-name />\n\t\t${getDavProperties()}\n\t</d:prop>\n</d:propfind>`\n\n/**\n * Converts a WebDAV file stat to a File or Folder\n * This will fix the preview URL attribute for trashbin items\n *\n * @param stat - The file stat object from WebDAV response\n */\nfunction resultToNode(stat: FileStat): Node {\n\tconst node = davResultToNode(stat, rootPath)\n\tnode.attributes.previewUrl = generateUrl('/apps/files_trashbin/preview?fileId={fileid}&x=32&y=32', { fileid: node.fileid })\n\treturn node\n}\n\n/**\n * Get the contents of a trashbin folder\n *\n * @param path - The path of the trashbin folder to get contents from\n */\nexport async function getContents(path = '/'): Promise<ContentsWithRoot> {\n\tconst contentsResponse = await client.getDirectoryContents(`${rootPath}${path}`, {\n\t\tdetails: true,\n\t\tdata,\n\t\tincludeSelf: true,\n\t}) as ResponseDataDetailed<FileStat[]>\n\n\tconst contents = contentsResponse.data.map(resultToNode)\n\tconst [folder] = contents.splice(contents.findIndex((node) => node.path === path), 1)\n\n\treturn {\n\t\tfolder: folder as Folder,\n\t\tcontents,\n\t}\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { Node } from '@nextcloud/files'\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { Column } from '@nextcloud/files'\nimport { formatRelativeTime, getCanonicalLocale, getLanguage, t } from '@nextcloud/l10n'\nimport { dirname } from '@nextcloud/paths'\nimport { createApp } from 'vue'\nimport NcUserBubble from '@nextcloud/vue/components/NcUserBubble'\n\nexport const originalLocation = new Column({\n\tid: 'files_trashbin--original-location',\n\ttitle: t('files_trashbin', 'Original location'),\n\trender(node) {\n\t\tconst originalLocation = parseOriginalLocation(node)\n\t\tconst span = document.createElement('span')\n\t\tspan.title = originalLocation\n\t\tspan.textContent = originalLocation\n\t\treturn span\n\t},\n\tsort(nodeA, nodeB) {\n\t\tconst locationA = parseOriginalLocation(nodeA)\n\t\tconst locationB = parseOriginalLocation(nodeB)\n\t\treturn locationA.localeCompare(locationB, [getLanguage(), getCanonicalLocale()], { numeric: true, usage: 'sort' })\n\t},\n})\n\nexport const deletedBy = new Column({\n\tid: 'files_trashbin--deleted-by',\n\ttitle: t('files_trashbin', 'Deleted by'),\n\trender(node) {\n\t\tconst { userId, displayName, label } = parseDeletedBy(node)\n\t\tif (label) {\n\t\t\tconst span = document.createElement('span')\n\t\t\tspan.textContent = label\n\t\t\treturn span\n\t\t}\n\n\t\tconst el = document.createElement('div')\n\t\tcreateApp(NcUserBubble, {\n\t\t\tsize: 32,\n\t\t\tuser: userId ?? undefined,\n\t\t\tdisplayName: displayName ?? userId,\n\t\t}).mount(el)\n\t\treturn el\n\t},\n\tsort(nodeA, nodeB) {\n\t\tconst deletedByA = parseDeletedBy(nodeA)\n\t\tconst deletedbyALabel = deletedByA.label ?? deletedByA.displayName ?? deletedByA.userId\n\t\tconst deletedByB = parseDeletedBy(nodeB)\n\t\tconst deletedByBLabel = deletedByB.label ?? deletedByB.displayName ?? deletedByB.userId\n\t\t// label is set if uid and display name are unset - if label is unset at least uid or display name is set.\n\t\treturn deletedbyALabel!.localeCompare(deletedByBLabel!, [getLanguage(), getCanonicalLocale()], { numeric: true, usage: 'sort' })\n\t},\n})\n\nexport const deleted = new Column({\n\tid: 'files_trashbin--deleted',\n\ttitle: t('files_trashbin', 'Deleted'),\n\n\trender(node) {\n\t\tconst deletionTime = node.attributes?.['trashbin-deletion-time'] || ((node?.mtime?.getTime() ?? 0) / 1000)\n\t\tconst span = document.createElement('span')\n\t\tif (deletionTime) {\n\t\t\tconst formatter = Intl.DateTimeFormat([getCanonicalLocale()], { dateStyle: 'long', timeStyle: 'short' })\n\t\t\tconst timestamp = new Date(deletionTime * 1000)\n\n\t\t\tspan.title = formatter.format(timestamp)\n\t\t\tspan.textContent = formatRelativeTime(timestamp, { ignoreSeconds: t('files', 'few seconds ago') })\n\t\t\treturn span\n\t\t}\n\n\t\t// Unknown deletion time\n\t\tspan.textContent = t('files_trashbin', 'A long time ago')\n\t\treturn span\n\t},\n\n\tsort(nodeA, nodeB) {\n\t\t// deletion time is a unix timestamp while mtime is a JS Date -> we need to align the numbers (seconds vs milliseconds)\n\t\tconst deletionTimeA = nodeA.attributes?.['trashbin-deletion-time'] || ((nodeA?.mtime?.getTime() ?? 0) / 1000)\n\t\tconst deletionTimeB = nodeB.attributes?.['trashbin-deletion-time'] || ((nodeB?.mtime?.getTime() ?? 0) / 1000)\n\t\treturn deletionTimeB - deletionTimeA\n\t},\n})\n\n/**\n * Get the original file location of a trashbin file.\n *\n * @param node The node to parse\n */\nfunction parseOriginalLocation(node: Node): string {\n\tconst path = stringOrNull(node.attributes?.['trashbin-original-location'])\n\tif (!path) {\n\t\treturn t('files_trashbin', 'Unknown')\n\t}\n\n\tconst dir = dirname(path)\n\tif (dir === '/' || dir === '.') { // Node is in root folder\n\t\treturn t('files_trashbin', 'All files')\n\t}\n\n\treturn dir.replace(/^\\//, '')\n}\n\n/**\n * Parse a trashbin file to get information about the user that deleted the file.\n *\n * @param node The node to parse\n */\nfunction parseDeletedBy(node: Node) {\n\tconst userId = stringOrNull(node.attributes?.['trashbin-deleted-by-id'])\n\tconst displayName = stringOrNull(node.attributes?.['trashbin-deleted-by-display-name'])\n\n\tlet label: string | undefined\n\tconst currentUserId = getCurrentUser()?.uid\n\tif (userId === currentUserId) {\n\t\tlabel = t('files_trashbin', 'You')\n\t}\n\tif (!userId && !displayName) {\n\t\tlabel = t('files_trashbin', 'Unknown')\n\t}\n\n\treturn {\n\t\tuserId,\n\t\tdisplayName,\n\t\tlabel,\n\t}\n}\n\n/**\n * If the attribute is given it will be stringified and returned - otherwise null is returned.\n *\n * @param attribute The attribute to check\n */\nfunction stringOrNull(attribute: unknown): string | null {\n\tif (attribute) {\n\t\treturn String(attribute)\n\t}\n\treturn null\n}\n","/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport svgDelete from '@mdi/svg/svg/trash-can-outline.svg?raw'\nimport { View } from '@nextcloud/files'\nimport { t } from '@nextcloud/l10n'\nimport { getContents } from '../services/trashbin.ts'\nimport { deleted, deletedBy, originalLocation } from './columns.ts'\n\nexport const TRASHBIN_VIEW_ID = 'trashbin'\n\nexport const trashbinView = new View({\n\tid: TRASHBIN_VIEW_ID,\n\tname: t('files_trashbin', 'Deleted files'),\n\tcaption: t('files_trashbin', 'List of files that have been deleted.'),\n\n\temptyTitle: t('files_trashbin', 'No deleted files'),\n\temptyCaption: t('files_trashbin', 'Files and folders you have deleted will show up here'),\n\n\ticon: svgDelete,\n\torder: 50,\n\tsticky: true,\n\n\tdefaultSortKey: 'deleted',\n\n\tcolumns: [\n\t\toriginalLocation,\n\t\tdeletedBy,\n\t\tdeleted,\n\t],\n\n\tgetContents,\n})\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nexport const logger = getLoggerBuilder()\n\t.setApp('files_trashbin')\n\t.detectUser()\n\t.build()\n","/*!\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport svgHistory from '@mdi/svg/svg/history.svg?raw'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios, { isAxiosError } from '@nextcloud/axios'\nimport { showError } from '@nextcloud/dialogs'\nimport { emit } from '@nextcloud/event-bus'\nimport { FileAction, Permission } from '@nextcloud/files'\nimport { t } from '@nextcloud/l10n'\nimport { encodePath } from '@nextcloud/paths'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { TRASHBIN_VIEW_ID } from '../files_views/trashbinView.ts'\nimport { logger } from '../logger.ts'\n\nexport const restoreAction = new FileAction({\n\tid: 'restore',\n\n\tdisplayName() {\n\t\treturn t('files_trashbin', 'Restore')\n\t},\n\n\ticonSvgInline: () => svgHistory,\n\n\tenabled({ nodes, view }) {\n\t\t// Only available in the trashbin view\n\t\tif (view.id !== TRASHBIN_VIEW_ID) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Only available if all nodes have read permission\n\t\treturn nodes.length > 0\n\t\t\t&& nodes\n\t\t\t\t.map((node) => node.permissions)\n\t\t\t\t.every((permission) => Boolean(permission & Permission.READ))\n\t},\n\n\tasync exec({ nodes }) {\n\t\tconst node = nodes[0]\n\t\ttry {\n\t\t\tconst destination = generateRemoteUrl(encodePath(`dav/trashbin/${getCurrentUser()!.uid}/restore/${node.basename}`))\n\t\t\tawait axios.request({\n\t\t\t\tmethod: 'MOVE',\n\t\t\t\turl: node.encodedSource,\n\t\t\t\theaders: {\n\t\t\t\t\tdestination,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\t// Let's pretend the file is deleted since\n\t\t\t// we don't know the restored location\n\t\t\temit('files:node:deleted', node)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tif (isAxiosError(error) && error.response?.status === 507) {\n\t\t\t\tshowError(t('files_trashbin', 'Not enough free space to restore the file/folder'))\n\t\t\t}\n\t\t\tlogger.error('Failed to restore node', { error, node })\n\t\t\treturn false\n\t\t}\n\t},\n\n\tasync execBatch({ nodes, view, folder, contents }) {\n\t\treturn Promise.all(nodes.map((node) => this.exec({ nodes: [node], view, folder, contents })))\n\t},\n\n\torder: 1,\n\n\tinline: () => true,\n})\n","/**\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getCurrentUser } from '@nextcloud/auth'\nimport axios from '@nextcloud/axios'\nimport { showError, showSuccess } from '@nextcloud/dialogs'\nimport { defaultRemoteURL } from '@nextcloud/files/dav'\nimport { t } from '@nextcloud/l10n'\nimport { logger } from '../logger.ts'\n\n/**\n * Send API request to empty the trashbin.\n * Returns true if request succeeded - otherwise false is returned.\n */\nexport async function emptyTrash(): Promise<boolean> {\n\ttry {\n\t\tawait axios.delete(`${defaultRemoteURL}/trashbin/${getCurrentUser()!.uid}/trash`)\n\t\tshowSuccess(t('files_trashbin', 'All files have been permanently deleted'))\n\t\treturn true\n\t} catch (error) {\n\t\tshowError(t('files_trashbin', 'Failed to empty deleted files'))\n\t\tlogger.error('Failed to empty deleted files', { error })\n\t\treturn false\n\t}\n}\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { getDialogBuilder } from '@nextcloud/dialogs'\nimport { emit } from '@nextcloud/event-bus'\nimport { FileListAction } from '@nextcloud/files'\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport { TRASHBIN_VIEW_ID } from '../files_views/trashbinView.ts'\nimport { emptyTrash } from '../services/api.ts'\n\nexport type FilesTrashbinConfigState = {\n\tallow_delete: boolean\n}\n\nexport const emptyTrashAction = new FileListAction({\n\tid: 'empty-trash',\n\n\tdisplayName: () => t('files_trashbin', 'Empty deleted files'),\n\torder: 0,\n\n\tenabled({ view, folder, contents }) {\n\t\tif (view.id !== TRASHBIN_VIEW_ID) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst config = loadState<FilesTrashbinConfigState>('files_trashbin', 'config')\n\t\tif (!config.allow_delete) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn contents.length > 0 && folder.path === '/'\n\t},\n\n\tasync exec({ contents }): Promise<null> {\n\t\tconst askConfirmation = new Promise<boolean>((resolve) => {\n\t\t\tconst dialog = getDialogBuilder(t('files_trashbin', 'Confirm permanent deletion'))\n\t\t\t\t.setSeverity('warning')\n\t\t\t\t// TODO Add note for groupfolders\n\t\t\t\t.setText(t('files_trashbin', 'Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone.'))\n\t\t\t\t.setButtons([\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t('files_trashbin', 'Cancel'),\n\t\t\t\t\t\tvariant: 'secondary',\n\t\t\t\t\t\tcallback: () => resolve(false),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t('files_trashbin', 'Empty deleted files'),\n\t\t\t\t\t\tvariant: 'error',\n\t\t\t\t\t\tcallback: () => resolve(true),\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t\t.build()\n\t\t\tdialog.show().then(() => {\n\t\t\t\tresolve(false)\n\t\t\t})\n\t\t})\n\n\t\tconst result = await askConfirmation\n\t\tif (result === true) {\n\t\t\tif (await emptyTrash()) {\n\t\t\t\tcontents.forEach((node) => emit('files:node:deleted', node))\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\n\t\treturn null\n\t},\n})\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { getNavigation, registerFileAction, registerFileListAction } from '@nextcloud/files'\nimport { restoreAction } from './files_actions/restoreAction.ts'\nimport { emptyTrashAction } from './files_listActions/emptyTrashAction.ts'\nimport { trashbinView } from './files_views/trashbinView.ts'\n\nimport './trashbin.scss'\n\nconst Navigation = getNavigation()\nNavigation.register(trashbinView)\n\nregisterFileListAction(emptyTrashAction)\nregisterFileAction(restoreAction)\n"],"names":["_sfc_main$1","_sfc_render","_ctx","_cache","openBlock","createElementBlock","renderSlot","NcUserBubbleDiv","_export_sfc","_hoisted_1","_hoisted_2","_sfc_main","defineComponent","mergeModels","__props","__emit","isOpen","useModel","props","emit","isAvatarUrl","computed","isCustomAvatar","avatarStyle","hasUrl","warn","href","contentComponent","RouterLink","contentStyle","watch","createBlock","resolveDynamicComponent","NcPopover","$event","withCtx","attrs","mergeProps","createVNode","NcAvatar","normalizeStyle","createElementVNode","toDisplayString","createCommentVNode","NcUserBubble","svgHistory","svgDelete","rootPath","getCurrentUser","client","getClient","data","getDavNameSpaces","getDavProperties","resultToNode","stat","node","davResultToNode","generateUrl","getContents","path","contents","folder","originalLocation","Column","t","parseOriginalLocation","span","nodeA","nodeB","locationA","locationB","getLanguage","getCanonicalLocale","deletedBy","userId","displayName","label","parseDeletedBy","el","createApp","deletedByA","deletedbyALabel","deletedByB","deletedByBLabel","deleted","deletionTime","formatter","timestamp","formatRelativeTime","deletionTimeA","stringOrNull","dir","dirname","currentUserId","attribute","TRASHBIN_VIEW_ID","trashbinView","View","logger","getLoggerBuilder","restoreAction","FileAction","nodes","view","permission","Permission","destination","generateRemoteUrl","encodePath","axios","error","isAxiosError","showError","emptyTrash","defaultRemoteURL","showSuccess","emptyTrashAction","FileListAction","loadState","resolve","getDialogBuilder","Navigation","getNavigation","registerFileListAction","registerFileAction"],"mappings":"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","x_google_ignoreList":[0,1,2]} |