{"version":3,"file":"index.mjs","sources":["../lib/utils/dialogs.ts","../node_modules/@mdi/svg/svg/folder-move.svg?raw","../node_modules/@mdi/svg/svg/folder-multiple.svg?raw","../lib/filepicker-builder.ts","../lib/components/types.ts","../lib/components/GenericDialog.vue","../lib/dialogs.ts"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { AsyncComponent, Component } from 'vue'\n\nimport Vue, { toRaw } from 'vue'\n\n/**\n * Helper to spawn a Vue dialog without having to mount it from a component\n *\n * @param dialog The dialog component to spawn\n * @param props Properties to pass to the dialog\n * @param onClose Callback when the dialog is closed\n */\nexport const spawnDialog = (dialog: Component | AsyncComponent, props: any, onClose: (...rest: unknown[]) => void = () => {}): Vue => {\n\tconst el = document.createElement('div')\n\n\tconst container: HTMLElement = document.querySelector(props?.container) || document.body\n\tcontainer.appendChild(el)\n\n\tconst vue = new Vue({\n\t\tel,\n\t\tname: 'VueDialogHelper',\n\t\trender: (h) =>\n\t\t\th(dialog, {\n\t\t\t\tprops,\n\t\t\t\ton: {\n\t\t\t\t\tclose: (...rest: unknown[]) => {\n\t\t\t\t\t\tonClose(...rest.map(v => toRaw(v)))\n\t\t\t\t\t\tvue.$destroy()\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t})\n\treturn vue\n}\n","export default \"\"","export default \"\"","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { IFilePickerButton, IFilePickerButtonFactory, IFilePickerFilter } from './components/types'\nimport type { Node } from '@nextcloud/files'\n\nimport { basename } from 'path'\nimport { spawnDialog } from './utils/dialogs'\nimport { n, t } from './utils/l10n'\n\nimport IconMove from '@mdi/svg/svg/folder-move.svg?raw'\nimport IconCopy from '@mdi/svg/svg/folder-multiple.svg?raw'\n\n/**\n * @deprecated\n */\nexport enum FilePickerType {\n\tChoose = 1,\n\tMove = 2,\n\tCopy = 3,\n\tCopyMove = 4,\n\tCustom = 5,\n}\n\n/**\n * Error that is thrown in the rejected promise when the FilePicker was closed\n */\nexport class FilePickerClosed extends Error {}\n\nexport class FilePicker {\n\n\tprivate title: string\n\tprivate multiSelect: IsMultiSelect\n\tprivate mimeTypeFilter: string[]\n\tprivate directoriesAllowed: boolean\n\tprivate buttons: IFilePickerButton[] | IFilePickerButtonFactory\n\tprivate path?: string\n\tprivate filter?: IFilePickerFilter\n\tprivate container?: string\n\tprivate disabledNavigation: boolean\n\n\tpublic constructor(title: string,\n\t\tmultiSelect: IsMultiSelect,\n\t\tmimeTypeFilter: string[],\n\t\tdirectoriesAllowed: boolean,\n\t\tbuttons: IFilePickerButton[] | IFilePickerButtonFactory,\n\t\tpath?: string,\n\t\tfilter?: IFilePickerFilter,\n\t\tcontainer?: string,\n\t\tdisabledNavigation = false,\n\t) {\n\t\tthis.title = title\n\t\tthis.multiSelect = multiSelect\n\t\tthis.mimeTypeFilter = mimeTypeFilter\n\t\tthis.directoriesAllowed = directoriesAllowed\n\t\tthis.path = path\n\t\tthis.filter = filter\n\t\tthis.buttons = buttons\n\t\tthis.container = container\n\t\tthis.disabledNavigation = disabledNavigation\n\t}\n\n\t/**\n\t * Pick files using the FilePicker\n\t *\n\t * @return Promise with array of picked files or rejected promise on close without picking\n\t */\n\tpublic async pick(): Promise {\n\t\tconst { FilePickerVue } = await import('./components/FilePicker/index')\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tspawnDialog(FilePickerVue, {\n\t\t\t\tallowPickDirectory: this.directoriesAllowed,\n\t\t\t\tbuttons: this.buttons,\n\t\t\t\tcontainer: this.container,\n\t\t\t\tname: this.title,\n\t\t\t\tpath: this.path,\n\t\t\t\tmimetypeFilter: this.mimeTypeFilter,\n\t\t\t\tmultiselect: this.multiSelect,\n\t\t\t\tfilterFn: this.filter,\n\t\t\t\tdisabledNavigation: this.disabledNavigation,\n\t\t\t}, (...rest: unknown[]) => {\n\t\t\t\tconst [nodes] = rest as [nodes: Node[]]\n\t\t\t\tif (!Array.isArray(nodes) || nodes.length === 0) {\n\t\t\t\t\treject(new FilePickerClosed('FilePicker: No nodes selected'))\n\t\t\t\t} else {\n\t\t\t\t\tif (this.multiSelect) {\n\t\t\t\t\t\tresolve((nodes as Node[]).map((node) => node.path) as (IsMultiSelect extends true ? string[] : string))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve(((nodes as Node[])[0]?.path || '/') as (IsMultiSelect extends true ? string[] : string))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n}\n\nexport class FilePickerBuilder {\n\n\tprivate title: string\n\tprivate multiSelect = false\n\tprivate mimeTypeFilter: string[] = []\n\tprivate directoriesAllowed = false\n\tprivate path?: string\n\tprivate filter?: IFilePickerFilter\n\tprivate buttons: IFilePickerButton[] | IFilePickerButtonFactory = []\n\tprivate container?: string\n\tprivate disabledNavigation = false\n\n\t/**\n\t * Construct a new FilePicker\n\t *\n\t * @param title Title of the FilePicker\n\t */\n\tpublic constructor(title: string) {\n\t\tthis.title = title\n\t}\n\n\t/**\n\t * Set the container where the FilePicker will be mounted\n\t * By default 'body' is used\n\t *\n\t * @param container The dialog container\n\t */\n\tpublic setContainer(container: string) {\n\t\tthis.container = container\n\t\treturn this\n\t}\n\n\t/**\n\t * Enable or disable picking multiple files\n\t *\n\t * @param ms True to enable picking multiple files, false otherwise\n\t */\n\tpublic setMultiSelect(ms: T) {\n\t\tthis.multiSelect = ms\n\t\treturn this as unknown as FilePickerBuilder\n\t}\n\n\t/**\n\t * Add allowed MIME type\n\t *\n\t * @param filter MIME type to allow\n\t */\n\tpublic addMimeTypeFilter(filter: string) {\n\t\tthis.mimeTypeFilter.push(filter)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set allowed MIME types\n\t *\n\t * @param filter Array of allowed MIME types\n\t */\n\tpublic setMimeTypeFilter(filter: string[]) {\n\t\tthis.mimeTypeFilter = filter\n\t\treturn this\n\t}\n\n\t/**\n\t * Add a button to the FilePicker\n\t * Note: This overrides any previous `setButtonFactory` call\n\t *\n\t * @param button The button\n\t */\n\tpublic addButton(button: IFilePickerButton) {\n\t\tif (typeof this.buttons === 'function') {\n\t\t\tconsole.warn('FilePicker buttons were set to factory, now overwritten with button object.')\n\t\t\tthis.buttons = []\n\t\t}\n\t\tthis.buttons.push(button)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the button factory which is used to generate buttons from current view, path and selected nodes\n\t * Note: This overrides any previous `addButton` call\n\t *\n\t * @param factory The button factory\n\t */\n\tpublic setButtonFactory(factory: IFilePickerButtonFactory) {\n\t\tthis.buttons = factory\n\t\treturn this\n\t}\n\n\t/**\n\t * Set FilePicker type based on legacy file picker types\n\t * @param type The legacy filepicker type to emulate\n\t * @deprecated Use `addButton` or `setButtonFactory` instead as with setType you do not know which button was pressed\n\t */\n\tpublic setType(type: FilePickerType) {\n\t\tthis.buttons = (nodes, path) => {\n\t\t\tconst buttons: IFilePickerButton[] = []\n\t\t\tconst node = nodes?.[0]?.attributes?.displayName || nodes?.[0]?.basename\n\t\t\tconst target = node || basename(path)\n\n\t\t\tif (type === FilePickerType.Choose) {\n\t\t\t\tlet label = t('Choose')\n\t\t\t\tif (nodes.length === 1) {\n\t\t\t\t\tlabel = t('Choose {file}', { file: node })\n\t\t\t\t} else if (this.multiSelect) {\n\t\t\t\t\tlabel = n('Choose %n file', 'Choose %n files', nodes.length)\n\t\t\t\t}\n\t\t\t\tbuttons.push({\n\t\t\t\t\tcallback: () => {},\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\tlabel,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (type === FilePickerType.CopyMove || type === FilePickerType.Copy) {\n\t\t\t\tbuttons.push({\n\t\t\t\t\tcallback: () => {},\n\t\t\t\t\tlabel: target ? t('Copy to {target}', { target }) : t('Copy'),\n\t\t\t\t\ttype: 'primary',\n\t\t\t\t\ticon: IconCopy,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (type === FilePickerType.Move || type === FilePickerType.CopyMove) {\n\t\t\t\tbuttons.push({\n\t\t\t\t\tcallback: () => {},\n\t\t\t\t\tlabel: target ? t('Move to {target}', { target }) : t('Move'),\n\t\t\t\t\ttype: type === FilePickerType.Move ? 'primary' : 'secondary',\n\t\t\t\t\ticon: IconMove,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn buttons\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Allow to pick directories besides files\n\t *\n\t * @param allow True to allow picking directories\n\t */\n\tpublic allowDirectories(allow = true) {\n\t\tthis.directoriesAllowed = allow\n\t\treturn this\n\t}\n\n\t/**\n\t * Set starting path of the FilePicker\n\t *\n\t * @param path Path to start from picking\n\t */\n\tpublic startAt(path: string) {\n\t\tthis.path = path\n\t\treturn this\n\t}\n\n\t/**\n\t * Add filter function to filter file list of FilePicker\n\t *\n\t * @param filter Filter function to apply\n\t */\n\tpublic setFilter(filter: IFilePickerFilter) {\n\t\tthis.filter = filter\n\t\treturn this\n\t}\n\n\t/**\n\t * Allow to pick directories besides files\n\t *\n\t * @param allow True to allow picking directories\n\t */\n\tpublic disableNavigation() {\n\t\tthis.disabledNavigation = true\n\t\treturn this\n\t}\n\n\t/**\n\t * Construct the configured FilePicker\n\t */\n\tpublic build() {\n\t\treturn new FilePicker(\n\t\t\tthis.title,\n\t\t\tthis.multiSelect as IsMultiSelect,\n\t\t\tthis.mimeTypeFilter,\n\t\t\tthis.directoriesAllowed,\n\t\t\tthis.buttons,\n\t\t\tthis.path,\n\t\t\tthis.filter,\n\t\t\tthis.container,\n\t\t\tthis.disabledNavigation,\n\t\t)\n\t}\n\n}\n\n/**\n *\n * @param title Title of the file picker\n */\nexport function getFilePickerBuilder(title: string): FilePickerBuilder {\n\treturn new FilePickerBuilder(title)\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { Node } from '@nextcloud/files'\n\nexport enum DialogSeverity {\n\tInfo = 'info',\n\tWarning = 'warning',\n\tError = 'error',\n}\n\n/**\n * Interface for defining buttons passed to the Dialog component\n * See NcDialogButton\n */\nexport interface IDialogButton {\n\t/** Label of the button */\n\tlabel: string,\n\n\t/** Callback on button click */\n\tcallback: () => void,\n\n\t/**\n\t * Optional Icon for the button\n\t * Should be a SVG image as raw string\n\t */\n\ticon?: string,\n\n\t/**\n\t * Button type\n\t * @see https://nextcloud-vue-components.netlify.app/#/Components/NcButton\n\t */\n\ttype?: 'primary' | 'secondary' | 'error' | 'warning' | 'success'\n\n\t/**\n\t * Disabled state of the button\n\t * @default false\n\t */\n\tdisabled?: boolean\n}\n\n/**\n * Interface to define buttons of the FilePicker component\n * The buttons are based on the Dialog buttons but the callback gets the array of selected nodes\n */\nexport interface IFilePickerButton extends Omit {\n\t/**\n\t * Callback on button click\n\t *\n\t * @param nodes Array of `@nextcloud/files` Nodes that were selected\n\t */\n\tcallback: (nodes: Node[]) => void\n}\n\nexport type IFilePickerButtonFactory = (selectedNodes: Node[], currentPath: string, currentView: string) => IFilePickerButton[]\n\n/**\n * Type of filter functions to filter the FilePicker's file list\n */\nexport type IFilePickerFilter = (node: Node) => boolean\n","\n\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\n\n\n\n\n\n","/**\n * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { IDialogButton } from './components/types'\nimport type Vue from 'vue'\n\nimport { DialogSeverity } from './components/types'\nimport { spawnDialog } from './utils/dialogs'\nimport GenericDialog from './components/GenericDialog.vue'\n\nexport { DialogSeverity } from './components/types'\n\n/**\n * This class provides generic Nextcloud themed dialogs\n */\nexport class Dialog {\n\n\t#name: string\n\t#text: string\n\t#buttons: IDialogButton[]\n\t#severity?: DialogSeverity\n\t#dialog?: Vue\n\n\t/** @deprecated */\n\t#html?: string\n\n\tconstructor(\n\t\tname: string,\n\t\ttext: string,\n\t\tbuttons: IDialogButton[] = [],\n\t\tseverity?: DialogSeverity,\n\t) {\n\t\tthis.#name = name\n\t\tthis.#text = text\n\t\tthis.#buttons = buttons\n\t\tthis.#severity = severity\n\t\tthis.#dialog = undefined\n\t\tthis.#html = undefined\n\t}\n\n\t/**\n\t * @deprecated DO NOT USE! It will be removed in the near future!\n\t * @param html HTML content\n\t */\n\tsetHTML(html: string) {\n\t\tthis.#html = html\n\t\treturn this\n\t}\n\n\t/**\n\t * Spawn and show the dialog - if already open the previous instance will be destroyed\n\t * @return Promise that resolves when the dialog is answered successfully and rejects on close\n\t */\n\tshow() {\n\t\tif (this.#dialog) {\n\t\t\tthis.#dialog.$destroy()\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.#dialog = spawnDialog(GenericDialog,\n\t\t\t\t{\n\t\t\t\t\tbuttons: this.#buttons,\n\t\t\t\t\tname: this.#name,\n\t\t\t\t\ttext: this.#text,\n\t\t\t\t\tseverity: this.#severity,\n\t\t\t\t\thtml: this.#html,\n\t\t\t\t},\n\t\t\t\tresolve,\n\t\t\t)\n\t\t})\n\t}\n\n\t/**\n\t * Hide and destroy the current dialog instance\n\t */\n\thide() {\n\t\tthis.#dialog?.$destroy()\n\t}\n\n}\n\n/**\n * The DialogBuilder provides an easy to use interface for creating simple dialogs in consistent Nextcloud design\n *\n * @example\n * ```ts\n * // It is recommended to use `getDialogBuilder` instead\n * const dialogBuilder = new DialogBuilder('The dialog title')\n * const dialog = dialogBuilder\n * .setText('The dialog message')\n * .setSeverity(DialogSeverity.Warning)\n * .addButton({\n * label: 'Ok',\n * callback: () => console.warn('Warning was dismissed'),\n * })\n * .build()\n * ```\n */\nexport class DialogBuilder {\n\n\t#severity?: DialogSeverity\n\t#text: string\n\t#name: string\n\t#buttons: IDialogButton[]\n\n\tconstructor(name?: string) {\n\t\tthis.#severity = undefined\n\t\tthis.#text = ''\n\t\tthis.#name = name ?? ''\n\t\tthis.#buttons = []\n\t}\n\n\t/**\n\t * Set dialog name\n\t * @param name The name or headline of the dialog\n\t */\n\tsetName(name: string) {\n\t\tthis.#name = name\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the dialog text\n\t * @param text Main text of the dialog\n\t */\n\tsetText(text: string) {\n\t\tthis.#text = text\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the severity of the dialog\n\t * @param severity Severity of the dialog\n\t */\n\tsetSeverity(severity: DialogSeverity) {\n\t\tthis.#severity = severity\n\t\treturn this\n\t}\n\n\t/**\n\t * Set buttons from array\n\t * @param buttons Either an array of dialog buttons\n\t */\n\tsetButtons(buttons: IDialogButton[]) {\n\t\tif (this.#buttons.length > 0) {\n\t\t\tconsole.warn('[@nextcloud/dialogs] Dialog buttons are already set - this overrides previous buttons.')\n\t\t}\n\t\tthis.#buttons = buttons\n\t\treturn this\n\t}\n\n\t/**\n\t * Add a single button\n\t * @param button Button to add\n\t */\n\taddButton(button: IDialogButton) {\n\t\tthis.#buttons.push(button)\n\t\treturn this\n\t}\n\n\tbuild() {\n\t\treturn new Dialog(this.#name, this.#text, this.#buttons, this.#severity)\n\t}\n\n}\n\n/**\n * Get the dialog builder to create a new dialog\n *\n * @param name The name of the dialog (title)\n * @example\n * ```ts\n * const dialog = getDialogBuilder('Confirm action')\n * .addButton({\n * label: 'Ok',\n * callback: () => console.warn('confirmed'),\n * })\n * .build()\n * ```\n */\nexport function getDialogBuilder(name: string) {\n\treturn new DialogBuilder(name)\n}\n"],"names":["h","FilePickerType","DialogSeverity"],"mappings":"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","x_google_ignoreList":[1,2]}