mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
1 line
No EOL
68 KiB
Text
1 line
No EOL
68 KiB
Text
{"version":3,"file":"files_external-settings.mjs","sources":["../node_modules/@mdi/svg/svg/account-group-outline.svg?raw","../build/frontend/apps/files_external/src/composables/useEntities.ts","../build/frontend/apps/files_external/src/components/AddExternalStorageDialog/ApplicableEntities.vue","../build/frontend/apps/files_external/src/components/AddExternalStorageDialog/AuthMechanismConfiguration.vue","../build/frontend/apps/files_external/src/components/AddExternalStorageDialog/BackendConfiguration.vue","../build/frontend/apps/files_external/src/components/AddExternalStorageDialog/MountOptions.vue","../build/frontend/apps/files_external/src/components/AddExternalStorageDialog/AddExternalStorageDialog.vue","../build/frontend/apps/files_external/src/store/storages.ts","../build/frontend/apps/files_external/src/components/ExternalStorageTableRow.vue","../build/frontend/apps/files_external/src/components/ExternalStorageTable.vue","../build/frontend/apps/files_external/src/components/UserMountSettings.vue","../build/frontend/apps/files_external/src/views/ExternalStoragesSection.vue","../build/frontend/apps/files_external/src/views/GlobalCredentialsSection.vue","../build/frontend/apps/files_external/src/views/FilesExternalSettings.vue","../build/frontend/apps/files_external/src/settings-main.ts"],"sourcesContent":["export default \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" id=\\\"mdi-account-group-outline\\\" viewBox=\\\"0 0 24 24\\\"><path d=\\\"M12,5A3.5,3.5 0 0,0 8.5,8.5A3.5,3.5 0 0,0 12,12A3.5,3.5 0 0,0 15.5,8.5A3.5,3.5 0 0,0 12,5M12,7A1.5,1.5 0 0,1 13.5,8.5A1.5,1.5 0 0,1 12,10A1.5,1.5 0 0,1 10.5,8.5A1.5,1.5 0 0,1 12,7M5.5,8A2.5,2.5 0 0,0 3,10.5C3,11.44 3.53,12.25 4.29,12.68C4.65,12.88 5.06,13 5.5,13C5.94,13 6.35,12.88 6.71,12.68C7.08,12.47 7.39,12.17 7.62,11.81C6.89,10.86 6.5,9.7 6.5,8.5C6.5,8.41 6.5,8.31 6.5,8.22C6.2,8.08 5.86,8 5.5,8M18.5,8C18.14,8 17.8,8.08 17.5,8.22C17.5,8.31 17.5,8.41 17.5,8.5C17.5,9.7 17.11,10.86 16.38,11.81C16.5,12 16.63,12.15 16.78,12.3C16.94,12.45 17.1,12.58 17.29,12.68C17.65,12.88 18.06,13 18.5,13C18.94,13 19.35,12.88 19.71,12.68C20.47,12.25 21,11.44 21,10.5A2.5,2.5 0 0,0 18.5,8M12,14C9.66,14 5,15.17 5,17.5V19H19V17.5C19,15.17 14.34,14 12,14M4.71,14.55C2.78,14.78 0,15.76 0,17.5V19H3V17.07C3,16.06 3.69,15.22 4.71,14.55M19.29,14.55C20.31,15.22 21,16.06 21,17.07V19H24V17.5C24,15.76 21.22,14.78 19.29,14.55M12,16C13.53,16 15.24,16.5 16.23,17H7.77C8.76,16.5 10.47,16 12,16Z\\\" /></svg>\"","/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { MaybeRefOrGetter } from 'vue'\n\nimport svgAccountGroupOutline from '@mdi/svg/svg/account-group-outline.svg?raw'\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { computed, reactive, toValue, watchEffect } from 'vue'\n\nconst displayNames = reactive(new Map<string, string>())\n\n/**\n * Fetch and provide user display names for given UIDs\n *\n * @param uids - The user ids to fetch display names for\n */\nexport function useUsers(uids: MaybeRefOrGetter<string[]>) {\n\tconst users = computed(() => toValue(uids).map((uid) => ({\n\t\tid: `user:${uid}`,\n\t\tuser: uid,\n\t\tdisplayName: displayNames.get(uid) || uid,\n\t})))\n\n\twatchEffect(async () => {\n\t\tconst missingUsers = toValue(uids).filter((uid) => !displayNames.has(uid))\n\t\tif (missingUsers.length > 0) {\n\t\t\tconst { data } = await axios.post(generateUrl('/displaynames'), {\n\t\t\t\tusers: missingUsers,\n\t\t\t})\n\t\t\tfor (const [uid, displayName] of Object.entries(data.users)) {\n\t\t\t\tdisplayNames.set(uid, displayName as string)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn users\n}\n\n/**\n * Map group ids to IUserData objects\n *\n * @param gids - The group ids to create entities for\n */\nexport function useGroups(gids: MaybeRefOrGetter<string[]>) {\n\treturn computed(() => toValue(gids).map(mapGroupToUserData))\n}\n\n/**\n * Map a group id to an IUserData object\n *\n * @param gid - The group id to map\n */\nexport function mapGroupToUserData(gid: string) {\n\treturn {\n\t\tid: gid,\n\t\tisNoUser: true,\n\t\tdisplayName: gid,\n\t\ticonSvg: svgAccountGroupOutline,\n\t}\n}\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport axios from '@nextcloud/axios'\nimport { t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport { useDebounceFn } from '@vueuse/core'\nimport { computed, ref } from 'vue'\nimport NcSelectUsers from '@nextcloud/vue/components/NcSelectUsers'\nimport { mapGroupToUserData, useGroups, useUsers } from '../../composables/useEntities.ts'\n\ntype IUserData = InstanceType<typeof NcSelectUsers>['$props']['options'][number]\n\nconst groups = defineModel<string[]>('groups', { default: () => [] })\nconst users = defineModel<string[]>('users', { default: () => [] })\n\nconst entities = ref<IUserData[]>([])\nconst selectedUsers = useUsers(users)\nconst selectedGroups = useGroups(groups)\n\nconst model = computed({\n\tget() {\n\t\treturn [...selectedGroups.value, ...selectedUsers.value]\n\t},\n\tset(value: IUserData[]) {\n\t\tusers.value = value.filter((u) => u.user).map((u) => u.user!)\n\t\tgroups.value = value.filter((g) => g.isNoUser).map((g) => g.id)\n\t},\n})\n\nconst debouncedSearch = useDebounceFn(onSearch, 500)\n\n/**\n * Handle searching for users and groups\n *\n * @param pattern - The pattern to search\n */\nasync function onSearch(pattern: string) {\n\tconst { data } = await axios.get<{ groups: Record<string, string>, users: Record<string, string> }>(\n\t\tgenerateUrl('apps/files_external/ajax/applicable'),\n\t\t{ params: { pattern, limit: 20 } },\n\t)\n\n\tconst newEntries = [\n\t\t...entities.value.map((e) => [e.id, e]),\n\t\t...Object.entries(data.groups)\n\t\t\t.map(([id, displayName]) => [id, { ...mapGroupToUserData(id), displayName }]),\n\t\t...Object.entries(data.users)\n\t\t\t.map(([id, displayName]) => [`user:${id}`, { id: `user:${id}`, user: id, displayName }]),\n\t] as [string, IUserData][]\n\n\tentities.value = [...new Map(newEntries).values()]\n}\n</script>\n\n<template>\n\t<NcSelectUsers\n\t\tv-model=\"model\"\n\t\tkeep-open\n\t\tmultiple\n\t\t:options=\"entities\"\n\t\t:input-label=\"t('files_external', 'Restrict to')\"\n\t\t@search=\"debouncedSearch\" />\n</template>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport type { IAuthMechanism } from '../../types.ts'\n\nimport { t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport { computed, ref, watch, watchEffect } from 'vue'\nimport ConfigurationEntry from './ConfigurationEntry.vue'\nimport { ConfigurationFlag, ConfigurationType } from '../../types.ts'\n\nconst modelValue = defineModel<Record<string, string | boolean>>({ required: true })\n\nconst props = defineProps<{\n\tauthMechanism: IAuthMechanism\n}>()\n\nconst configuration = computed(() => {\n\tif (!props.authMechanism.configuration) {\n\t\treturn undefined\n\t}\n\n\tconst entries = Object.entries(props.authMechanism.configuration)\n\t\t.filter(([, option]) => !(option.flags & ConfigurationFlag.UserProvided))\n\treturn Object.fromEntries(entries) as typeof props.authMechanism.configuration\n})\n\nconst customComponent = computed(() => window.OCA.FilesExternal.AuthMechanism!.getHandler(props.authMechanism))\nconst hasConfiguration = computed(() => {\n\tif (!configuration.value) {\n\t\treturn false\n\t}\n\tfor (const option of Object.values(configuration.value)) {\n\t\tif ((option.flags & ConfigurationFlag.Hidden) || (option.flags & ConfigurationFlag.UserProvided)) {\n\t\t\tcontinue\n\t\t}\n\t\t// a real config option\n\t\treturn true\n\t}\n\treturn false\n})\n\nconst isLoadingCustomComponent = ref(false)\nwatchEffect(async () => {\n\tif (customComponent.value) {\n\t\tisLoadingCustomComponent.value = true\n\t\tawait window.customElements.whenDefined(customComponent.value.tagName)\n\t\tisLoadingCustomComponent.value = false\n\t}\n})\n\nwatch(configuration, () => {\n\tfor (const key in configuration.value) {\n\t\tif (!(key in modelValue.value)) {\n\t\t\tmodelValue.value[key] = configuration.value[key]?.type === ConfigurationType.Boolean\n\t\t\t\t? false\n\t\t\t\t: ''\n\t\t}\n\t}\n})\n\n/**\n * Update the model value when the custom component emits an update event.\n *\n * @param event - The custom event\n */\nfunction onUpdateModelValue(event: CustomEvent) {\n\tconst config = [event.detail].flat()[0]\n\tmodelValue.value = { ...modelValue.value, ...config }\n}\n</script>\n\n<template>\n\t<fieldset v-if=\"hasConfiguration\" :class=\"$style.authMechanismConfiguration\">\n\t\t<legend>\n\t\t\t{{ t('files_external', 'Authentication') }}\n\t\t</legend>\n\n\t\t<template v-if=\"customComponent\">\n\t\t\t<NcLoadingIcon v-if=\"isLoadingCustomComponent\" />\n\t\t\t<!-- eslint-disable vue/attribute-hyphenation,vue/v-on-event-hyphenation -- for custom elements the casing is fixed! -->\n\t\t\t<component\n\t\t\t\t:is=\"customComponent.tagName\"\n\t\t\t\tv-else\n\t\t\t\t:modelValue.prop=\"modelValue\"\n\t\t\t\t:authMechanism.prop=\"authMechanism\"\n\t\t\t\t@update:modelValue=\"onUpdateModelValue\" />\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<ConfigurationEntry\n\t\t\t\tv-for=\"(configOption, configKey) in configuration\"\n\t\t\t\tv-show=\"!(configOption.flags & ConfigurationFlag.Hidden)\"\n\t\t\t\t:key=\"configOption.value\"\n\t\t\t\tv-model=\"modelValue[configKey]!\"\n\t\t\t\t:config-key\n\t\t\t\t:config-option />\n\t\t</template>\n\t</fieldset>\n</template>\n\n<style module>\n.authMechanismConfiguration {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport type { IConfigurationOption } from '../../types.ts'\n\nimport { t } from '@nextcloud/l10n'\nimport { watch } from 'vue'\nimport ConfigurationEntry from './ConfigurationEntry.vue'\nimport { ConfigurationFlag, ConfigurationType } from '../../types.ts'\n\nconst modelValue = defineModel<Record<string, string | boolean>>({ required: true })\n\nconst props = defineProps<{\n\tconfiguration: Record<string, IConfigurationOption>\n}>()\n\nwatch(() => props.configuration, () => {\n\tfor (const key in props.configuration) {\n\t\tif (!(key in modelValue.value)) {\n\t\t\tmodelValue.value[key] = props.configuration[key]?.type === ConfigurationType.Boolean\n\t\t\t\t? false\n\t\t\t\t: ''\n\t\t}\n\t}\n})\n</script>\n\n<template>\n\t<fieldset :class=\"$style.backendConfiguration\">\n\t\t<legend>\n\t\t\t{{ t('files_external', 'Storage configuration') }}\n\t\t</legend>\n\n\t\t<ConfigurationEntry\n\t\t\tv-for=\"configOption, configKey in configuration\"\n\t\t\tv-show=\"!(configOption.flags & ConfigurationFlag.Hidden)\"\n\t\t\t:key=\"configOption.value\"\n\t\t\tv-model=\"modelValue[configKey]!\"\n\t\t\t:config-key=\"configKey\"\n\t\t\t:config-option=\"configOption\" />\n\t</fieldset>\n</template>\n\n<style module>\n.backendConfiguration {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport type { IMountOptions } from '../../types.ts'\n\nimport { mdiChevronDown, mdiChevronRight } from '@mdi/js'\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport { computed, ref, useId, watchEffect } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'\nimport NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'\nimport NcSelect from '@nextcloud/vue/components/NcSelect'\nimport { MountOptionsCheckFilesystem } from '../../types.ts'\n\nconst mountOptions = defineModel<Partial<IMountOptions>>({ required: true })\nwatchEffect(() => {\n\tif (Object.keys(mountOptions.value).length === 0) {\n\t\tmountOptions.value.encrypt = true\n\t\tmountOptions.value.previews = true\n\t\tmountOptions.value.enable_sharing = false\n\t\tmountOptions.value.filesystem_check_changes = MountOptionsCheckFilesystem.OncePerRequest\n\t\tmountOptions.value.encoding_compatibility = false\n\t\tmountOptions.value.readonly = false\n\t}\n})\n\nconst { hasEncryption } = loadState<{ hasEncryption: boolean }>('files_external', 'settings')\n\nconst idButton = useId()\nconst idFieldset = useId()\n\nconst isExpanded = ref(false)\n\nconst checkFilesystemOptions = [\n\t{\n\t\tlabel: t('files_external', 'Never'),\n\t\tvalue: MountOptionsCheckFilesystem.Never,\n\t},\n\t{\n\t\tlabel: t('files_external', 'Once every direct access'),\n\t\tvalue: MountOptionsCheckFilesystem.OncePerRequest,\n\t},\n\t{\n\t\tlabel: t('files_external', 'Always'),\n\t\tvalue: MountOptionsCheckFilesystem.Always,\n\t},\n]\nconst checkFilesystem = computed({\n\tget() {\n\t\treturn checkFilesystemOptions.find((option) => option.value === mountOptions.value.filesystem_check_changes)\n\t},\n\tset(value) {\n\t\tmountOptions.value.filesystem_check_changes = value?.value ?? MountOptionsCheckFilesystem.OncePerRequest\n\t},\n})\n\n</script>\n\n<template>\n\t<div :class=\"$style.mountOptions\">\n\t\t<NcButton\n\t\t\t:id=\"idButton\"\n\t\t\t:aria-controls=\"idFieldset\"\n\t\t\t:aria-expanded=\"isExpanded\"\n\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t@click=\"isExpanded = !isExpanded\">\n\t\t\t<template #icon>\n\t\t\t\t<NcIconSvgWrapper directional :path=\"isExpanded ? mdiChevronDown : mdiChevronRight\" />\n\t\t\t</template>\n\t\t\t{{ t('files_external', 'Mount options') }}\n\t\t</NcButton>\n\n\t\t<fieldset\n\t\t\tv-show=\"isExpanded\"\n\t\t\t:id=\"idFieldset\"\n\t\t\t:class=\"$style.mountOptions__fieldset\"\n\t\t\t:aria-labelledby=\"idButton\">\n\t\t\t<NcSelect\n\t\t\t\tv-model=\"checkFilesystem\"\n\t\t\t\t:input-label=\"t('files_external', 'Check filesystem changes')\"\n\t\t\t\t:options=\"checkFilesystemOptions\" />\n\n\t\t\t<NcCheckboxRadioSwitch v-model=\"modelValue.readonly\" type=\"switch\">\n\t\t\t\t{{ t('files_external', 'Read only') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcCheckboxRadioSwitch v-model=\"modelValue.previews\" type=\"switch\">\n\t\t\t\t{{ t('files_external', 'Enable previews') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcCheckboxRadioSwitch v-model=\"modelValue.enable_sharing\" type=\"switch\">\n\t\t\t\t{{ t('files_external', 'Enable sharing') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcCheckboxRadioSwitch v-if=\"hasEncryption\" v-model=\"modelValue.encrypt\" type=\"switch\">\n\t\t\t\t{{ t('files_external', 'Enable encryption') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcCheckboxRadioSwitch v-model=\"modelValue.encoding_compatibility\" type=\"switch\">\n\t\t\t\t{{ t('files_external', 'Compatibility with Mac NFD encoding (slow)') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</fieldset>\n\t</div>\n</template>\n\n<style module>\n.mountOptions {\n\tbackground-color: hsl(from var(--color-primary-element-light) h s calc(l * 1.045));\n\tborder-radius: var(--border-radius-element);\n\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n\twidth: 100%;\n}\n\n.mountOptions__fieldset {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n\tpadding-inline: calc(2 * var(--default-grid-baseline)) var(--default-grid-baseline);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script lang=\"ts\">\nimport { loadState } from '@nextcloud/initial-state'\n\nconst { isAdmin } = loadState<{ isAdmin: boolean }>('files_external', 'settings')\nconst allowedBackendIds = loadState<string[]>('files_external', 'allowedBackends')\nconst backends = loadState<IBackend[]>('files_external', 'backends')\n\t.filter((b) => allowedBackendIds.includes(b.identifier))\n\nconst allAuthMechanisms = loadState<IAuthMechanism[]>('files_external', 'authMechanisms')\n</script>\n\n<script setup lang=\"ts\">\nimport type { IAuthMechanism, IBackend, IStorage } from '../../types.ts'\n\nimport { t } from '@nextcloud/l10n'\nimport { computed, ref, toRaw, watch, watchEffect } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport NcSelect from '@nextcloud/vue/components/NcSelect'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\nimport ApplicableEntities from './ApplicableEntities.vue'\nimport AuthMechanismConfiguration from './AuthMechanismConfiguration.vue'\nimport BackendConfiguration from './BackendConfiguration.vue'\nimport MountOptions from './MountOptions.vue'\n\nconst open = defineModel<boolean>('open', { default: true })\n\nconst {\n\tstorage = { backendOptions: {}, mountOptions: {}, type: isAdmin ? 'system' : 'personal' },\n} = defineProps<{\n\tstorage?: Partial<IStorage> & { backendOptions: IStorage['backendOptions'] }\n}>()\n\ndefineEmits<{\n\tclose: [storage?: Partial<IStorage>]\n}>()\n\nconst internalStorage = ref(structuredClone(toRaw(storage)))\nwatchEffect(() => {\n\tif (open.value) {\n\t\tinternalStorage.value = structuredClone(toRaw(storage))\n\t}\n})\n\nconst backend = computed({\n\tget() {\n\t\treturn backends.find((b) => b.identifier === internalStorage.value.backend)\n\t},\n\tset(value?: IBackend) {\n\t\tinternalStorage.value.backend = value?.identifier\n\t},\n})\n\nconst authMechanisms = computed(() => allAuthMechanisms\n\t.filter(({ scheme }) => backend.value?.authSchemes[scheme]))\nconst authMechanism = computed({\n\tget() {\n\t\treturn authMechanisms.value.find((a) => a.identifier === internalStorage.value.authMechanism)\n\t},\n\tset(value?: IAuthMechanism) {\n\t\tinternalStorage.value.authMechanism = value?.identifier\n\t},\n})\n\n// auto set the auth mechanism if there's only one available\nwatch(authMechanisms, () => {\n\tif (authMechanisms.value.length === 1) {\n\t\tinternalStorage.value.authMechanism = authMechanisms.value[0]!.identifier\n\t}\n})\n</script>\n\n<template>\n\t<NcDialog\n\t\tv-model:open=\"open\"\n\t\tis-form\n\t\t:content-classes=\"$style.externalStorageDialog\"\n\t\t:name=\"internalStorage.id ? t('files_external', 'Edit storage') : t('files_external', 'Add storage')\"\n\t\t@submit=\"$emit('close', internalStorage)\"\n\t\t@update:open=\"$event || $emit('close')\">\n\t\t<NcTextField\n\t\t\tv-model=\"internalStorage.mountPoint\"\n\t\t\t:label=\"t('files_external', 'Folder name')\"\n\t\t\trequired />\n\n\t\t<MountOptions v-model=\"internalStorage.mountOptions\" />\n\n\t\t<ApplicableEntities\n\t\t\tv-if=\"isAdmin\"\n\t\t\tv-model:groups=\"internalStorage.applicableGroups\"\n\t\t\tv-model:users=\"internalStorage.applicableUsers\" />\n\n\t\t<NcSelect\n\t\t\tv-model=\"backend\"\n\t\t\t:options=\"backends\"\n\t\t\t:disabled=\"!!(internalStorage.id && internalStorage.backend)\"\n\t\t\t:input-label=\"t('files_external', 'External storage')\"\n\t\t\tlabel=\"name\"\n\t\t\trequired />\n\n\t\t<NcSelect\n\t\t\tv-model=\"authMechanism\"\n\t\t\t:options=\"authMechanisms\"\n\t\t\t:disabled=\"!internalStorage.backend || authMechanisms.length <= 1 || !!(internalStorage.id && internalStorage.authMechanism)\"\n\t\t\t:input-label=\"t('files_external', 'Authentication')\"\n\t\t\tlabel=\"name\"\n\t\t\trequired />\n\n\t\t<BackendConfiguration\n\t\t\tv-if=\"backend\"\n\t\t\tv-model=\"internalStorage.backendOptions\"\n\t\t\t:class=\"$style.externalStorageDialog__configuration\"\n\t\t\t:configuration=\"backend.configuration\" />\n\n\t\t<AuthMechanismConfiguration\n\t\t\tv-if=\"authMechanism\"\n\t\t\tv-model=\"internalStorage.backendOptions\"\n\t\t\t:class=\"$style.externalStorageDialog__configuration\"\n\t\t\t:auth-mechanism=\"authMechanism\" />\n\n\t\t<template #actions>\n\t\t\t<NcButton v-if=\"storage.id\" @click=\"$emit('close')\">\n\t\t\t\t{{ t('files_external', 'Cancel') }}\n\t\t\t</NcButton>\n\n\t\t\t<NcButton variant=\"primary\" type=\"submit\">\n\t\t\t\t{{ storage.id ? t('files_external', 'Edit') : t('files_external', 'Create') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<style module>\n.externalStorageDialog {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--default-grid-baseline);\n\tmin-height: calc(14 * var(--default-clickable-area)) !important;\n}\n\n.externalStorageDialog__configuration {\n\tmargin-block: 0.5rem;\n}\n</style>\n","/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { IStorage } from '../types.d.ts'\n\nimport axios from '@nextcloud/axios'\nimport { loadState } from '@nextcloud/initial-state'\nimport { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation'\nimport { generateUrl } from '@nextcloud/router'\nimport { defineStore } from 'pinia'\nimport { ref, toRaw } from 'vue'\n\nconst { isAdmin } = loadState<{ isAdmin: boolean }>('files_external', 'settings')\n\nexport const useStorages = defineStore('files_external--storages', () => {\n\tconst globalStorages = ref<IStorage[]>([])\n\tconst userStorages = ref<IStorage[]>([])\n\n\t/**\n\t * Create a new global storage\n\t *\n\t * @param storage - The storage to create\n\t */\n\tasync function createGlobalStorage(storage: Partial<IStorage>) {\n\t\tconst url = generateUrl('apps/files_external/globalstorages')\n\t\tconst { data } = await axios.post<IStorage>(\n\t\t\turl,\n\t\t\ttoRaw(storage),\n\t\t\t{ confirmPassword: PwdConfirmationMode.Strict },\n\t\t)\n\t\tglobalStorages.value.push(data)\n\t}\n\n\t/**\n\t * Create a new global storage\n\t *\n\t * @param storage - The storage to create\n\t */\n\tasync function createUserStorage(storage: Partial<IStorage>) {\n\t\tconst url = generateUrl('apps/files_external/userstorages')\n\t\tconst { data } = await axios.post<IStorage>(\n\t\t\turl,\n\t\t\ttoRaw(storage),\n\t\t\t{ confirmPassword: PwdConfirmationMode.Strict },\n\t\t)\n\t\tuserStorages.value.push(data)\n\t}\n\n\t/**\n\t * Delete a storage\n\t *\n\t * @param storage - The storage to delete\n\t */\n\tasync function deleteStorage(storage: IStorage) {\n\t\tawait axios.delete(getUrl(storage), {\n\t\t\tconfirmPassword: PwdConfirmationMode.Strict,\n\t\t})\n\n\t\tif (storage.type === 'personal') {\n\t\t\tuserStorages.value = userStorages.value.filter((s) => s.id !== storage.id)\n\t\t} else {\n\t\t\tglobalStorages.value = globalStorages.value.filter((s) => s.id !== storage.id)\n\t\t}\n\t}\n\n\t/**\n\t * Update an existing storage\n\t *\n\t * @param storage - The storage to update\n\t */\n\tasync function updateStorage(storage: IStorage) {\n\t\tconst { data } = await axios.put(\n\t\t\tgetUrl(storage),\n\t\t\ttoRaw(storage),\n\t\t\t{ confirmPassword: PwdConfirmationMode.Strict },\n\t\t)\n\n\t\toverrideStorage(data)\n\t}\n\n\t/**\n\t * Reload a storage from the server\n\t *\n\t * @param storage - The storage to reload\n\t */\n\tasync function reloadStorage(storage: IStorage) {\n\t\tconst { data } = await axios.get(getUrl(storage))\n\t\toverrideStorage(data)\n\t}\n\n\t// initialize the store\n\tinitialize()\n\n\treturn {\n\t\tglobalStorages,\n\t\tuserStorages,\n\n\t\tcreateGlobalStorage,\n\t\tcreateUserStorage,\n\t\tdeleteStorage,\n\t\treloadStorage,\n\t\tupdateStorage,\n\t}\n\n\t/**\n\t * @param type - The type of storages to load\n\t */\n\tasync function loadStorages(type: string) {\n\t\tconst url = `apps/files_external/${type}`\n\t\tconst { data } = await axios.get<Record<number, IStorage>>(generateUrl(url))\n\t\treturn Object.values(data)\n\t}\n\n\t/**\n\t * Load the storages based on the user role\n\t */\n\tasync function initialize() {\n\t\taddPasswordConfirmationInterceptors(axios)\n\n\t\tif (isAdmin) {\n\t\t\tglobalStorages.value = await loadStorages('globalstorages')\n\t\t} else {\n\t\t\tuserStorages.value = await loadStorages('userstorages')\n\t\t\tglobalStorages.value = await loadStorages('userglobalstorages')\n\t\t}\n\t}\n\n\t/**\n\t * @param storage - The storage to get the URL for\n\t */\n\tfunction getUrl(storage: IStorage) {\n\t\tconst type = storage.type === 'personal' ? 'userstorages' : 'globalstorages'\n\t\treturn generateUrl(`apps/files_external/${type}/${storage.id}`)\n\t}\n\n\t/**\n\t * Override a storage in the store\n\t *\n\t * @param storage - The storage save\n\t */\n\tfunction overrideStorage(storage: IStorage) {\n\t\tif (storage.type === 'personal') {\n\t\t\tconst index = userStorages.value.findIndex((s) => s.id === storage.id)\n\t\t\tuserStorages.value.splice(index, 1, storage)\n\t\t} else {\n\t\t\tconst index = globalStorages.value.findIndex((s) => s.id === storage.id)\n\t\t\tglobalStorages.value.splice(index, 1, storage)\n\t\t}\n\t}\n})\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport type { IBackend, IStorage } from '../types.ts'\n\nimport { mdiAccountGroupOutline, mdiInformationOutline, mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js'\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport { NcChip, NcLoadingIcon, NcUserBubble, spawnDialog } from '@nextcloud/vue'\nimport { computed, ref } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'\nimport AddExternalStorageDialog from './AddExternalStorageDialog/AddExternalStorageDialog.vue'\nimport { useUsers } from '../composables/useEntities.ts'\nimport { useStorages } from '../store/storages.ts'\nimport { StorageStatus, StorageStatusIcons, StorageStatusMessage } from '../types.ts'\n\nconst props = defineProps<{\n\tstorage: IStorage\n\tisAdmin: boolean\n}>()\n\nconst store = useStorages()\n\nconst backends = loadState<IBackend[]>('files_external', 'backends')\nconst backendName = computed(() => backends.find((b) => b.identifier === props.storage.backend)!.name)\n\nconst authMechanisms = loadState<IBackend[]>('files_external', 'authMechanisms')\nconst authMechanismName = computed(() => authMechanisms.find((a) => a.identifier === props.storage.authMechanism)!.name)\n\nconst checkingStatus = ref(false)\nconst status = computed(() => {\n\tif (checkingStatus.value) {\n\t\treturn {\n\t\t\ticon: 'loading',\n\t\t\tlabel: t('files_external', 'Checking …'),\n\t\t}\n\t}\n\n\tconst status = props.storage.status ?? StorageStatus.Indeterminate\n\tconst label = props.storage.statusMessage || StorageStatusMessage[status]\n\tconst icon = StorageStatusIcons[status]\n\n\tconst isWarning = status === StorageStatus.NetworkError || status === StorageStatus.Timeout\n\tconst isError = !isWarning && status !== StorageStatus.Success && status !== StorageStatus.Indeterminate\n\n\treturn { icon, label, isWarning, isError }\n})\n\nconst users = useUsers(() => props.storage.applicableUsers || [])\n\n/**\n * Handle deletion of the external storage mount point\n */\nasync function onDelete() {\n\tawait store.deleteStorage(props.storage)\n}\n\n/**\n * Handle editing of the external storage mount point\n */\nasync function onEdit() {\n\tconst storage = await spawnDialog(AddExternalStorageDialog, {\n\t\tstorage: props.storage,\n\t})\n\n\tif (!storage) {\n\t\treturn\n\t}\n\tawait store.updateStorage(storage as IStorage)\n}\n\n/**\n * Reload the status of the external storage mount point\n */\nasync function reloadStatus() {\n\tcheckingStatus.value = true\n\ttry {\n\t\tawait store.reloadStorage(props.storage)\n\t} finally {\n\t\tcheckingStatus.value = false\n\t}\n}\n</script>\n\n<template>\n\t<tr :class=\"$style.storageTableRow\">\n\t\t<td>\n\t\t\t<span class=\"hidden-visually\">{{ status.label }}</span>\n\t\t\t<NcButton\n\t\t\t\t:aria-label=\"t('files_external', 'Recheck status')\"\n\t\t\t\t:title=\"status.label\"\n\t\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t\t@click=\"reloadStatus\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"status.icon === 'loading'\" />\n\t\t\t\t\t<NcIconSvgWrapper\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t[$style.storageTableRow__status_error]: status.isError,\n\t\t\t\t\t\t\t[$style.storageTableRow__status_warning]: status.isWarning,\n\t\t\t\t\t\t}\"\n\t\t\t\t\t\t:path=\"status.icon\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t</td>\n\t\t<td>{{ storage.mountPoint }}</td>\n\t\t<td>{{ backendName }}</td>\n\t\t<td>{{ authMechanismName }}</td>\n\t\t<td v-if=\"isAdmin\">\n\t\t\t<div :class=\"$style.storageTableRow__cellApplicable\">\n\t\t\t\t<NcChip\n\t\t\t\t\tv-for=\"group of storage.applicableGroups\"\n\t\t\t\t\t:key=\"group\"\n\t\t\t\t\t:icon-path=\"mdiAccountGroupOutline\"\n\t\t\t\t\tno-close\n\t\t\t\t\t:text=\"group\" />\n\t\t\t\t<NcUserBubble\n\t\t\t\t\tv-for=\"user of users\"\n\t\t\t\t\t:key=\"user.user\"\n\t\t\t\t\t:display-name=\"user.displayName\"\n\t\t\t\t\t:size=\"24\"\n\t\t\t\t\t:user=\"user.user\" />\n\t\t\t</div>\n\t\t</td>\n\t\t<td>\n\t\t\t<div v-if=\"isAdmin || storage.type === 'personal'\" :class=\"$style.storageTableRow__cellActions\">\n\t\t\t\t<NcButton\n\t\t\t\t\t:aria-label=\"t('files_external', 'Edit')\"\n\t\t\t\t\t:title=\"t('files_external', 'Edit')\"\n\t\t\t\t\t@click=\"onEdit\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcIconSvgWrapper :path=\"mdiPencilOutline\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton\n\t\t\t\t\t:aria-label=\"t('files_external', 'Delete')\"\n\t\t\t\t\t:title=\"t('files_external', 'Delete')\"\n\t\t\t\t\tvariant=\"error\"\n\t\t\t\t\t@click=\"onDelete\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<NcIconSvgWrapper :path=\"mdiTrashCanOutline\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t\t<NcIconSvgWrapper\n\t\t\t\tv-else\n\t\t\t\tinline\n\t\t\t\t:path=\"mdiInformationOutline\"\n\t\t\t\t:name=\"t('files_external', 'System provided storage')\"\n\t\t\t\t:title=\"t('files_external', 'System provided storage')\" />\n\t\t</td>\n\t</tr>\n</template>\n\n<style module>\n.storageTableRow__cellActions {\n\tdisplay: flex;\n\tgap: var(--default-grid-baseline);\n}\n\n.storageTableRow__cellApplicable {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--default-grid-baseline);\n\talign-items: center;\n\n\tmax-height: calc(48px + 2 * var(--default-grid-baseline));\n\toverflow: scroll;\n}\n\n.storageTableRow__status_warning {\n\tcolor: var(--color-element-warning);\n}\n\n.storageTableRow__status_error {\n\tcolor: var(--color-element-error);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport { computed } from 'vue'\nimport ExternalStorageTableRow from './ExternalStorageTableRow.vue'\nimport { useStorages } from '../store/storages.ts'\n\nconst store = useStorages()\nconst { isAdmin } = loadState<{ isAdmin: boolean }>('files_external', 'settings')\nconst storages = computed(() => {\n\tif (isAdmin) {\n\t\treturn store.globalStorages\n\t} else {\n\t\treturn [\n\t\t\t...store.userStorages,\n\t\t\t...store.globalStorages,\n\t\t]\n\t}\n})\n</script>\n\n<template>\n\t<table :class=\"$style.storageTable\" :aria-label=\"t('files_external', 'External storages')\">\n\t\t<thead :class=\"$style.storageTable__header\">\n\t\t\t<tr>\n\t\t\t\t<th :class=\"$style.storageTable__headerStatus\">\n\t\t\t\t\t<span class=\"hidden-visually\">\n\t\t\t\t\t\t{{ t('files_external', 'Status') }}\n\t\t\t\t\t</span>\n\t\t\t\t</th>\n\t\t\t\t<th :class=\"$style.storageTable__headerFolder\">\n\t\t\t\t\t{{ t('files_external', 'Folder name') }}\n\t\t\t\t</th>\n\t\t\t\t<th :class=\"$style.storageTable__headerBackend\">\n\t\t\t\t\t{{ t('files_external', 'External storage') }}\n\t\t\t\t</th>\n\t\t\t\t<th :class=\"$style.storageTable__headerAuthentication\">\n\t\t\t\t\t{{ t('files_external', 'Authentication') }}\n\t\t\t\t</th>\n\t\t\t\t<th v-if=\"isAdmin\">\n\t\t\t\t\t{{ t('files_external', 'Restricted to') }}\n\t\t\t\t</th>\n\t\t\t\t<th :class=\"$style.storageTable__headerActions\">\n\t\t\t\t\t<span class=\"hidden-visually\">\n\t\t\t\t\t\t{{ t('files_external', 'Actions') }}\n\t\t\t\t\t</span>\n\t\t\t\t</th>\n\t\t\t</tr>\n\t\t</thead>\n\t\t<tbody>\n\t\t\t<ExternalStorageTableRow\n\t\t\t\tv-for=\"storage in storages\"\n\t\t\t\t:key=\"storage.id\"\n\t\t\t\t:is-admin\n\t\t\t\t:storage=\"storage\" />\n\t\t</tbody>\n\t</table>\n</template>\n\n<style module>\n.storageTable {\n\twidth: 100%;\n}\n\n.storageTable td,th {\n\tpadding-block: calc(var(--default-grid-baseline) / 2);\n\tpadding-inline: var(--default-grid-baseline);\n}\n\n.storageTable__header {\n\tcolor: var(--color-text-maxcontrast);\n\tmin-height: var(--default-clickable-area);\n}\n\n.storageTable__headerStatus {\n\twidth: calc(var(--default-clickable-area) + 2 * var(--default-grid-baseline));\n}\n\n.storageTable__headerFolder {\n\twidth: 25%;\n}\n\n.storageTable__headerBackend {\n\twidth: 20%;\n}\n\n.storageTable__headerFAuthentication {\n\twidth: 20%;\n}\n\n.storageTable__headerActions {\n\twidth: calc(2 * var(--default-clickable-area) + 3 * var(--default-grid-baseline));\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n<script setup lang=\"ts\">\nimport type { IBackend } from '../types.ts'\n\nimport { showError, showSuccess } from '@nextcloud/dialogs'\nimport { loadState } from '@nextcloud/initial-state'\nimport { translate as t } from '@nextcloud/l10n'\nimport { ref, watch } from 'vue'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'\n\nconst userMounting = loadState<{\n\tallowUserMounting: boolean\n\tallowedBackends: string[]\n}>('files_external', 'user-mounting')\n\nconst availableBackends = loadState<IBackend[]>('files_external', 'backends')\nconst allowUserMounting = ref(userMounting.allowUserMounting)\nconst allowedBackends = ref<string[]>(userMounting.allowedBackends)\n\n/**\n * When changing the enabled state of the user-mounting settings then also change this on the server\n */\nwatch(allowUserMounting, () => {\n\tconst backupValue = !allowUserMounting.value\n\twindow.OCP.AppConfig.setValue(\n\t\t'files_external',\n\t\t'allow_user_mounting',\n\t\tallowUserMounting.value ? 'yes' : 'no',\n\t\t{\n\t\t\tsuccess: () => showSuccess(t('files_external', 'Saved')),\n\t\t\terror: () => {\n\t\t\t\tallowUserMounting.value = backupValue\n\t\t\t\tshowError(t('files_external', 'Error while saving'))\n\t\t\t},\n\t\t},\n\t)\n})\n\n/**\n * Save list of allowed backends on the server\n *\n * @param newValue - The new changed value\n * @param oldValue - The old value for resetting on failure\n */\nwatch(allowedBackends, (newValue, oldValue) => {\n\t// save to server\n\twindow.OCP.AppConfig.setValue(\n\t\t'files_external',\n\t\t'user_mounting_backends',\n\t\tnewValue.join(','),\n\t\t{\n\t\t\tsuccess: () => showSuccess(t('files_external', 'Saved allowed backends')),\n\t\t\terror: () => {\n\t\t\t\tshowError(t('files_external', 'Failed to save allowed backends'))\n\t\t\t\tallowedBackends.value = oldValue\n\t\t\t},\n\t\t},\n\t)\n})\n</script>\n\n<template>\n\t<form>\n\t\t<h3 :class=\"$style.userMountSettings__heading\">\n\t\t\t{{ t('files_external', 'Advanced options for external storage mounts') }}\n\t\t</h3>\n\n\t\t<NcCheckboxRadioSwitch v-model=\"allowUserMounting\" type=\"switch\">\n\t\t\t{{ t('files_external', 'Allow people to mount external storage') }}\n\t\t</NcCheckboxRadioSwitch>\n\n\t\t<fieldset v-show=\"allowUserMounting\" :class=\"$style.userMountSettings__backends\">\n\t\t\t<legend>\n\t\t\t\t{{ t('files_external', 'External storage backends people are allowed to mount') }}\n\t\t\t</legend>\n\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\tv-for=\"backend of availableBackends\"\n\t\t\t\t:key=\"backend.identifier\"\n\t\t\t\tv-model=\"allowedBackends\"\n\t\t\t\t:value=\"backend.identifier\"\n\t\t\t\tname=\"allowUserMountingBackends[]\">\n\t\t\t\t{{ backend.name }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</fieldset>\n\t</form>\n</template>\n\n<style module>\n.userMountSettings__heading {\n\tfont-weight: bold;\n\tfont-size: 1.2rem;\n\n\tmargin-block-start: var(--default-clickable-area);\n}\n\n.userMountSettings__backends {\n\t--padding: calc((var(--default-clickable-area) - 20px) / 2 + var(--default-grid-baseline));\n\tmargin-block-start: var(--padding);\n\tmargin-inline-start: var(--padding);\n\n\tlegend {\n\t\tfont-weight: bold;\n\t}\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n<script setup lang=\"ts\">\nimport type { IStorage } from '../types.ts'\n\nimport { mdiPlus } from '@mdi/js'\nimport { loadState } from '@nextcloud/initial-state'\nimport { n, t } from '@nextcloud/l10n'\nimport { ref } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'\nimport NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'\nimport NcNoteCard from '@nextcloud/vue/components/NcNoteCard'\nimport NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'\nimport AddExternalStorageDialog from '../components/AddExternalStorageDialog/AddExternalStorageDialog.vue'\nimport ExternalStorageTable from '../components/ExternalStorageTable.vue'\nimport UserMountSettings from '../components/UserMountSettings.vue'\nimport filesExternalSvg from '../../img/app-dark.svg?raw'\nimport { useStorages } from '../store/storages.ts'\nimport logger from '../utils/logger.ts'\n\nconst settings = loadState('files_external', 'settings', {\n\tdocUrl: '',\n\tdependencyIssues: {\n\t\tmessages: null as string[] | null,\n\t\tmodules: null as Record<string, string[]> | null,\n\t},\n\tisAdmin: false,\n})\n\nconst store = useStorages()\n\n/** List of dependency issue messages */\nconst dependencyIssues = settings.dependencyIssues?.messages ?? []\n/** Map of missing modules -> list of dependant backends */\nconst missingModules = settings.dependencyIssues?.modules ?? {}\n\nconst showDialog = ref(false)\nconst newStorage = ref<Partial<IStorage>>()\n\n/**\n * Add a new external storage\n *\n * @param storage - The storage to add\n */\nasync function addStorage(storage?: Partial<IStorage>) {\n\tshowDialog.value = false\n\tif (!storage) {\n\t\treturn\n\t}\n\n\ttry {\n\t\tif (settings.isAdmin) {\n\t\t\tawait store.createGlobalStorage(storage)\n\t\t} else {\n\t\t\tawait store.createUserStorage(storage)\n\t\t}\n\t\tnewStorage.value = undefined\n\t} catch (error) {\n\t\tlogger.error('Failed to add external storage', { error })\n\t\tshowDialog.value = true\n\t}\n}\n</script>\n\n<template>\n\t<NcSettingsSection\n\t\t:doc-url=\"settings.docUrl\"\n\t\t:name=\"t('files_external', 'External storage')\"\n\t\t:description=\"\n\t\t\tt('files_external', 'External storage enables you to mount external storage services and devices as secondary Nextcloud storage devices.')\n\t\t\t\t+ (settings.isAdmin\n\t\t\t\t\t? ' ' + t('files_external', 'You may also allow people to mount their own external storage services.')\n\t\t\t\t\t: ''\n\t\t\t\t)\">\n\t\t<!-- Dependency error messages -->\n\t\t<NcNoteCard\n\t\t\tv-for=\"message, index of dependencyIssues\"\n\t\t\t:key=\"index\"\n\t\t\ttype=\"error\">\n\t\t\t{{ message }}\n\t\t</NcNoteCard>\n\n\t\t<!-- Missing modules for backends -->\n\t\t<NcNoteCard\n\t\t\tv-for=\"(dependants, module) in missingModules\"\n\t\t\t:key=\"module\"\n\t\t\ttype=\"warning\">\n\t\t\t<p>\n\t\t\t\t<template v-if=\"module === 'curl'\">\n\t\t\t\t\t{{ t('files_external', 'The cURL support in PHP is not enabled or installed.') }}\n\t\t\t\t</template>\n\t\t\t\t<template v-else-if=\"module === 'ftp'\">\n\t\t\t\t\t{{ t('files_external', 'The FTP support in PHP is not enabled or installed.') }}\n\t\t\t\t</template>\n\t\t\t\t<template v-else>\n\t\t\t\t\t{{ t('files_external', '{module} is not installed.', { module }) }}\n\t\t\t\t</template>\n\t\t\t\t{{ n(\n\t\t\t\t\t'files_external',\n\t\t\t\t\t'Please ask your system administrator to install it as otherwise mounting the following backend is not possible:',\n\t\t\t\t\t'Please ask your system administrator to install it as otherwise mounting the following backends is not possible:',\n\t\t\t\t\tdependants.length,\n\t\t\t\t) }}\n\t\t\t</p>\n\t\t\t<ul :class=\"$style.externalStoragesSection__dependantList\" :aria-label=\"t('files_external', 'Dependant backends')\">\n\t\t\t\t<li v-for=\"backend of dependants\" :key=\"backend\">\n\t\t\t\t\t{{ backend }}\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</NcNoteCard>\n\n\t\t<!-- For user settings if the user has no permission or for user and admin settings if no storage was configured -->\n\t\t<NcEmptyContent\n\t\t\tv-if=\"false\"\n\t\t\t:description=\"t('files_external', 'No external storage configured or you do not have the permission to configure them')\">\n\t\t\t<template #icon>\n\t\t\t\t<NcIconSvgWrapper :svg=\"filesExternalSvg\" :size=\"64\" />\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\n\t\t<ExternalStorageTable />\n\n\t\t<NcButton\n\t\t\t:class=\"$style.externalStoragesSection__newStorageButton\"\n\t\t\tvariant=\"primary\"\n\t\t\t@click=\"showDialog = !showDialog\">\n\t\t\t<template #icon>\n\t\t\t\t<NcIconSvgWrapper :path=\"mdiPlus\" />\n\t\t\t</template>\n\t\t\t{{ t('files_external', 'Add external storage') }}\n\t\t</NcButton>\n\n\t\t<AddExternalStorageDialog\n\t\t\tv-model=\"newStorage\"\n\t\t\tv-model:open=\"showDialog\"\n\t\t\t@close=\"addStorage\" />\n\n\t\t<UserMountSettings v-if=\"settings.isAdmin\" />\n\t</NcSettingsSection>\n</template>\n\n<style module>\n.externalStoragesSection__dependantList {\n\tlist-style: disc !important;\n\tmargin-inline-start: calc(var(--default-clickable-area) / 2);\n}\n\n.externalStoragesSection__newStorageButton {\n\tmargin-top: var(--default-clickable-area);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n\n<script setup lang=\"ts\">\nimport axios from '@nextcloud/axios'\nimport { showError, showSuccess } from '@nextcloud/dialogs'\nimport { loadState } from '@nextcloud/initial-state'\nimport { t } from '@nextcloud/l10n'\nimport { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation'\nimport { generateUrl } from '@nextcloud/router'\nimport { ref } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcPasswordField from '@nextcloud/vue/components/NcPasswordField'\nimport NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'\nimport NcTextField from '@nextcloud/vue/components/NcTextField'\nimport logger from '../utils/logger.ts'\n\nconst globalCredentials = loadState<{\n\tuid: string\n\tuser: string\n\tpassword: string\n}>('files_external', 'global-credentials')\n\nconst loading = ref(false)\nconst username = ref(globalCredentials.user)\nconst password = ref(globalCredentials.password)\n\naddPasswordConfirmationInterceptors(axios)\n\n/**\n * Submit the global credentials form\n */\nasync function onSubmit() {\n\ttry {\n\t\tloading.value = true\n\t\tconst { data } = await axios.post<boolean>(generateUrl('apps/files_external/globalcredentials'), {\n\t\t\t// This is the UID of the user to save the credentials (admins can set that also for other users)\n\t\t\tuid: globalCredentials.uid,\n\t\t\tuser: username.value,\n\t\t\tpassword: password.value,\n\t\t}, { confirmPassword: PwdConfirmationMode.Strict })\n\t\tif (data) {\n\t\t\tshowSuccess(t('files_external', 'Global credentials saved'))\n\t\t\treturn\n\t\t}\n\t} catch (e) {\n\t\tlogger.error(e as Error)\n\t\t// Error is handled below\n\t} finally {\n\t\tloading.value = false\n\t}\n\t// result was false so show an error\n\tshowError(t('files_external', 'Could not save global credentials'))\n\tusername.value = globalCredentials.user\n\tpassword.value = globalCredentials.password\n}\n</script>\n\n<template>\n\t<NcSettingsSection\n\t\t:name=\"t('files_external', 'Global credentials')\"\n\t\t:description=\"t('files_external', 'Global credentials can be used to authenticate with multiple external storages that have the same credentials.')\">\n\t\t<form\n\t\t\tid=\"global_credentials\"\n\t\t\t:class=\"$style.globalCredentialsSectionForm\"\n\t\t\tautocomplete=\"false\"\n\t\t\t@submit.prevent=\"onSubmit\">\n\t\t\t<NcTextField\n\t\t\t\tv-model=\"username\"\n\t\t\t\tname=\"username\"\n\t\t\t\tautocomplete=\"false\"\n\t\t\t\t:label=\"t('files_external', 'Login')\" />\n\t\t\t<NcPasswordField\n\t\t\t\tv-model=\"password\"\n\t\t\t\tname=\"password\"\n\t\t\t\tautocomplete=\"false\"\n\t\t\t\t:label=\"t('files_external', 'Password')\" />\n\t\t\t<NcButton\n\t\t\t\t:class=\"$style.globalCredentialsSectionForm__submit\"\n\t\t\t\t:disabled=\"loading\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\ttype=\"submit\">\n\t\t\t\t{{ loading ? t('files_external', 'Saving …') : t('files_external', 'Save') }}\n\t\t\t</NcButton>\n\t\t</form>\n\t</NcSettingsSection>\n</template>\n\n<style module>\n.globalCredentialsSectionForm {\n\tmax-width: 400px;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: end;\n\tgap: 15px;\n}\n\n.globalCredentialsSectionForm__submit {\n\tmin-width: max(40%, 44px);\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n -->\n<script setup lang=\"ts\">\nimport ExternalStoragesSection from './ExternalStoragesSection.vue'\nimport GlobalCredentialsSection from './GlobalCredentialsSection.vue'\n</script>\n\n<template>\n\t<ExternalStoragesSection />\n\t<GlobalCredentialsSection />\n</template>\n","/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { createPinia } from 'pinia'\nimport { createApp } from 'vue'\nimport FilesExternalApp from './views/FilesExternalSettings.vue'\n\nconst pinia = createPinia()\nconst app = createApp(FilesExternalApp)\napp.config.idPrefix = 'files-external'\napp.use(pinia)\napp.mount('#files-external')\n"],"names":["svgAccountGroupOutline","displayNames","reactive","useUsers","uids","users","computed","toValue","uid","watchEffect","missingUsers","data","axios","generateUrl","displayName","useGroups","gids","mapGroupToUserData","gid","groups","_useModel","__props","entities","ref","selectedUsers","selectedGroups","model","value","u","g","debouncedSearch","useDebounceFn","onSearch","pattern","newEntries","e","id","_createBlock","_unref","NcSelectUsers","$event","t","modelValue","props","configuration","entries","option","ConfigurationFlag","customComponent","hasConfiguration","isLoadingCustomComponent","watch","key","ConfigurationType","onUpdateModelValue","event","config","_createElementBlock","_normalizeClass","$style","_createElementVNode","_Fragment","NcLoadingIcon","_resolveDynamicComponent","_openBlock","_renderList","configOption","configKey","ConfigurationEntry","_vShow","mountOptions","MountOptionsCheckFilesystem","hasEncryption","loadState","idButton","useId","idFieldset","isExpanded","checkFilesystemOptions","checkFilesystem","_createVNode","NcButton","_cache","NcIconSvgWrapper","mdiChevronDown","mdiChevronRight","_createTextVNode","NcSelect","NcCheckboxRadioSwitch","isAdmin","allowedBackendIds","backends","b","allAuthMechanisms","open","internalStorage","toRaw","backend","authMechanisms","scheme","authMechanism","a","NcDialog","$emit","_toDisplayString","NcTextField","MountOptions","ApplicableEntities","BackendConfiguration","AuthMechanismConfiguration","useStorages","defineStore","globalStorages","userStorages","createGlobalStorage","storage","url","PwdConfirmationMode","createUserStorage","deleteStorage","getUrl","s","updateStorage","overrideStorage","reloadStorage","initialize","loadStorages","type","addPasswordConfirmationInterceptors","index","store","backendName","authMechanismName","checkingStatus","status","StorageStatus","label","StorageStatusMessage","icon","StorageStatusIcons","isWarning","isError","onDelete","onEdit","spawnDialog","AddExternalStorageDialog","reloadStatus","_hoisted_1","_hoisted_2","group","NcChip","mdiAccountGroupOutline","user","NcUserBubble","mdiPencilOutline","mdiTrashCanOutline","mdiInformationOutline","storages","_hoisted_4","ExternalStorageTableRow","userMounting","availableBackends","allowUserMounting","allowedBackends","backupValue","showSuccess","showError","newValue","oldValue","settings","dependencyIssues","missingModules","showDialog","newStorage","addStorage","error","logger","NcSettingsSection","message","NcNoteCard","dependants","module","n","ExternalStorageTable","mdiPlus","UserMountSettings","globalCredentials","loading","username","password","onSubmit","NcPasswordField","ExternalStoragesSection","GlobalCredentialsSection","pinia","createPinia","app","createApp","FilesExternalApp"],"mappings":"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","x_google_ignoreList":[0]} |