Skip to content
This repository was archived by the owner on Jul 14, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions apps/files/src/components/FilesAppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<oc-nav>
<file-upload :url='url' :headers="headers" @success="onFileSuccess" @error="onFileError" @progress="onFileProgress"></file-upload>
<folder-upload :rootPath='item' :url='url' :headers="headers" @success="onFileSuccess" @error="onFileError" @progress="onFileProgress"></folder-upload>
<oc-nav-item @click="createFolder = true" id="new-folder-btn" icon="create_new_folder"><translate>Create new folder…</translate></oc-nav-item>
<oc-nav-item @click="createFile = true" id="new-file-btn" icon="save"><translate>Create new file…</translate></oc-nav-item>
<oc-nav-item @click="showCreateFolderDialog" id="new-folder-btn" icon="create_new_folder"><translate>Create new folder…</translate></oc-nav-item>
<oc-nav-item @click="showCreateFileDialog" id="new-file-btn" icon="save"><translate>Create new file…</translate></oc-nav-item>
</oc-nav>
</oc-drop>
</template>
Expand All @@ -55,8 +55,8 @@
</div>
</oc-grid>
<oc-dialog-prompt name="overwrite-dialog" :oc-active="overwriteDialogMessage !== null" :oc-has-input="false" ocCancelId="files-overwrite-cancel" ocConfirmId="files-overwrite-confirm" :ocTitle="overwriteDialogTitle" :oc-content="overwriteDialogMessage" @oc-confirm="$_ocUpload_confirmOverwrite(true)" @oc-cancel="$_ocUpload_confirmOverwrite(false)" />
<oc-dialog-prompt name="new-folder-dialog" :oc-active="createFolder" v-model="newFolderName" ocInputId="new-folder-input" ocConfirmId="new-folder-ok" :ocLoading="fileFolderCreationLoading" :ocError="newFolderErrorMessage" :ocTitle="_createFolderDialogTitle" @oc-confirm="addNewFolder" @oc-cancel="createFolder = false; newFolderName = ''"></oc-dialog-prompt>
<oc-dialog-prompt name="new-file-dialog" :oc-active="createFile" v-model="newFileName" :ocLoading="fileFolderCreationLoading" :ocError="newFileErrorMessage" :ocTitle="_createFileDialogTitle" @oc-confirm="addNewFile" @oc-cancel="createFile = false; newFileName = ''"></oc-dialog-prompt>
<oc-dialog-prompt name="new-folder-dialog" :oc-active="createFolder" v-model="newFolderName" ocInputId="new-folder-input" ocConfirmId="new-folder-ok" :ocLoading="fileFolderCreationLoading" :ocError="newFolderErrorMessage" :ocTitle="$_createFolderDialogTitle" :ocInputPlaceholder="$_createFolderDialogPlaceholder" @oc-confirm="addNewFolder" @oc-cancel="createFolder = false"></oc-dialog-prompt>
<oc-dialog-prompt name="new-file-dialog" :oc-active="createFile" v-model="newFileName" :ocLoading="fileFolderCreationLoading" :ocError="newFileErrorMessage" :ocTitle="$_createFileDialogTitle" :ocInputPlaceholder="$_createFileDialogTitle" @oc-confirm="addNewFile" @oc-cancel="createFile = false"></oc-dialog-prompt>
</div>
</template>

