mirror of
https://github.com/nextcloud/richdocuments.git
synced 2025-12-17 21:12:14 +01:00
Merge pull request #5186 from nextcloud/fix/moved-to-root
fix: document created in wrong location on public share
This commit is contained in:
commit
bd709674bd
8 changed files with 74 additions and 161 deletions
|
|
@ -2,8 +2,8 @@
|
|||
* SPDX-FileCopyrightText: 2023 Julius Härtl <jus@bitgrid.net>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
// FIXME: Re-renable once 28 has file creation again working
|
||||
describe.skip('Create new office files', function() {
|
||||
|
||||
describe('New file menu', function() {
|
||||
|
||||
let randUser
|
||||
before(function() {
|
||||
|
|
@ -18,51 +18,34 @@ describe.skip('Create new office files', function() {
|
|||
})
|
||||
|
||||
it('Shows create file entries', function() {
|
||||
cy.get('.files-controls .button.new')
|
||||
cy.get('form[data-cy-upload-picker=""]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
|
||||
cy.get('.newFileMenu', { timeout: 10000 })
|
||||
cy.get('button[role="menuitem"]')
|
||||
.contains('New document')
|
||||
.should('be.visible')
|
||||
.contains('.menuitem', 'New document')
|
||||
.should('be.visible')
|
||||
.find('.icon')
|
||||
.should('have.css', 'background-image')
|
||||
|
||||
cy.get('.files-controls .button.new')
|
||||
cy.get('form[data-cy-upload-picker=""]')
|
||||
.click()
|
||||
|
||||
cy.get('.newFileMenu', { timeout: 10000 })
|
||||
cy.get('li[data-cy-upload-picker-menu-entry="upload-file"]')
|
||||
.should('not.be.visible')
|
||||
})
|
||||
|
||||
const newFileTypeLabels = [
|
||||
'document', 'spreadsheet', 'presentation', 'diagram',
|
||||
]
|
||||
newFileTypeLabels.forEach((filetype) => {
|
||||
it('Create empty ' + filetype + ' file', function() {
|
||||
cy.get('.files-controls .button.new')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
describe('Creates a new file', function() {
|
||||
const newFileTypeLabels = [
|
||||
'document', 'spreadsheet', 'presentation', 'diagram',
|
||||
]
|
||||
newFileTypeLabels.forEach((filetype) => {
|
||||
it('Create empty ' + filetype + ' file', function() {
|
||||
cy.newFileFromMenu(filetype, 'MyNewFile')
|
||||
cy.waitForViewer()
|
||||
cy.waitForCollabora()
|
||||
|
||||
cy.get('.newFileMenu', { timeout: 10000 })
|
||||
.should('be.visible')
|
||||
.contains('.menuitem', 'New ' + filetype)
|
||||
.as('menuitem')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
cy.screenshot('new-file-' + filetype)
|
||||
|
||||
cy.get('@menuitem').find('.filenameform input[type=text]').type('MyNewFile')
|
||||
cy.get('@menuitem').find('.filenameform .icon-confirm').click()
|
||||
|
||||
cy.waitForViewer()
|
||||
cy.waitForCollabora()
|
||||
|
||||
cy.screenshot('new-file-' + filetype)
|
||||
|
||||
cy.get('@loleafletframe').within(() => {
|
||||
cy.get('#closebutton').click()
|
||||
cy.waitForViewerClose()
|
||||
cy.closeDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { randHash } from '../utils/index.js'
|
|||
const shareOwner = new User(randHash(), randHash())
|
||||
const otherUser = new User(randHash(), randHash())
|
||||
|
||||
describe.skip('Public sharing of office documents', () => {
|
||||
describe('Public sharing of office documents', () => {
|
||||
before(function() {
|
||||
cy.nextcloudTestingAppConfigSet('richdocuments', 'doc_format', '')
|
||||
cy.createUser(shareOwner)
|
||||
|
|
@ -105,6 +105,37 @@ describe.skip('Public sharing of office documents', () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('New file', () => {
|
||||
before(() => {
|
||||
cy.createFolder(shareOwner, '/Shared-Folder')
|
||||
cy.createFolder(shareOwner, '/Shared-Folder/Subfolder')
|
||||
})
|
||||
|
||||
it('Creates a new file in a public share as a guest', () => {
|
||||
cy.shareLink(shareOwner, '/Shared-Folder', { permissions: 13 }).then((token) => {
|
||||
cy.logout()
|
||||
|
||||
cy.visit(`/s/${token}`, {
|
||||
onBeforeLoad(win) {
|
||||
cy.spy(win, 'postMessage').as('postMessage')
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('tr[data-cy-files-list-row-name="Subfolder"]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
|
||||
cy.newFileFromMenu('document', 'MyNewFile')
|
||||
waitForCollabora()
|
||||
|
||||
// Make sure the document is still in the correct subfolder
|
||||
cy.reload()
|
||||
cy.get('tr[data-cy-files-list-row-name="MyNewFile.odt"]')
|
||||
.should('be.visible')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -454,3 +454,18 @@ Cypress.Commands.add('makeTalkRoomPublic', (user, token, password = '') => {
|
|||
})
|
||||
})
|
||||
|
||||
Cypress.Commands.add('newFileFromMenu', (fileType = 'document', fileName = 'MyNewFile') => {
|
||||
cy.get('div[data-cy-files-content-breadcrumbs=""]')
|
||||
.find('form[data-cy-upload-picker=""]')
|
||||
.should('be.visible')
|
||||
.click()
|
||||
|
||||
cy.get('button[role="menuitem"]')
|
||||
.contains('New ' + fileType)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
|
||||
cy.get('input[data-cy-files-new-node-dialog-input=""]')
|
||||
.should('be.visible')
|
||||
.type(fileName + '{enter}')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -34,7 +34,13 @@ class RegisterTemplateFileCreatorListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->permissionManager->isEnabledForUser() || !$this->permissionManager->userCanEdit() || empty($this->capabilitiesService->getCapabilities())) {
|
||||
if (empty($this->capabilitiesService->getCapabilities())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $this->permissionManager->loggedInUser();
|
||||
$userCanCreate = $this->permissionManager->isEnabledForUser($user) && $this->permissionManager->userCanEdit($user);
|
||||
if ($user && !$userCanCreate) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,12 @@ import {
|
|||
isDownloadHidden,
|
||||
} from './helpers/index.js'
|
||||
import { getCapabilities } from './services/capabilities.ts'
|
||||
import { registerNewFileMenuEntries } from './view/NewFileMenu.js'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (!isPublicShare() || !OCA.Viewer) {
|
||||
return
|
||||
}
|
||||
|
||||
registerNewFileMenuEntries()
|
||||
|
||||
const isEnabledFilesPdfViewer = getCapabilities().mimetypesNoDefaultOpen.includes('application/pdf')
|
||||
|
||||
if ((isDownloadHidden() || !isEnabledFilesPdfViewer) && isPdf()) {
|
||||
|
|
|
|||
|
|
@ -4,22 +4,7 @@
|
|||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import { generateOcsUrl, generateFilePath } from '@nextcloud/router'
|
||||
import { getSharingToken } from '@nextcloud/sharing/public'
|
||||
|
||||
export const createEmptyFile = async (context, mimeType, fileName, templateId = null) => {
|
||||
const shareToken = getSharingToken()
|
||||
|
||||
const response = await axios.post(generateOcsUrl('apps/richdocuments/api/v1/file', 2), {
|
||||
mimeType,
|
||||
fileName,
|
||||
directoryPath: context.dirname,
|
||||
shareToken,
|
||||
templateId,
|
||||
})
|
||||
|
||||
return response.data
|
||||
}
|
||||
import { generateFilePath } from '@nextcloud/router'
|
||||
|
||||
export const savePersonalSetting = (data) => {
|
||||
return axios.post(generateFilePath('richdocuments', 'ajax', 'personal.php'), data)
|
||||
|
|
|
|||
|
|
@ -1,105 +0,0 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import Types from '../helpers/types.js'
|
||||
import { createEmptyFile } from '../services/api.js'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
import { showError, spawnDialog } from '@nextcloud/dialogs'
|
||||
import { getCapabilities } from '../services/capabilities.ts'
|
||||
import { File, addNewFileMenuEntry, isFilenameValid, getUniqueName } from '@nextcloud/files'
|
||||
import TemplatePicker from '../components/Modal/TemplatePicker.vue'
|
||||
|
||||
const createFileTypeEntry = (type, displayName, iconClass, index) => ({
|
||||
id: 'add-' + type.extension,
|
||||
displayName: t('richdocuments', displayName),
|
||||
iconClass,
|
||||
order: 10 + index,
|
||||
async handler(context, content) {
|
||||
const filename = t('richdocuments', displayName) + '.' + type.extension
|
||||
if (getCapabilities().templates) {
|
||||
await openTemplatePicker(context, type.name, type.mime, filename, content)
|
||||
} else {
|
||||
await createDocument(context, type.mime, filename, null, content)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const registerNewFileMenuEntries = () => {
|
||||
const fileTypes = [
|
||||
{ type: Types.getFileType('document'), displayName: 'New document', iconClass: 'icon-filetype-document' },
|
||||
{ type: Types.getFileType('spreadsheet'), displayName: 'New spreadsheet', iconClass: 'icon-filetype-spreadsheet' },
|
||||
{ type: Types.getFileType('presentation'), displayName: 'New presentation', iconClass: 'icon-filetype-presentation' },
|
||||
{ type: Types.getFileType('drawing'), displayName: 'New drawing', iconClass: 'icon-filetype-draw' },
|
||||
]
|
||||
|
||||
fileTypes.forEach(({ type, displayName, iconClass }, index) => {
|
||||
addNewFileMenuEntry(createFileTypeEntry(type, displayName, iconClass, index))
|
||||
})
|
||||
}
|
||||
|
||||
const createDocument = async (context, mimetype, filename, templateId = null, content = []) => {
|
||||
if (!isFilenameValid(filename)) {
|
||||
return
|
||||
}
|
||||
|
||||
filename = getUniqueName(
|
||||
filename,
|
||||
content.map((n) => n.basename),
|
||||
)
|
||||
|
||||
try {
|
||||
const response = await createEmptyFile(context, mimetype, filename, templateId)
|
||||
const { data } = response
|
||||
|
||||
const file = new File({
|
||||
source: context.source + '/' + filename,
|
||||
basename: filename,
|
||||
id: data.id,
|
||||
mtime: new Date(data.mtime),
|
||||
mime: data.mimetype,
|
||||
owner: null,
|
||||
permissions: data.permissions,
|
||||
root: context?.root,
|
||||
})
|
||||
emit('files:node:created', file)
|
||||
|
||||
if (response && response.status === 'success') {
|
||||
OCA.Viewer.open({ path: context.dirname + '/' + filename })
|
||||
} else {
|
||||
showError(t('core', 'Could not create file') + ': ' + response.data.message)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
showError(t('core', 'Could not create file'))
|
||||
}
|
||||
}
|
||||
|
||||
const openTemplatePicker = async (context, type, mimetype, filename, content = []) => {
|
||||
try {
|
||||
const { data: response } = await axios.get(generateOcsUrl(`apps/richdocuments/api/v1/templates/${type}`, 2))
|
||||
const templates = response.ocs.data
|
||||
|
||||
if (templates.length === 1) {
|
||||
await createDocument(context, mimetype, filename, templates[0].id, content)
|
||||
return
|
||||
}
|
||||
|
||||
await spawnDialog(TemplatePicker, {
|
||||
templates,
|
||||
suggestedFilename: filename,
|
||||
content,
|
||||
initialTemplateId: templates[0]?.id,
|
||||
}, (templateId, filename) => {
|
||||
if (templateId) {
|
||||
createDocument(context, mimetype, filename, templateId, content)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
showError(t('core', 'Could not load templates'))
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +114,7 @@ class RegisterTemplateFileCreatorListenerTest extends TestCase {
|
|||
public function testHandleDoesNotRegisterIfUserCannotEdit() {
|
||||
$event = $this->createMock(RegisterTemplateCreatorEvent::class);
|
||||
$event->method('getTemplateManager')->willReturn($this->templateManager);
|
||||
$this->permissionManager->method('loggedInUser')->willReturn('user');
|
||||
$this->permissionManager->method('isEnabledForUser')->willReturn(true);
|
||||
$this->permissionManager->method('userCanEdit')->willReturn(false);
|
||||
$this->capabilitiesService->method('getCapabilities')->willReturn(['something']);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue