mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #58041 from nextcloud/fix/renaming
feat(files): warn when file would be hidden
This commit is contained in:
commit
29e1ac3c02
13 changed files with 354 additions and 49 deletions
|
|
@ -40,7 +40,6 @@
|
|||
ref="name"
|
||||
:basename="basename"
|
||||
:extension="extension"
|
||||
:nodes="nodes"
|
||||
:source="source"
|
||||
@auxclick.native="execDefaultAction"
|
||||
@click.native="execDefaultAction" />
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
ref="renameInput"
|
||||
v-model="newName"
|
||||
:label="renameLabel"
|
||||
:autofocus="true"
|
||||
autofocus
|
||||
required
|
||||
:minlength="1"
|
||||
:required="true"
|
||||
enterkeyhint="done"
|
||||
@keyup.esc="stopRenaming" />
|
||||
</form>
|
||||
|
|
@ -45,6 +45,7 @@ import type { PropType } from 'vue'
|
|||
import { showError } from '@nextcloud/dialogs'
|
||||
import { FileType, NodeStatus } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { basename } from '@nextcloud/paths'
|
||||
import { defineComponent, inject } from 'vue'
|
||||
import NcTextField from '@nextcloud/vue/components/NcTextField'
|
||||
import { useFileListWidth } from '../../composables/useFileListWidth.ts'
|
||||
|
|
@ -78,20 +79,10 @@ export default defineComponent({
|
|||
required: true,
|
||||
},
|
||||
|
||||
nodes: {
|
||||
type: Array as PropType<Node[]>,
|
||||
required: true,
|
||||
},
|
||||
|
||||
source: {
|
||||
type: Object as PropType<Node>,
|
||||
required: true,
|
||||
},
|
||||
|
||||
gridMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
|
|
@ -153,8 +144,8 @@ export default defineComponent({
|
|||
if (this.defaultFileAction) {
|
||||
const displayName = this.defaultFileAction.displayName({
|
||||
nodes: [this.source],
|
||||
view: this.activeView,
|
||||
folder: this.activeFolder,
|
||||
view: this.activeView!,
|
||||
folder: this.activeFolder!,
|
||||
contents: [],
|
||||
})
|
||||
return {
|
||||
|
|
@ -215,7 +206,8 @@ export default defineComponent({
|
|||
|
||||
methods: {
|
||||
checkIfNodeExists(name: string) {
|
||||
return this.nodes.find((node) => node.basename === name && node !== this.source)
|
||||
const sources: string[] = (this.activeFolder as { _children?: string[] })?._children || []
|
||||
return sources.some((sourceName) => basename(sourceName) === name)
|
||||
},
|
||||
|
||||
startRenaming() {
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@
|
|||
ref="name"
|
||||
:basename="basename"
|
||||
:extension="extension"
|
||||
:grid-mode="true"
|
||||
:nodes="nodes"
|
||||
:source="source"
|
||||
@auxclick.native="execDefaultAction"
|
||||
@click.native="execDefaultAction" />
|
||||
|
|
|
|||
2
apps/files/src/eventbus.d.ts
vendored
2
apps/files/src/eventbus.d.ts
vendored
|
|
@ -27,7 +27,7 @@ declare module '@nextcloud/event-bus' {
|
|||
'files:node:updated': INode
|
||||
'files:node:rename': INode
|
||||
'files:node:renamed': INode
|
||||
'files:node:moved': { INode: INode, oldSource: string }
|
||||
'files:node:moved': { node: INode, oldSource: string }
|
||||
|
||||
'files:search:updated': { query: string, scope: SearchScope }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import type { Node } from '@nextcloud/files'
|
||||
|
||||
import type { INode } from '@nextcloud/files'
|
||||
|
||||
import axios, { isAxiosError } from '@nextcloud/axios'
|
||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||
|
|
@ -20,7 +21,7 @@ export const useRenamingStore = defineStore('renaming', () => {
|
|||
/**
|
||||
* The currently renamed node
|
||||
*/
|
||||
const renamingNode = ref<Node>()
|
||||
const renamingNode = ref<INode>()
|
||||
/**
|
||||
* The new name of the currently renamed node
|
||||
*/
|
||||
|
|
@ -43,37 +44,47 @@ export const useRenamingStore = defineStore('renaming', () => {
|
|||
throw new Error('No node is currently being renamed')
|
||||
}
|
||||
|
||||
const oldName = renamingNode.value.basename
|
||||
let newName = newNodeName.value.trim()
|
||||
if (newName === oldName) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Only rename once so we use this as some kind of mutex
|
||||
if (isRenaming.value) {
|
||||
return false
|
||||
}
|
||||
isRenaming.value = true
|
||||
|
||||
const userConfig = useUserConfigStore()
|
||||
let node = renamingNode.value
|
||||
Vue.set(node, 'status', NodeStatus.LOADING)
|
||||
|
||||
const userConfig = useUserConfigStore()
|
||||
|
||||
let newName = newNodeName.value.trim()
|
||||
const oldName = node.basename
|
||||
const oldExtension = extname(oldName)
|
||||
const newExtension = extname(newName)
|
||||
// Check for extension change for files
|
||||
if (node.type === FileType.File
|
||||
&& oldExtension !== newExtension
|
||||
&& userConfig.userConfig.show_dialog_file_extension
|
||||
&& !(await showFileExtensionDialog(oldExtension, newExtension))
|
||||
) {
|
||||
// user selected to use the old extension
|
||||
newName = basename(newName, newExtension) + oldExtension
|
||||
}
|
||||
|
||||
const oldEncodedSource = node.encodedSource
|
||||
try {
|
||||
if (oldName === newName) {
|
||||
return false
|
||||
if (userConfig.userConfig.show_dialog_file_extension) {
|
||||
const oldExtension = extname(oldName)
|
||||
const newExtension = extname(newName)
|
||||
// Check for extension change for files
|
||||
if (node.type === FileType.File
|
||||
&& oldExtension !== newExtension
|
||||
&& !(await showFileExtensionDialog(oldExtension, newExtension))
|
||||
) {
|
||||
// user selected to use the old extension
|
||||
newName = basename(newName, newExtension) + oldExtension
|
||||
if (oldName === newName) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (!userConfig.userConfig.show_hidden
|
||||
&& newName.startsWith('.')
|
||||
&& !oldName.startsWith('.')
|
||||
&& !(await showHiddenFileDialog(newName))
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const oldEncodedSource = node.encodedSource
|
||||
// rename the node
|
||||
node.rename(newName)
|
||||
logger.debug('Moving file to', { destination: node.encodedSource, oldEncodedSource })
|
||||
|
|
@ -90,7 +101,7 @@ export const useRenamingStore = defineStore('renaming', () => {
|
|||
// Update mime type if extension changed
|
||||
// as other related informations might have changed
|
||||
// on the backend but it is really hard to know on the front
|
||||
if (oldExtension !== newExtension) {
|
||||
if (extname(oldName) !== extname(newName)) {
|
||||
node = await fetchNode(node.path)
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +155,7 @@ export const useRenamingStore = defineStore('renaming', () => {
|
|||
}
|
||||
|
||||
// Make sure we only register the listeners once
|
||||
subscribe('files:node:rename', (node: Node) => {
|
||||
subscribe('files:node:rename', (node: INode) => {
|
||||
renamingNode.value = node
|
||||
newNodeName.value = node.basename
|
||||
})
|
||||
|
|
@ -166,10 +177,25 @@ export const useRenamingStore = defineStore('renaming', () => {
|
|||
*/
|
||||
async function showFileExtensionDialog(oldExtension: string, newExtension: string): Promise<boolean> {
|
||||
const { promise, resolve } = Promise.withResolvers<boolean>()
|
||||
spawnDialog(
|
||||
await spawnDialog(
|
||||
defineAsyncComponent(() => import('../views/DialogConfirmFileExtension.vue')),
|
||||
{ oldExtension, newExtension },
|
||||
(useNewExtension: unknown) => resolve(Boolean(useNewExtension)),
|
||||
resolve,
|
||||
)
|
||||
return await promise
|
||||
return promise
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a dialog asking user for confirmation about renaming a file to a hidden file.
|
||||
*
|
||||
* @param filename - The new filename
|
||||
*/
|
||||
async function showHiddenFileDialog(filename: string): Promise<boolean> {
|
||||
const { promise, resolve } = Promise.withResolvers<boolean>()
|
||||
await spawnDialog(
|
||||
defineAsyncComponent(() => import('../views/DialogConfirmFileHidden.vue')),
|
||||
{ filename },
|
||||
resolve,
|
||||
)
|
||||
return promise
|
||||
}
|
||||
|
|
|
|||
94
apps/files/src/views/DialogConfirmFileHidden.spec.ts
Normal file
94
apps/files/src/views/DialogConfirmFileHidden.spec.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { cleanup, fireEvent, render } from '@testing-library/vue'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import DialogConfirmFileHidden from './DialogConfirmFileHidden.vue'
|
||||
import { useUserConfigStore } from '../store/userconfig.ts'
|
||||
|
||||
describe('DialogConfirmFileHidden', () => {
|
||||
beforeEach(cleanup)
|
||||
|
||||
it('renders', async () => {
|
||||
const component = render(DialogConfirmFileHidden, {
|
||||
props: {
|
||||
filename: '.filename.txt',
|
||||
},
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: vi.fn,
|
||||
})],
|
||||
},
|
||||
})
|
||||
|
||||
await expect(component.findByRole('dialog', { name: 'Rename file to hidden' })).resolves.not.toThrow()
|
||||
expect((component.getByRole('checkbox', { name: /Do not show this dialog again/i }) as HTMLInputElement).checked).toBe(false)
|
||||
await expect(component.findByRole('button', { name: 'Cancel' })).resolves.not.toThrow()
|
||||
await expect(component.findByRole('button', { name: 'Rename' })).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
it('emits false value on cancel', async () => {
|
||||
const onclose = vi.fn()
|
||||
const component = render(DialogConfirmFileHidden, {
|
||||
props: {
|
||||
filename: '.filename.txt',
|
||||
},
|
||||
listeners: {
|
||||
close: onclose,
|
||||
},
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: vi.fn,
|
||||
})],
|
||||
},
|
||||
})
|
||||
|
||||
await fireEvent.click(component.getByRole('button', { name: 'Cancel' }))
|
||||
expect(onclose).toHaveBeenCalledOnce()
|
||||
expect(onclose).toHaveBeenCalledWith(false)
|
||||
})
|
||||
|
||||
it('emits true on rename', async () => {
|
||||
const onclose = vi.fn()
|
||||
const component = render(DialogConfirmFileHidden, {
|
||||
props: {
|
||||
filename: '.filename.txt',
|
||||
},
|
||||
listeners: {
|
||||
close: onclose,
|
||||
},
|
||||
global: {
|
||||
plugins: [createTestingPinia({
|
||||
createSpy: vi.fn,
|
||||
})],
|
||||
},
|
||||
})
|
||||
|
||||
await fireEvent.click(component.getByRole('button', { name: 'Rename' }))
|
||||
expect(onclose).toHaveBeenCalledOnce()
|
||||
expect(onclose).toHaveBeenCalledWith(true)
|
||||
})
|
||||
|
||||
it('updates user config when checking the checkbox', async () => {
|
||||
const pinia = createTestingPinia({
|
||||
createSpy: vi.fn,
|
||||
})
|
||||
|
||||
const component = render(DialogConfirmFileHidden, {
|
||||
props: {
|
||||
filename: '.filename.txt',
|
||||
},
|
||||
global: {
|
||||
plugins: [pinia],
|
||||
},
|
||||
})
|
||||
|
||||
await fireEvent.click(component.getByRole('checkbox', { name: /Do not show this dialog again/i }))
|
||||
const store = useUserConfigStore()
|
||||
expect(store.update).toHaveBeenCalledOnce()
|
||||
expect(store.update).toHaveBeenCalledWith('show_dialog_file_extension', false)
|
||||
})
|
||||
})
|
||||
76
apps/files/src/views/DialogConfirmFileHidden.vue
Normal file
76
apps/files/src/views/DialogConfirmFileHidden.vue
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { computed, ref } from 'vue'
|
||||
import NcButton from '@nextcloud/vue/components/NcButton'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
|
||||
import NcDialog from '@nextcloud/vue/components/NcDialog'
|
||||
import { useUserConfigStore } from '../store/userconfig.ts'
|
||||
|
||||
const props = defineProps<{
|
||||
filename: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'close', v: boolean): void
|
||||
}>()
|
||||
|
||||
const userConfigStore = useUserConfigStore()
|
||||
const dontShowAgain = computed({
|
||||
get: () => !userConfigStore.userConfig.show_dialog_file_extension,
|
||||
set: (value: boolean) => userConfigStore.update('show_dialog_file_extension', !value),
|
||||
})
|
||||
|
||||
/** Open state of the dialog */
|
||||
const open = ref(true)
|
||||
|
||||
/**
|
||||
* Close the dialog and emit the response
|
||||
*
|
||||
* @param value User selected response
|
||||
*/
|
||||
function closeDialog(value: boolean) {
|
||||
emit('close', value)
|
||||
open.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcDialog
|
||||
no-close
|
||||
:open="open"
|
||||
:name="t('files', 'Rename file to hidden')"
|
||||
size="small">
|
||||
<div>
|
||||
<p>
|
||||
{{ t('files', 'Prefixing a filename with a dot may render the file hidden.') }}
|
||||
{{ t('files', 'Are you sure you want to rename the file to "{filename}"?', { filename: props.filename }) }}
|
||||
</p>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
v-model="dontShowAgain"
|
||||
:class="$style.dialogConfirmFileHidden__checkbox"
|
||||
type="switch">
|
||||
{{ t('files', 'Do not show this dialog again.') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</div>
|
||||
<template #actions>
|
||||
<NcButton variant="secondary" @click="closeDialog(false)">
|
||||
{{ t('files', 'Cancel') }}
|
||||
</NcButton>
|
||||
<NcButton variant="primary" @click="closeDialog(true)">
|
||||
{{ t('files', 'Rename') }}
|
||||
</NcButton>
|
||||
</template>
|
||||
</NcDialog>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.dialogConfirmFileHidden__checkbox {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
2
dist/4723-4723.js
vendored
Normal file
2
dist/4723-4723.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";(globalThis.webpackChunknextcloud_ui_legacy=globalThis.webpackChunknextcloud_ui_legacy||[]).push([[4723],{35412(t,e,n){n.d(e,{A:()=>a});var o=n(71354),i=n.n(o),l=n(76314),s=n.n(l)()(i());s.push([t.id,"\n._dialogConfirmFileHidden__checkbox_CoKAM {\n\tmargin-top: 1rem;\n}\n","",{version:3,sources:["webpack://./apps/files/src/views/DialogConfirmFileHidden.vue"],names:[],mappings:";AAwEA;CACA,gBAAA;AACA",sourcesContent:["\x3c!--\n - SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n\n<script setup lang=\"ts\">\nimport { t } from '@nextcloud/l10n'\nimport { computed, ref } from 'vue'\nimport NcButton from '@nextcloud/vue/components/NcButton'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'\nimport NcDialog from '@nextcloud/vue/components/NcDialog'\nimport { useUserConfigStore } from '../store/userconfig.ts'\n\nconst props = defineProps<{\n\tfilename: string\n}>()\n\nconst emit = defineEmits<{\n\t(e: 'close', v: boolean): void\n}>()\n\nconst userConfigStore = useUserConfigStore()\nconst dontShowAgain = computed({\n\tget: () => !userConfigStore.userConfig.show_dialog_file_extension,\n\tset: (value: boolean) => userConfigStore.update('show_dialog_file_extension', !value),\n})\n\n/** Open state of the dialog */\nconst open = ref(true)\n\n/**\n * Close the dialog and emit the response\n *\n * @param value User selected response\n */\nfunction closeDialog(value: boolean) {\n\temit('close', value)\n\topen.value = false\n}\n<\/script>\n\n<template>\n\t<NcDialog\n\t\tno-close\n\t\t:open=\"open\"\n\t\t:name=\"t('files', 'Rename file to hidden')\"\n\t\tsize=\"small\">\n\t\t<div>\n\t\t\t<p>\n\t\t\t\t{{ t('files', 'Prefixing a filename with a dot may render the file hidden.') }}\n\t\t\t\t{{ t('files', 'Are you sure you want to rename the file to \"{filename}\"?', { filename: props.filename }) }}\n\t\t\t</p>\n\n\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\tv-model=\"dontShowAgain\"\n\t\t\t\t:class=\"$style.dialogConfirmFileHidden__checkbox\"\n\t\t\t\ttype=\"switch\">\n\t\t\t\t{{ t('files', 'Do not show this dialog again.') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton variant=\"secondary\" @click=\"closeDialog(false)\">\n\t\t\t\t{{ t('files', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton variant=\"primary\" @click=\"closeDialog(true)\">\n\t\t\t\t{{ t('files', 'Rename') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<style module>\n.dialogConfirmFileHidden__checkbox {\n\tmargin-top: 1rem;\n}\n</style>\n"],sourceRoot:""}]),s.locals={dialogConfirmFileHidden__checkbox:"_dialogConfirmFileHidden__checkbox_CoKAM"};const a=s},54723(t,e,n){n.r(e),n.d(e,{default:()=>k});var o=n(85471),i=n(53334),l=n(74095),s=n(32073),a=n(94219),c=n(69379);const r=(0,o.pM)({__name:"DialogConfirmFileHidden",props:{filename:null},emits:["close"],setup(t,{emit:e}){const n=t,r=(0,c.O)(),d=(0,o.EW)({get:()=>!r.userConfig.show_dialog_file_extension,set:t=>r.update("show_dialog_file_extension",!t)}),u=(0,o.KR)(!0);return{__sfc:!0,props:n,emit:e,userConfigStore:r,dontShowAgain:d,open:u,closeDialog:function(t){e("close",t),u.value=!1},t:i.t,NcButton:l.A,NcCheckboxRadioSwitch:s.A,NcDialog:a.A}}});var d=n(85072),u=n.n(d),f=n(97825),m=n.n(f),p=n(77659),g=n.n(p),h=n(55056),_=n.n(h),v=n(10540),C=n.n(v),x=n(41113),A=n.n(x),w=n(35412),b={};b.styleTagTransform=A(),b.setAttributes=_(),b.insert=g().bind(null,"head"),b.domAPI=m(),b.insertStyleElement=C(),u()(w.A,b);const y=w.A&&w.A.locals?w.A.locals:void 0,k=(0,n(14486).A)(r,function(){var t=this,e=t._self._c,n=t._self._setupProxy;return e(n.NcDialog,{attrs:{"no-close":"",open:n.open,name:n.t("files","Rename file to hidden"),size:"small"},scopedSlots:t._u([{key:"actions",fn:function(){return[e(n.NcButton,{attrs:{variant:"secondary"},on:{click:function(t){return n.closeDialog(!1)}}},[t._v("\n\t\t\t"+t._s(n.t("files","Cancel"))+"\n\t\t")]),t._v(" "),e(n.NcButton,{attrs:{variant:"primary"},on:{click:function(t){return n.closeDialog(!0)}}},[t._v("\n\t\t\t"+t._s(n.t("files","Rename"))+"\n\t\t")])]},proxy:!0}])},[e("div",[e("p",[t._v("\n\t\t\t"+t._s(n.t("files","Prefixing a filename with a dot may render the file hidden."))+"\n\t\t\t"+t._s(n.t("files",'Are you sure you want to rename the file to "{filename}"?',{filename:n.props.filename}))+"\n\t\t")]),t._v(" "),e(n.NcCheckboxRadioSwitch,{class:t.$style.dialogConfirmFileHidden__checkbox,attrs:{type:"switch"},model:{value:n.dontShowAgain,callback:function(t){n.dontShowAgain=t},expression:"dontShowAgain"}},[t._v("\n\t\t\t"+t._s(n.t("files","Do not show this dialog again."))+"\n\t\t")])],1)])},[],!1,function(t){this.$style=y.locals||y},null,null).exports}}]);
|
||||
//# sourceMappingURL=4723-4723.js.map?v=934c36402dc782526ac6
|
||||
116
dist/4723-4723.js.license
vendored
Normal file
116
dist/4723-4723.js.license
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
SPDX-License-Identifier: MIT
|
||||
SPDX-License-Identifier: ISC
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
SPDX-License-Identifier: (MPL-2.0 OR Apache-2.0)
|
||||
SPDX-FileCopyrightText: escape-html developers
|
||||
SPDX-FileCopyrightText: Tobias Koppers @sokra
|
||||
SPDX-FileCopyrightText: T. Jameson Little <t.jameson.little@gmail.com>
|
||||
SPDX-FileCopyrightText: Roman Shtylman <shtylman@gmail.com>
|
||||
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
||||
SPDX-FileCopyrightText: Matt Zabriskie
|
||||
SPDX-FileCopyrightText: Guillaume Chau <guillaume.b.chau@gmail.com>
|
||||
SPDX-FileCopyrightText: Guillaume Chau
|
||||
SPDX-FileCopyrightText: GitHub Inc.
|
||||
SPDX-FileCopyrightText: Feross Aboukhadijeh
|
||||
SPDX-FileCopyrightText: Evan You
|
||||
SPDX-FileCopyrightText: Eduardo San Martin Morote
|
||||
SPDX-FileCopyrightText: Dr.-Ing. Mario Heiderich, Cure53 <mario@cure53.de> (https://cure53.de/)
|
||||
SPDX-FileCopyrightText: David Clark
|
||||
SPDX-FileCopyrightText: Christoph Wurst
|
||||
SPDX-FileCopyrightText: Anthony Fu <https://github.com/antfu>
|
||||
SPDX-FileCopyrightText: Anthony Fu <anthonyfu117@hotmail.com>
|
||||
|
||||
|
||||
This file is generated from multiple sources. Included packages:
|
||||
- @nextcloud/auth
|
||||
- version: 2.5.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/axios
|
||||
- version: 2.5.2
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/browser-storage
|
||||
- version: 0.5.0
|
||||
- license: GPL-3.0-or-later
|
||||
- semver
|
||||
- version: 7.7.2
|
||||
- license: ISC
|
||||
- @nextcloud/event-bus
|
||||
- version: 3.3.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/initial-state
|
||||
- version: 3.0.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/l10n
|
||||
- version: 3.4.1
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/logger
|
||||
- version: 3.0.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/router
|
||||
- version: 3.1.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/vue
|
||||
- version: 8.35.3
|
||||
- license: AGPL-3.0-or-later
|
||||
- @vue/devtools-api
|
||||
- version: 6.6.4
|
||||
- license: MIT
|
||||
- @vueuse/core
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- @vueuse/shared
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- axios
|
||||
- version: 1.12.2
|
||||
- license: MIT
|
||||
- base64-js
|
||||
- version: 1.5.1
|
||||
- license: MIT
|
||||
- css-loader
|
||||
- version: 7.1.2
|
||||
- license: MIT
|
||||
- dompurify
|
||||
- version: 3.3.1
|
||||
- license: (MPL-2.0 OR Apache-2.0)
|
||||
- escape-html
|
||||
- version: 1.0.3
|
||||
- license: MIT
|
||||
- floating-vue
|
||||
- version: 1.0.0-beta.19
|
||||
- license: MIT
|
||||
- focus-trap
|
||||
- version: 7.8.0
|
||||
- license: MIT
|
||||
- ieee754
|
||||
- version: 1.2.1
|
||||
- license: BSD-3-Clause
|
||||
- buffer
|
||||
- version: 6.0.3
|
||||
- license: MIT
|
||||
- pinia
|
||||
- version: 2.3.1
|
||||
- license: MIT
|
||||
- process
|
||||
- version: 0.11.10
|
||||
- license: MIT
|
||||
- style-loader
|
||||
- version: 4.0.0
|
||||
- license: MIT
|
||||
- tabbable
|
||||
- version: 6.4.0
|
||||
- license: MIT
|
||||
- vue-demi
|
||||
- version: 0.14.10
|
||||
- license: MIT
|
||||
- vue-loader
|
||||
- version: 15.11.1
|
||||
- license: MIT
|
||||
- vue
|
||||
- version: 2.7.16
|
||||
- license: MIT
|
||||
- nextcloud
|
||||
- version: 1.0.0
|
||||
- license: AGPL-3.0-or-later
|
||||
1
dist/4723-4723.js.map
vendored
Normal file
1
dist/4723-4723.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/4723-4723.js.map.license
vendored
Symbolic link
1
dist/4723-4723.js.map.license
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
4723-4723.js.license
|
||||
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue