forked from Ivasoft/geovisio-website
Merge branch 'feat-add-sort-file' into 'develop'
Feat add sorting for file upload See merge request geovisio/website!79
This commit is contained in:
15
CHANGELOG.md
15
CHANGELOG.md
@@ -4,12 +4,24 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
Before _0.1.0_ Changelog didn't exist.
|
||||
|
||||
## [2.1.0] - 2023-08-29
|
||||
|
||||
### Added
|
||||
|
||||
- A new page `/telecharger` to upload picture with an interface ([#13](https://gitlab.com/geovisio/website/-/issues/13)) :
|
||||
- the user can upload multiples pictures with the interface
|
||||
- the pictures are sorted by name
|
||||
- the user can see all the pictures uploaded and all the errors
|
||||
|
||||
### Fixed
|
||||
|
||||
- fix a bug in the header hidden sub menu when authentication is not with keycloak
|
||||
|
||||
## [0.1.0] -
|
||||
|
||||
### Added
|
||||
|
||||
- A new page `/mes-sequences` to access to a list of sequences for a logged user ([#14](https://gitlab.com/geovisio/website/-/issues/14)) :
|
||||
|
||||
- the user can see all his sequences
|
||||
- the user can filter sequences
|
||||
- the user can enter to a specific sequence
|
||||
@@ -20,7 +32,6 @@ Before _0.1.0_ Changelog didn't exist.
|
||||
- the user can see all the sequence's photos
|
||||
- the user can disable and delete one or many photo(s) of the sequence
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- Header have now a new entry `Mes photos` when the user is logged to access to the sequence list
|
||||
|
||||
24
docs/90_Releases.md
Normal file
24
docs/90_Releases.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Make a release
|
||||
|
||||
The web site uses [semantic versioning](https://semver.org/) for its release numbers.
|
||||
|
||||
__Note__ : make sure that versions are in-sync with other Website components. Each component can have different `PATCH` versions, but compatibility __must__ be ensured between `MAJOR.MINOR` versions.
|
||||
|
||||
Run these commands in order to issue a new release:
|
||||
|
||||
```bash
|
||||
git checkout develop
|
||||
|
||||
vim package.json # Change version
|
||||
npm run doc
|
||||
|
||||
vim CHANGELOG.md # Replace unreleased to version number
|
||||
|
||||
git add *
|
||||
git commit -m "Release x.x.x"
|
||||
git tag -a x.x.x -m "Release x.x.x"
|
||||
git push origin develop
|
||||
git checkout main
|
||||
git merge develop
|
||||
git push origin main --tags
|
||||
```
|
||||
@@ -68,9 +68,7 @@ function drop(event: DragEvent): void | boolean {
|
||||
}
|
||||
|
||||
function checkPicturesType(files: FileList): number {
|
||||
const picturesToUpload = [...files]
|
||||
.filter((p) => p.type == 'image/jpeg')
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
const picturesToUpload = [...files].filter((p) => p.type == 'image/jpeg')
|
||||
return picturesToUpload.length
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -38,7 +38,7 @@ const itemUploadedText = computed<string | null>(
|
||||
}
|
||||
.success {
|
||||
background-color: var(--white);
|
||||
border: toRem(1) solid var(--grey);
|
||||
border: toRem(0.1) solid var(--grey);
|
||||
color: var(--black);
|
||||
}
|
||||
.error {
|
||||
|
||||
@@ -6,6 +6,7 @@ const i18n = createI18n({
|
||||
fallbackLocale: 'fr',
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
warnHtmlMessage: false,
|
||||
messages: {
|
||||
fr
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
} from '../../views/utils/sequence/index'
|
||||
import {
|
||||
formatPictureSize,
|
||||
formatTextSize
|
||||
formatTextSize,
|
||||
sortByName
|
||||
} from '../../views/utils/upload/index'
|
||||
import { getAuthRoute } from '../../utils/auth'
|
||||
import { img, getPicId } from '../../utils/image'
|
||||
@@ -181,3 +182,36 @@ describe('title', () => {
|
||||
expect(title(myTitle)).toEqual('my title')
|
||||
})
|
||||
})
|
||||
|
||||
describe('sortByName', () => {
|
||||
it('should return the the list sorted by name', () => {
|
||||
const list1 = [
|
||||
{ name: 'd_1_ct.jpg' },
|
||||
{ name: 'd_11_ct.jpg' },
|
||||
{ name: 'd_2_ct.jpg' }
|
||||
]
|
||||
expect(sortByName(list1)).toEqual([
|
||||
{ name: 'd_1_ct.jpg' },
|
||||
{ name: 'd_2_ct.jpg' },
|
||||
{ name: 'd_11_ct.jpg' }
|
||||
])
|
||||
|
||||
const list2 = [{ name: 'A.jpg' }, { name: 'Z.jpg' }, { name: 'B.jpg' }]
|
||||
expect(sortByName(list2)).toEqual([
|
||||
{ name: 'A.jpg' },
|
||||
{ name: 'B.jpg' },
|
||||
{ name: 'Z.jpg' }
|
||||
])
|
||||
|
||||
const list3 = [
|
||||
{ name: 'CAM1_001.jpg' },
|
||||
{ name: 'CAM2_002.jpg' },
|
||||
{ name: 'CAM1_011.jpg' }
|
||||
]
|
||||
expect(sortByName(list3)).toEqual([
|
||||
{ name: 'CAM1_001.jpg' },
|
||||
{ name: 'CAM1_011.jpg' },
|
||||
{ name: 'CAM2_002.jpg' }
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import SharePicturesView from '../../../views/SharePicturesView.vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import fr from '../../../locales/fr.json'
|
||||
import i18n from '../config'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
fallbackLocale: 'fr',
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
messages: {
|
||||
fr
|
||||
}
|
||||
})
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: []
|
||||
|
||||
@@ -7,6 +7,7 @@ import InputUpload from '../../../components/InputUpload.vue'
|
||||
import * as createAPictureToASequence from '@/views/utils/upload/request'
|
||||
import * as createASequence from '@/views/utils/upload/request'
|
||||
import { formatDate } from '../../../utils/dates'
|
||||
import * as sortByName from '../../../views/utils/upload/index'
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: []
|
||||
@@ -41,10 +42,11 @@ describe('Template', () => {
|
||||
}
|
||||
})
|
||||
const spy = vi.spyOn(wrapper.vm, 'addPictures')
|
||||
const wrapperInputUpload = wrapper.findComponent(InputUpload)
|
||||
const sortByNameMock = vi.spyOn(sortByName, 'sortByName')
|
||||
sortByNameMock.mockReturnValue([{}, {}])
|
||||
const wrapperInputUpload = await wrapper.findComponent(InputUpload)
|
||||
await wrapperInputUpload.trigger('trigger')
|
||||
await wrapperInputUpload.vm.$emit('trigger', [{}, {}])
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
expect(wrapper.html()).contains('2 fichiers')
|
||||
})
|
||||
@@ -83,11 +85,19 @@ describe('Template', () => {
|
||||
}
|
||||
}
|
||||
})
|
||||
const picture = {
|
||||
lastModified: 1599133968750,
|
||||
name: '100MSDCF_DSC02790.JPG',
|
||||
size: 2345,
|
||||
type: 'image/jpeg'
|
||||
}
|
||||
const spyASequence = vi.spyOn(createASequence, 'createASequence')
|
||||
const spyPicture = vi.spyOn(
|
||||
createAPictureToASequence,
|
||||
'createAPictureToASequence'
|
||||
)
|
||||
const sortByNameMock = vi.spyOn(sortByName, 'sortByName')
|
||||
sortByNameMock.mockReturnValue([picture])
|
||||
const sequenceId = 'my-id'
|
||||
spyASequence.mockReturnValue({ data: { id: sequenceId } })
|
||||
spyPicture.mockReturnValue({ data: {} })
|
||||
@@ -95,12 +105,6 @@ describe('Template', () => {
|
||||
new Date(),
|
||||
'Do MMMM YY, hh:mm:ss'
|
||||
)}`
|
||||
const picture = {
|
||||
lastModified: 1599133968750,
|
||||
name: '100MSDCF_DSC02790.JPG',
|
||||
size: 2345,
|
||||
type: 'image/jpeg'
|
||||
}
|
||||
const body = new FormData()
|
||||
body.append('position', '1')
|
||||
body.append('picture', picture)
|
||||
@@ -112,6 +116,7 @@ describe('Template', () => {
|
||||
|
||||
expect(spyASequence).toHaveBeenCalledWith(sequenceTitle)
|
||||
expect(spyPicture).toHaveBeenCalledWith(sequenceId, body)
|
||||
|
||||
expect(wrapper.html()).contains('class="uploaded-picture-list"')
|
||||
expect(wrapper.html()).contains('class="uploaded-picture-item success"')
|
||||
expect(wrapper.html()).contains(
|
||||
|
||||
@@ -62,9 +62,13 @@ import {
|
||||
createAPictureToASequence,
|
||||
createASequence
|
||||
} from '@/views/utils/upload/request'
|
||||
import { formatPictureSize, formatTextSize } from '@/views/utils/upload/index'
|
||||
import {
|
||||
formatPictureSize,
|
||||
formatTextSize,
|
||||
sortByName
|
||||
} from '@/views/utils/upload/index'
|
||||
const { t } = useI18n()
|
||||
let pictures = ref<FileList | []>([])
|
||||
let pictures = ref<File[] | []>([])
|
||||
let picturesCount = ref<number>(0)
|
||||
let isLoading = ref<boolean>(false)
|
||||
let isLoaded = ref<boolean>(false)
|
||||
@@ -124,7 +128,8 @@ function triggerNewUpload(): void {
|
||||
picturesCount.value = 0
|
||||
}
|
||||
function addPictures(value: FileList): void {
|
||||
pictures.value = value
|
||||
const files = sortByName([].slice.call(value))
|
||||
pictures.value = files
|
||||
picturesCount.value = pictures.value.length
|
||||
picturesUploadingSize.value = 0
|
||||
picturesToUploadSize.value = 0
|
||||
|
||||
@@ -5,4 +5,12 @@ function formatTextSize(size: number, i: number): string {
|
||||
const sizes = ['0', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'o']
|
||||
return `${parseFloat((size / Math.pow(1024, i)).toFixed(2))} ${sizes[i]}`
|
||||
}
|
||||
export { formatPictureSize, formatTextSize }
|
||||
function sortByName(fileList: File[]): File[] {
|
||||
return fileList.sort((a: File, b: File) =>
|
||||
a.name.localeCompare(b.name, navigator.languages[0] || navigator.language, {
|
||||
numeric: true,
|
||||
ignorePunctuation: true
|
||||
})
|
||||
)
|
||||
}
|
||||
export { formatPictureSize, formatTextSize, sortByName }
|
||||
|
||||
Reference in New Issue
Block a user