Expand Down Expand Up @@ -100,10 +100,16 @@ export default {
searchLabel () {
return this.$gettext('Search')
},
_createFolderDialogTitle () {
$_createFolderDialogPlaceholder () {
return this.$gettext('Enter new folder name…')
},
$_createFolderDialogTitle () {
return this.$gettext('Create new folder…')
},
_createFileDialogTitle () {
$_createFileDialogPlaceholder () {
return this.$gettext('Enter new file name…')
},
$_createFileDialogTitle () {
return this.$gettext('Create new file…')
},
_cannotCreateDialogText () {
Expand Down Expand Up @@ -259,6 +265,10 @@ export default {
})
})
},
showCreateFolderDialog () {
this.createFolder = true
this.newFolderName = this.$gettext('New folder')
},
addNewFolder (folderName) {
if (folderName !== '') {
this.fileFolderCreationLoading = true
Expand All @@ -270,7 +280,6 @@ export default {

p.then(() => {
this.createFolder = false
this.newFolderName = ''
this.$_ocFilesFolder_getFolder()
})
.catch(error => {
Expand All @@ -286,6 +295,10 @@ export default {
}
},
checkNewFolderName (folderName) {
if (folderName === '') {
return this.$gettext('Folder name cannot be empty')
}

if (/[/]/.test(folderName)) {
return this.$gettext('Folder name cannot contain "/"')
}
Expand All @@ -311,6 +324,10 @@ export default {

return null
},
showCreateFileDialog () {
this.createFile = true
this.newFileName = this.$gettext('New file') + '.txt'
},
addNewFile (fileName) {
if (fileName !== '') {
this.fileFolderCreationLoading = true
Expand All @@ -321,7 +338,6 @@ export default {
}
p.then(() => {
this.createFile = false
this.newFileName = ''
this.$_ocFilesFolder_getFolder()
})
.catch(error => {
Expand All @@ -337,6 +353,10 @@ export default {
}
},
checkNewFileName (fileName) {
if (fileName === '') {
return this.$gettext('File name cannot be empty')
}

if (/[/]/.test(fileName)) {
return this.$gettext('File name cannot contain "/"')
}
Expand Down
3 changes: 2 additions & 1 deletion apps/files/src/components/ocDialogPrompt.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<template>
<oc-dialog :name="name" v-model="ocActive" :title="ocTitle">
<template slot="content">
<oc-alert v-if="ocError" id="oc-dialog-prompt-alert" :noClose="true" variation="danger">
<oc-alert v-if="ocError" class="oc-dialog-prompt-alert" :noClose="true" variation="danger">
{{ ocError }}
</oc-alert>
<span v-if="ocContent" class="uk-text-break">{{ ocContent }}</span>
<oc-text-input v-if="ocHasInput"
:disabled="ocLoading"
:placeholder="ocInputPlaceholder"
autofocus
:id="ocInputId"
v-model="inputValue"
Expand Down
20 changes: 20 additions & 0 deletions tests/acceptance/customCommands/clearValueWithEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// from https://github.com/nightwatchjs/nightwatch/issues/1132#issuecomment-340257894
// and adjusted a bit
// because calling "clearValue()" does not trigger Vue events when using v-model
/**
* A better `clearValue` for inputs having a more complex interaction.
*
* @export
* @param {string} selector
* @returns
*/
exports.command = function clearValueWithEvent (selector) {
const { RIGHT_ARROW, BACK_SPACE } = this.Keys
return this.getValue(selector, result => {
const chars = result.value.split('')
// Make sure we are at the end of the input
chars.forEach(() => this.setValue(selector, RIGHT_ARROW))
// Delete all the existing characters
chars.forEach(() => this.setValue(selector, BACK_SPACE))
})
}
8 changes: 8 additions & 0 deletions tests/acceptance/features/webUIFiles/createFolders.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ Feature: create folders
When the user reloads the current page of the webUI
Then folder "sub-folder" should be listed on the webUI

Scenario: Create a folder with default name
When the user creates a folder with default name using the webUI
Then folder "New folder" should be listed on the webUI

Scenario: Try to create a folder without name
When the user creates a folder without name using the webUI
Then the error message 'Folder name cannot be empty' should be displayed on the webUI dialog prompt

Scenario: Try to create a folder with existing name
When the user creates a folder with the invalid name "simple-folder" using the webUI
Then the error message 'simple-folder already exists' should be displayed on the webUI dialog prompt
Expand Down
11 changes: 8 additions & 3 deletions tests/acceptance/pageObjects/filesPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ module.exports = {
.assert.containsText('@breadcrumb', folder)
},
/**
* Create a folder with the given name
*
* @param {string} name
* @param {string} name to set or null to use default value from dialog
* @param {boolean} expectToSucceed
*/
createFolder: function (name, expectToSucceed = true) {
Expand All @@ -38,7 +39,11 @@ module.exports = {
.waitForElementVisible('@newFolderButton')
.click('@newFolderButton')
.waitForElementVisible('@newFolderInput')
.setValue('@newFolderInput', name)
if (name !== null) {
this.clearValueWithEvent('@newFolderInput')
this.setValue('@newFolderInput', name)
}
this
.click('@newFolderOkButton')
.waitForElementNotPresent('@createFolderLoadingIndicator')
if (expectToSucceed) {
Expand Down Expand Up @@ -152,7 +157,7 @@ module.exports = {
},
elements: {
newFileMenuButton: {
selector: '#new-file-menu-btn'
selector: '#new-file-menu-btn:enabled'
},
deleteSelectedButton: {
selector: '#delete-selected-btn'
Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/pageObjects/phoenixPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ module.exports = {
selector: '#resolve-notification-button'
},
ocDialogPromptAlert: {
selector: '#oc-dialog-prompt-alert'
selector: '.uk-modal.uk-open .oc-dialog-prompt-alert'
},
searchInputFieldHighResolution: {
selector: '(//input[contains(@class, "oc-search-input")])[1]',
Expand Down
8 changes: 8 additions & 0 deletions tests/acceptance/stepDefinitions/filesContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ When('the user creates a folder with the name {string} using the webUI', functio
return client.page.filesPage().createFolder(folderName)
})

When('the user creates a folder with default name using the webUI', function () {
return client.page.filesPage().createFolder(null, false)
})

When('the user creates a folder without name using the webUI', function () {
return client.page.filesPage().createFolder('', false)
})

When('the user creates a folder with the invalid name {string} using the webUI', function (folderName) {
return client.page.filesPage().createFolder(folderName, false)
})
Expand Down