Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement file extensions toggle #6793

Merged
merged 7 commits into from
Apr 21, 2022
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
12 changes: 12 additions & 0 deletions changelog/unreleased/enhancement-add-show-file-extension-switch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Enhancement: Add show file extension toggle switch in file list settings

We've added a toggle switch to the file list settings to turn off and on displaying file extension.

If this setting is turned off, the file extension won't be shown anymore in:
* The name column displayed in the files list
* The right sidebar
* The rename modal
* The new file modal

https://github.com/owncloud/web/pull/6793
https://github.com/owncloud/web/issues/6730
12 changes: 10 additions & 2 deletions packages/web-app-files/src/components/AppBar/AppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default {
},
computed: {
...mapGetters('Files', ['files', 'selectedFiles']),
...mapState('Files', ['areHiddenFilesShown']),
...mapState('Files', ['areHiddenFilesShown', 'areFileExtensionsShown']),

pageTitle() {
const title = this.$route.meta.title
Expand Down Expand Up @@ -116,10 +116,18 @@ export default {
if (areHiddenFilesShownBoolean !== this.areHiddenFilesShown) {
this.SET_HIDDEN_FILES_VISIBILITY(areHiddenFilesShownBoolean)
}

// Storage returns a string so we need to convert it into a boolean
const areFileExtensionsShown = window.localStorage.getItem('oc_fileExtensionsShown') || 'true'
const areFileExtensionsShownBoolean = areFileExtensionsShown === 'true'

if (areFileExtensionsShownBoolean !== this.areFileExtensionsShown) {
this.SET_FILE_EXTENSIONS_VISIBILITY(areFileExtensionsShownBoolean)
}
},

methods: {
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY'])
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY', 'SET_FILE_EXTENSIONS_VISIBILITY'])
}
}
</script>
Expand Down
20 changes: 15 additions & 5 deletions packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
</template>

<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
import pathUtil from 'path'

import Mixins from '../../mixins'
Expand Down Expand Up @@ -165,6 +165,7 @@ export default {
computed: {
...mapGetters(['getToken', 'capabilities', 'configuration', 'newFileHandlers', 'user']),
...mapGetters('Files', ['files', 'currentFolder', 'publicLinkPassword']),
...mapState('Files', ['areFileExtensionsShown']),

mimetypesAllowedForCreation() {
// we can't use `mapGetters` here because the External app doesn't exist in all deployments
Expand Down Expand Up @@ -334,10 +335,12 @@ export default {
) {
const defaultName = isFolder
? this.$gettext('New folder')
: this.$gettext('New file') + '.' + ext
: this.$gettext('New file') + (this.areFileExtensionsShown ? `.${ext}` : '')
const checkInputValue = (value) => {
this.setModalInputErrorMessage(
isFolder ? this.checkNewFolderName(value) : this.checkNewFileName(value)
isFolder
? this.checkNewFolderName(value)
: this.checkNewFileName(this.areFileExtensionsShown ? value : `${value}.${ext}`)
)
}

Expand All @@ -356,13 +359,20 @@ export default {
inputLabel: isFolder ? this.$gettext('Folder name') : this.$gettext('File name'),
inputError: isFolder
? this.checkNewFolderName(defaultName)
: this.checkNewFileName(defaultName),
: this.checkNewFileName(
this.areFileExtensionsShown ? defaultName : `${defaultName}.${ext}`
),
onCancel: this.hideModal,
onConfirm: isFolder
? this.addNewFolder
: addAppProviderFile
? this.addAppProviderFile
: this.addNewFile,
: (fileName) => {
if (!this.areFileExtensionsShown) {
fileName = `${fileName}.${ext}`
}
this.addNewFile(fileName)
},
onInput: checkInputValue
}

Expand Down
20 changes: 18 additions & 2 deletions packages/web-app-files/src/components/AppBar/ViewOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
:label="$gettext('Show hidden files')"
/>
</li>
<li class="files-view-options-list-item">
<oc-switch
v-model="fileExtensionsShownModel"
data-testid="files-switch-files-extensions-files"
:label="$gettext('Show file extensions')"
/>
</li>
<li class="files-view-options-list-item">
<oc-page-size
v-model="itemsPerPage"
Expand Down Expand Up @@ -57,7 +64,7 @@ export default {
}
},
computed: {
...mapState('Files', ['areHiddenFilesShown']),
...mapState('Files', ['areHiddenFilesShown', 'areFileExtensionsShown']),

viewOptionsButtonLabel() {
return this.$gettext('Display customization options of the files list')
Expand All @@ -71,10 +78,19 @@ export default {
set(value) {
this.SET_HIDDEN_FILES_VISIBILITY(value)
}
},
fileExtensionsShownModel: {
get() {
return this.areFileExtensionsShown
},

set(value) {
this.SET_FILE_EXTENSIONS_VISIBILITY(value)
}
}
},
methods: {
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY'])
...mapMutations('Files', ['SET_HIDDEN_FILES_VISIBILITY', 'SET_FILE_EXTENSIONS_VISIBILITY'])
}
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
:is-path-displayed="arePathsDisplayed"
:parent-folder-name-default="defaultParentFolderName"
:is-thumbnail-displayed="areThumbnailsDisplayed"
:is-extension-displayed="areFileExtensionsShown"
:is-resource-clickable="isResourceClickable(item.id)"
:folder-link="folderLink(item)"
:parent-folder-link="parentFolderLink(item)"
Expand Down Expand Up @@ -165,7 +166,7 @@
<script lang="ts">
import { DateTime } from 'luxon'
import maxSize from 'popper-max-size-modifier'
import { mapGetters, mapActions } from 'vuex'
import { mapGetters, mapActions, mapState } from 'vuex'
import { EVENT_TROW_MOUNTED, EVENT_FILE_DROPPED } from '../../constants'
import { SortDir } from '../../composables'
import * as path from 'path'
Expand Down Expand Up @@ -352,6 +353,7 @@ export default defineComponent({
},
computed: {
...mapGetters(['configuration']),
...mapState('Files', ['areFileExtensionsShown']),
popperOptions() {
return {
modifiers: [
Expand Down
4 changes: 3 additions & 1 deletion packages/web-app-files/src/components/SideBar/FileInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:extension="file.extension"
:type="file.type"
:full-path="file.webDavPath"
:is-extension-displayed="areFileExtensionsShown"
:is-path-displayed="false"
/>
</h3>
Expand All @@ -30,7 +31,7 @@
import Mixins from '../../mixins'
import MixinResources from '../../mixins/resources'
import { isLocationSpacesActive, isLocationTrashActive } from '../../router'
import { mapGetters } from 'vuex'
import { mapGetters, mapState } from 'vuex'
import PrivateLinkItem from './PrivateLinkItem.vue'
import { useActiveLocation } from '../../composables'

Expand All @@ -54,6 +55,7 @@ export default {
},
computed: {
...mapGetters(['capabilities', 'user']),
...mapState('Files', ['areFileExtensionsShown']),
timeData() {
const interpolate = (obj) => {
obj.time = this.formDateFromRFC(obj.sourceTime)
Expand Down
33 changes: 28 additions & 5 deletions packages/web-app-files/src/mixins/actions/rename.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mapActions, mapGetters } from 'vuex'
import { mapActions, mapGetters, mapState } from 'vuex'
import { isSameResource, extractNameWithoutExtension } from '../../helpers/resource'
import { getParentPaths } from '../../helpers/path'
import { buildResource } from '../../helpers/resources'
Expand All @@ -8,6 +8,7 @@ export default {
computed: {
...mapGetters('Files', ['files', 'currentFolder']),
...mapGetters(['capabilities']),
...mapState('Files', ['areFileExtensionsShown']),

$_rename_items() {
return [
Expand Down Expand Up @@ -68,27 +69,49 @@ export default {
}

const confirmAction = (newName) => {
if (!this.areFileExtensionsShown) {
newName = `${newName}.${resources[0].extension}`
}

this.$_rename_renameResource(resources[0], newName)
}
const checkName = (newName) => {
if (!this.areFileExtensionsShown) {
newName = `${newName}.${resources[0].extension}`
}
this.$_rename_checkNewName(resources[0].name, newName, parentResources)
}
const nameWithoutExtension = extractNameWithoutExtension(resources[0])
const modalTitle =
!resources[0].isFolder && !this.areFileExtensionsShown
? nameWithoutExtension
: resources[0].name

const title = this.$gettextInterpolate(
resources[0].isFolder
? this.$gettext('Rename folder %{name}')
: this.$gettext('Rename file %{name}'),
{ name: resources[0].name }
{ name: modalTitle }
)
const nameWithoutExtension = extractNameWithoutExtension(resources[0])

const inputValue =
!resources[0].isFolder && !this.areFileExtensionsShown
? nameWithoutExtension
: resources[0].name

const inputSelectionRange =
resources[0].isFolder || !this.areFileExtensionsShown
? null
: [0, nameWithoutExtension.length]

const modal = {
variation: 'passive',
title,
cancelText: this.$gettext('Cancel'),
confirmText: this.$gettext('Rename'),
hasInput: true,
inputValue: resources[0].name,
inputSelectionRange: resources[0].isFolder ? null : [0, nameWithoutExtension.length],
inputValue,
inputSelectionRange,
inputLabel: resources[0].isFolder
? this.$gettext('Folder name')
: this.$gettext('File name'),
Expand Down
6 changes: 6 additions & 0 deletions packages/web-app-files/src/store/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,12 @@ export default {
state.areHiddenFilesShown = value

window.localStorage.setItem('oc_hiddenFilesShown', value)
},

SET_FILE_EXTENSIONS_VISIBILITY(state, value) {
state.areFileExtensionsShown = value

window.localStorage.setItem('oc_fileExtensionsShown', value)
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/web-app-files/src/store/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export default {
/**
* View settings
*/
areHiddenFilesShown: true
areHiddenFilesShown: true,
areFileExtensionsShown: true
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ function createStore(state = { selected: [] }) {
selectedFiles: () => state.selected
},
mutations: {
SET_HIDDEN_FILES_VISIBILITY: jest.fn()
SET_HIDDEN_FILES_VISIBILITY: jest.fn(),
SET_FILE_EXTENSIONS_VISIBILITY: jest.fn()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ describe('ViewOptions', () => {
Files: {
namespaced: true,
mutations: {
SET_HIDDEN_FILES_VISIBILITY: jest.fn()
SET_HIDDEN_FILES_VISIBILITY: jest.fn(),
SET_FILE_EXTENSIONS_VISIBILITY: jest.fn()
},
modules: {
sidebar: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ function getMountedWrapper(options = {}) {
store: createStore(Vuex.Store, {
getters: {
configuration: () => {}
},
modules: {
Files: {
namespaced: true
}
}
}),
propsData: {
Expand Down
9 changes: 9 additions & 0 deletions packages/web-app-files/tests/unit/store/mutations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ describe('vuex store mutations', () => {
expect(state.areHiddenFilesShown).toEqual(false)
})

it('SET_FILE_EXTENSIONS_VISIBILITY', () => {
const state = { areFileExtensionsShown: true }
const { SET_FILE_EXTENSIONS_VISIBILITY } = mutations

SET_FILE_EXTENSIONS_VISIBILITY(state, false)

expect(state.areFileExtensionsShown).toEqual(false)
})

describe('CURRENT_FILE_OUTGOING_SHARES_REMOVE', () => {
it('removes an outgoing user share', () => {
const shareToRemove = { id: 1, shareType: ShareTypes.user.value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports[`SharedWithOthers view when the wrapper is not loading anymore when leng
</td>
<td class="oc-td oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-expand oc-text-truncate oc-table-data-cell oc-table-data-cell-name">
<div class="resource-table-resource-wrapper">
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isextensiondisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-button-stub type="button" size="medium" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" class="resource-table-edit-name"><span class="oc-icon oc-icon-s oc-icon-passive"><!----></span></oc-button-stub>
</div>
</td>
Expand All @@ -51,7 +51,7 @@ exports[`SharedWithOthers view when the wrapper is not loading anymore when leng
</td>
<td class="oc-td oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-expand oc-text-truncate oc-table-data-cell oc-table-data-cell-name">
<div class="resource-table-resource-wrapper">
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isextensiondisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-button-stub type="button" size="medium" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" class="resource-table-edit-name"><span class="oc-icon oc-icon-s oc-icon-passive"><!----></span></oc-button-stub>
</div>
</td>
Expand All @@ -74,7 +74,7 @@ exports[`SharedWithOthers view when the wrapper is not loading anymore when leng
</td>
<td class="oc-td oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-expand oc-text-truncate oc-table-data-cell oc-table-data-cell-name">
<div class="resource-table-resource-wrapper">
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isextensiondisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-button-stub type="button" size="medium" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" class="resource-table-edit-name"><span class="oc-icon oc-icon-s oc-icon-passive"><!----></span></oc-button-stub>
</div>
</td>
Expand All @@ -97,7 +97,7 @@ exports[`SharedWithOthers view when the wrapper is not loading anymore when leng
</td>
<td class="oc-td oc-table-cell oc-table-cell-align-left oc-table-cell-align-middle oc-table-cell-width-expand oc-text-truncate oc-table-data-cell oc-table-data-cell-name">
<div class="resource-table-resource-wrapper">
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-resource-stub folderlink="[object Object]" parentfolderlink="[object Object]" resource="[object Object]" parentfoldernamedefault="All files and folders" ispathdisplayed="true" isextensiondisplayed="true" isresourceclickable="true"></oc-resource-stub>
<oc-button-stub type="button" size="medium" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" class="resource-table-edit-name"><span class="oc-icon oc-icon-s oc-icon-passive"><!----></span></oc-button-stub>
</div>
</td>
Expand Down
1 change: 1 addition & 0 deletions packages/web-app-files/tests/unit/views/views.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export const getStore = function ({
state.activeFiles.push(resource)
},
SET_HIDDEN_FILES_VISIBILITY: jest.fn(),
SET_FILE_EXTENSIONS_VISIBILITY: jest.fn(),
CLEAR_FILES_SEARCHED: () => {},
CLEAR_CURRENT_FILES_LIST: () => {},
LOAD_FILES: () => {},
Expand Down
2 changes: 1 addition & 1 deletion packages/web-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"luxon": "^2.3.0",
"marked": "^4.0.12",
"oidc-client": "1.11.5",
"owncloud-design-system": "^13.1.0-rc.3",
"owncloud-design-system": "^13.1.0-rc.5",
"owncloud-sdk": "~3.0.0-alpha.4",
"p-queue": "^6.1.1",
"popper-max-size-modifier": "^0.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exports[`ApplicationsMenu component should render navigation with button and men
</oc-button-stub>
</li>
<li>
<oc-button-stub type="a" size="medium" href="http://some.org" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" target="_blank" class=""><span class="icon-box"><oc-icon-stub name="some-icon" filltype="fill" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub></span> <span>External</span>
<oc-button-stub type="a" size="medium" href="http://some.org" target="_blank" submit="button" variation="passive" appearance="raw" justifycontent="center" gapsize="medium" class=""><span class="icon-box"><oc-icon-stub name="some-icon" filltype="fill" accessiblelabel="" type="span" size="medium" variation="passive" color=""></oc-icon-stub></span> <span>External</span>
<!---->
</oc-button-stub>
</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FeedbackLink component has no accessibility violations 1`] = `
<div class="oc-flex"><a aria-label="ownCloud feedback survey" href="https://owncloud.com/web-design-feedback" class="oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw" target="_blank" aria-describedby="oc-feedback-link-description"><span class="oc-icon oc-icon-m oc-icon-passive"><!----></span></a>
<div class="oc-flex"><a aria-label="ownCloud feedback survey" href="https://owncloud.com/web-design-feedback" target="_blank" class="oc-button oc-rounded oc-button-m oc-button-justify-content-center oc-button-gap-m oc-button-inverse oc-button-inverse-raw" aria-describedby="oc-feedback-link-description"><span class="oc-icon oc-icon-m oc-icon-passive"><!----></span></a>
<p id="oc-feedback-link-description" class="oc-invisible-sr">Provide your feedback: We'd like to improve the web design and would be happy to hear your feedback. Thank you! Your ownCloud team.</p>
</div>
`;
Loading