10 Commits

Author SHA1 Message Date
Jean Andreani
cec383e424 Merge branch 'feat/link-to-sequence-from-viewer' into 'develop'
feat: add button to viewer to link to seuqence + refacto

Closes #48

See merge request geovisio/website!114
2023-12-19 12:53:06 +00:00
Jean Andreani
7e20788591 feat: add button to viewer to link to seuqence + refacto 2023-12-19 12:53:06 +00:00
Jean Andreani
390343916e Merge branch 'tech/add-more-test-e2e' into 'develop'
add e2e for upload test

See merge request geovisio/website!113
2023-12-18 10:27:31 +00:00
Jean Andreani
c768b714b9 add e2e for upload test 2023-12-18 10:27:31 +00:00
Jean Andreani
bf0bc4d91c Merge branch 'tech/perf-hover-sequence-list' into 'develop'
Tech/perf hover sequence list

See merge request geovisio/website!110
2023-12-12 15:55:46 +00:00
Jean Andreani
5d292b186c Tech/perf hover sequence list 2023-12-12 15:55:46 +00:00
Jean Andreani
93e434ecf9 Merge branch 'fix-e2e' into 'develop'
fix duration gitlab for e2e

See merge request geovisio/website!112
2023-12-12 15:43:21 +00:00
Jean Andreani
721bafbd3e fix duration gitlab for e2e 2023-12-12 15:43:21 +00:00
Jean Andreani
127550a19f Merge branch 'tech-add-test-e2e' into 'develop'
Tech add test e2e

See merge request geovisio/website!89
2023-12-12 15:01:50 +00:00
Jean Andreani
85abc46038 Tech add test e2e 2023-12-12 15:01:50 +00:00
17 changed files with 316 additions and 164 deletions

View File

@@ -20,6 +20,10 @@ describe('In the contribute page', () => {
})
interface contributeInterface {
textButtonContribute: string
textButtonDocPython: string
textButtonCli: string
textButtonDocCli: string
textButtonTiles: string
textButtonDoc: string
}
export {}

32
cypress/e2e/upload.cy.ts Normal file
View File

@@ -0,0 +1,32 @@
describe('In the login page', () => {
it('login and go to the upload page to upload images', () => {
cy.visit(`${Cypress.env('api_url')}api/auth/login`)
cy.get('#username').type('Elysee')
cy.get('#password').type('my password')
cy.fixture('upload').then((uploadData: uploadInterface) => {
cy.contains(uploadData.textLinkLogin).click()
cy.visit('/envoyer')
cy.get('.edit-button').click()
cy.get('#upload-title').clear()
cy.get('#upload-title').type(uploadData.textTitle)
cy.contains(uploadData.textButtonTitle).click()
cy.contains(uploadData.textButtonUpload).click()
})
cy.get('.input-file').selectFile(
[
'/src/cypress/fixtures/images/image1.jpg',
'/src/cypress/fixtures/images/image2.jpg',
'/src/cypress/fixtures/images/image3.jpg'
],
{ force: true }
)
})
})
interface uploadInterface {
textLinkLogin: string
textLinkUpload: string
textButtonUpload: string
textTitle: string
textButtonTitle: string
}
export {}

View File

@@ -0,0 +1,7 @@
{
"textLinkLogin": "Sign In",
"textLinkUpload": "Mes photos",
"textTitle": "My title",
"textButtonTitle": "Valider",
"textButtonUpload": "Glissez vos images ici ou cliquez sur"
}

View File

@@ -1,3 +1,8 @@
export function createLink(href: string, text: string): string {
return `<a href='mailto:signalement.ign@panoramax.fr${href}' target='_blank' title='${text}' class='gvs-btn gvs-widget-bg gvs-btn-large' style='font-size: 1.6em;display: block'><i class="bi bi-exclamation-triangle"></i></a>`
}
export function createSequenceLink(href: string, title: string): string {
return `<a href='${href}' title='${title}' class='gvs-btn gvs-widget-bg gvs-btn-large' style='font-size: 1.6em;display: block; position: relative'>
<i class="bi bi-images"></i>
</a>`
}

View File

@@ -7,6 +7,7 @@
>
<div class="wrapper-input">
<Input
id="upload-title"
:text="text || ''"
:placeholder="$t('pages.upload.edit_placeholder_input')"
@input="changeTextValue"

View File

@@ -128,7 +128,6 @@ onClickOutside(list, () => closeModal())
function closeModal(): void {
menuIsClosed.value = true
}
function toggleMenu(): void {
menuIsClosed.value = !menuIsClosed.value
}

View File

@@ -3,13 +3,18 @@
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import type { ViewerInterface, MapInterface } from '@/views/interfaces/common'
import { getIgnTiles } from '@/utils/mapAndViewer'
import axios from 'axios'
import { onMounted, onUnmounted, ref, computed } from 'vue'
import { useSequenceStore } from '@/store/sequence'
import { Viewer, StandaloneMap } from 'geovisio'
import { getIgnTiles } from '@/utils/mapAndViewer'
import { createUrlLink } from '@/utils'
import { createLink } from '@/components-viewer/reportLink'
import { createLink, createSequenceLink } from '@/components-viewer/reportLink'
import { useI18n } from 'vue-i18n'
import { hasASessionCookieDecoded } from '@/utils/auth'
import type { ViewerInterface, MapInterface } from '@/views/interfaces/common'
const sequenceStore = useSequenceStore()
const { t } = useI18n()
let mapIsLoaded = ref<boolean>(false)
let viewer = ref()
@@ -20,119 +25,152 @@ const props = defineProps({
bbox: { type: Array, default: null },
userId: { type: String, default: '' }
})
const isLogged = computed((): boolean => {
const cookie = hasASessionCookieDecoded()
return !!(cookie && cookie.account)
})
const userName = computed((): string => {
const cookie = hasASessionCookieDecoded()
if (cookie && cookie.account) return cookie.account.name
return ''
})
defineExpose({
viewer
})
onMounted(async () => {
const tiles = import.meta.env.VITE_TILES
async function getSequenceId(imgId: string): Promise<{
sequenceId: string
username: string
}> {
const { data } = await axios.get(`api/search?ids=${imgId}`)
return {
sequenceId: data.features[0].collection,
username: data.features[0].properties['geovisio:producer']
}
}
function createViewerButton(link: HTMLDivElement): void {
viewer.value.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
const sequenceInformation = await getSequenceId(e.detail.picId)
let href: string
if (isLogged.value && sequenceInformation.username === userName.value) {
href = `${window.location.origin}/sequence/${sequenceInformation.sequenceId}?currentPic=${e.detail.picId}`
link.innerHTML = createSequenceLink(
href,
t('pages.home.sequence_title')
)
sequenceStore.addSequence(e.detail.picId)
} else {
href = t('pages.home.report_mail', {
picId: e.detail.picId,
link: createUrlLink(e.detail.picId)
})
link.innerHTML = createLink(href, t('pages.home.report_button_text'))
}
}
)
}
async function setupViewerMap(tiles: string): Promise<void> {
const maxZoom = import.meta.env.VITE_MAX_ZOOM
const zoom = import.meta.env.VITE_ZOOM
const center = import.meta.env.VITE_CENTER
let paramsViewer: ViewerInterface
let paramsMap: MapInterface
try {
if (props.geovisioViewer) {
paramsViewer = { map: { startWide: true } }
if (center && center !== '') {
const centerMap = center.split(',').map((el: string) => parseInt(el))
paramsViewer = {
map: {
...paramsViewer.map,
center: centerMap
}
}
let paramsViewer: ViewerInterface = { map: { startWide: true } }
if (center && center !== '') {
const centerMap = center.split(',').map((el: string) => parseInt(el))
paramsViewer = {
map: {
...paramsViewer.map,
center: centerMap
}
if (zoom && zoom !== '') {
paramsViewer = {
map: {
...paramsViewer.map,
zoom: parseFloat(zoom)
}
}
}
if (maxZoom && maxZoom !== '') {
paramsViewer = {
map: {
...paramsViewer.map,
maxZoom: parseInt(maxZoom)
}
}
}
if (tiles) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsViewer = {
map: {
...paramsViewer.map,
style
}
}
}
if (props.fetchOptions) {
paramsViewer = {
...paramsViewer,
...props.fetchOptions
}
}
const reportLink = document.createElement('div')
reportLink.className = 'gvs-group gvs-group-large gvs-group-btnpanel'
viewer.value = new Viewer(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsViewer,
widgets: { customWidget: reportLink }
}
)
if (viewer.value && viewer.value.addEventListener) {
viewer.value.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
const href = t('pages.home.report_mail', {
picId: e.detail.picId,
link: createUrlLink(e.detail.picId)
})
reportLink.innerHTML = createLink(
href,
t('pages.home.report_button_text')
)
}
)
}
} else {
paramsMap = { minZoom: 7 }
if (tiles) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsMap = {
...paramsMap,
style
}
}
const bbox = [props.bbox[0], props.bbox[1], props.bbox[2], props.bbox[3]]
viewer.value = new StandaloneMap(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsMap,
bounds: bbox,
zoom: 14
}
)
viewer.value.addEventListener('ready', () => {
viewer.value.setFilters({ user: props.userId }, true)
viewer.value.fitBounds(bbox, {
padding: { top: 70, bottom: 70, left: 70, right: 70 },
maxZoom: 14,
speed: 10
})
})
}
mapIsLoaded.value = true
}
if (zoom && zoom.length) {
paramsViewer = {
map: {
...paramsViewer.map,
zoom: parseFloat(zoom)
}
}
}
if (maxZoom && maxZoom.length) {
paramsViewer = {
map: {
...paramsViewer.map,
maxZoom: parseInt(maxZoom)
}
}
}
if (tiles && tiles.length) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsViewer = {
map: {
...paramsViewer.map,
style
}
}
}
if (props.fetchOptions) {
paramsViewer = {
...paramsViewer,
...props.fetchOptions
}
}
const reportLink = document.createElement('div')
reportLink.className = 'gvs-group gvs-group-large gvs-group-btnpanel'
viewer.value = new Viewer(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsViewer,
widgets: { customWidget: reportLink }
}
)
if (viewer.value && viewer.value.addEventListener) {
createViewerButton(reportLink)
}
mapIsLoaded.value = true
}
async function setupMap(tiles: string): Promise<void> {
let paramsMap: MapInterface
paramsMap = { minZoom: 7 }
if (tiles && tiles.length) {
const style = tiles.includes('wxs.ign.fr') ? await getIgnTiles() : tiles
paramsMap = {
...paramsMap,
style
}
}
const bbox = [props.bbox[0], props.bbox[1], props.bbox[2], props.bbox[3]]
viewer.value = new StandaloneMap(
'viewer', // Div ID
`${import.meta.env.VITE_API_URL}/api/search`,
{
...paramsMap,
bounds: bbox,
zoom: 14
}
)
viewer.value.addEventListener('ready', () => {
viewer.value.setFilters({ user: props.userId }, true)
viewer.value.fitBounds(bbox, {
padding: { top: 70, bottom: 70, left: 70, right: 70 },
maxZoom: 14,
speed: 10
})
})
mapIsLoaded.value = true
}
onMounted(async (): Promise<void> => {
const tiles = import.meta.env.VITE_TILES
try {
if (props.geovisioViewer) return await setupViewerMap(tiles)
return await setupMap(tiles)
} catch (err) {
mapIsLoaded.value = true
console.log(err)
}
})
onUnmounted(() => {
onUnmounted((): void => {
if (viewer.value && props.geovisioViewer) viewer.value.destroy()
})
</script>

View File

@@ -37,7 +37,8 @@
"pages": {
"home": {
"report_mail": "?subject=⚠️ Report on picture {picId}&body=HEllo, %0D%0A%0D%0A Problem on image (keep type of problem reported) : %0D%0A%0D%0A %0D%0A%0D%0A inappropriate content / lack of blurring on an element to be anonymized or blurred for security reasons / overblurring (too much blurring) %0D%0A%0D%0A Link to affected photo : {link} %0D%0A%0D%0A Details of affected elements (especially for blurring problems - what should be blurred or unblurred?) :",
"report_button_text": "Report this picture"
"report_button_text": "Report this picture",
"sequence_title": "See the séquence"
},
"settings": {
"title": "My tokens",

View File

@@ -37,7 +37,8 @@
"pages": {
"home": {
"report_mail": "?subject=⚠️ Signalement sur l`image {picId}&body=Bonjour, %0D%0A%0D%0A Problème sur l`image (garder le type de problème signalé) : %0D%0A%0D%0A contenu inapproprié / absence de floutage sur un élément à anonymiser ou flouter pour des raisons de sécurité /surfloutage (floutage en trop) %0D%0A%0D%0A Lien vers la photo concernée : {link} %0D%0A%0D%0A Précision sur les éléments concernés (en particulier pour les problèmes de floutage - que faut-il flouter ou déflouter?) :",
"report_button_text": "Signaler la photo"
"report_button_text": "Signaler la photo",
"sequence_title": "Voir la séquence"
},
"settings": {
"title": "Mes Tokens",

View File

@@ -37,7 +37,8 @@
"pages": {
"home": {
"report_mail": "?subject=⚠️ Report on picture {picId}&body=Hello, %0D%0A%0D%0A Problem on image (keep type of problem reported) : %0D%0A%0D%0A %0D%0A%0D%0A inappropriate content / lack of blurring on an element to be anonymized or blurred for security reasons / overblurring (too much blurring) %0D%0A%0D%0A Link to affected photo : {link} %0D%0A%0D%0A Details of affected elements (especially for blurring problems - what should be blurred or unblurred?) :",
"report_button_text": "Fénykép jelentése"
"report_button_text": "Fénykép jelentése",
"sequence_title": "lásd a sorrendet"
},
"settings": {
"title": "Saját tokenek",

View File

@@ -3,7 +3,8 @@ import { defineStore } from 'pinia'
export const useSequenceStore = defineStore('sequence', {
state: () => ({
toastText: <string>'',
toastLook: <string>''
toastLook: <string>'',
picId: <string>''
}),
actions: {
addToastText(text: string, look: string): void {
@@ -12,6 +13,9 @@ export const useSequenceStore = defineStore('sequence', {
setTimeout(() => {
this.toastText = ''
}, 3000)
},
addSequence(id: string): void {
this.picId = id
}
}
})

View File

@@ -7,7 +7,7 @@ async function getIgnTiles(): Promise<object> {
data.sources.plan_ign.scheme = 'xyz'
data.sources.plan_ign.attribution = 'Données cartographiques : © IGN'
const objIndex = data.layers.findIndex(
(el: any) => el.id === 'toponyme - parcellaire - adresse'
(el: { id: string }) => el.id === 'toponyme - parcellaire - adresse'
)
data.layers[objIndex].layout = {
...data.layers[objIndex].layout,

View File

@@ -245,7 +245,7 @@ let isLoading = ref<boolean>(false)
const collapseMenu = ref<HTMLDivElement>()
const deleteAll = ref<HTMLDivElement>()
const menuHeight = ref<string>()
const viewerRef = ref()
const viewerRef = ref<InstanceType<typeof Viewer>>()
onMounted(async () => {
try {
@@ -266,37 +266,54 @@ onMounted(async () => {
)
pictures.value = collectionItems
setHeightValue()
if (itemSelected.value.length || !collectionItemsReady[0]) return
if (
itemSelected.value.length ||
!getCurrentPicId(collectionItemsReady[0].id)
) {
return
}
if (!viewerRef.value) return
viewerRef.value.viewer._api.onceReady().then(() => {
if (!viewerRef.value) return
viewerRef.value.viewer.goToPicture(
collectionItemsReady[0].id,
getCurrentPicId(collectionItemsReady[0].id),
sequence.value?.id
)
})
itemSelected.value = collectionItemsReady[0].id
scrollIntoSelected(collectionItemsReady[0].id, pictures.value)
itemSelected.value = getCurrentPicId(collectionItemsReady[0].id)
if (!pictureExistInList(getCurrentPicId(collectionItemsReady[0].id))) {
await goToTheGoodPage(getCurrentPicId(collectionItemsReady[0].id))
}
scrollIntoSelected(
itemSelected.value,
pictures.value.map((e) => e.id)
)
} catch (err) {
console.log(err)
}
})
watchEffect(async () => {
if (!viewerExist(viewerRef)) return
if (!viewerRef || !viewerRef.value || !viewerRef.value.viewer) return
viewerRef.value.viewer.addEventListener(
'picture-loaded',
async (e: { detail: { picId: string } }): Promise<void> => {
if (itemSelected.value === e.detail.picId) return
if (!pictureExistInList(e.detail.picId)) {
await goToTheGoodPage(e.detail.picId)
if (!pictureExistInList(getCurrentPicId(e.detail.picId))) {
await goToTheGoodPage(getCurrentPicId(e.detail.picId))
}
itemSelected.value = e.detail.picId
scrollIntoSelected(e.detail.picId, pictures.value)
itemSelected.value = getCurrentPicId(e.detail.picId)
scrollIntoSelected(
getCurrentPicId(e.detail.picId),
pictures.value.map((e) => e.id)
)
}
)
})
function viewerExist(viewerRef: any): boolean {
return !!(viewerRef && viewerRef.value && viewerRef.value.viewer)
function getCurrentPicId(id: string): string {
const parseParams = new URLSearchParams(window.location.search)
const pict = parseParams.get('currentPic')
return pict && pict.length ? pict : id
}
const isSequenceOwner = computed((): boolean => {
@@ -421,7 +438,7 @@ async function patchCollection(): Promise<void> {
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
pictures.value = data.features
}
viewerRef.value.viewer.reloadVectorTiles()
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
isLoading.value = false
}
@@ -435,7 +452,10 @@ async function goToNextPage(value: string): Promise<void> {
selfLink.value = data.links.filter((el) => el.rel === 'self')
paginationLinks.value = formatPaginationItems(data.links)
pictures.value = data.features
scrollIntoSelected(pictures.value[0].id, pictures.value)
scrollIntoSelected(
pictures.value[0].id,
pictures.value.map((e) => e.id)
)
picturesToDelete.value = []
isLoading.value = false
setHeightValue()
@@ -484,16 +504,26 @@ function selectPhotoToDeleteOrPatch(
async function selectImageAndMove(
item: ResponseUserPhotoInterface
): Promise<void> {
const parseParams = new URLSearchParams(window.location.search)
const pict = parseParams.get('currentPic')
if (pict && pict.length) {
await router.push({ name: 'sequence', params: { id: route.params.id } })
}
selectPhotoToDeleteOrPatch(item)
if (
picturesToDelete.value.length < 2 &&
item.properties['geovisio:status'] === 'ready'
) {
const viewerMap = await viewerRef.value.viewer
viewerMap.goToPicture(item.id, sequence.value?.id)
if (viewerRef.value) {
const viewerMap = await viewerRef.value.viewer
viewerMap.goToPicture(item.id, sequence.value?.id)
}
itemSelected.value = item.id
await goToTheGoodPage(item.id)
scrollIntoSelected(item.id, pictures.value)
scrollIntoSelected(
item.id,
pictures.value.map((e) => e.id)
)
}
}
@@ -553,9 +583,14 @@ async function patchOrDeleteCollectionItems(
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
pictures.value = data.features
isLoading.value = false
viewerRef.value.viewer.reloadVectorTiles()
viewerRef.value.viewer.goToPicture(pictures.value[0].id, route.params.id)
scrollIntoSelected(picturesToDelete.value[0], pictures.value)
if (viewerRef.value) {
viewerRef.value.viewer.reloadVectorTiles()
viewerRef.value.viewer.goToPicture(pictures.value[0].id, route.params.id)
}
scrollIntoSelected(
picturesToDelete.value[0],
pictures.value.map((e) => e.id)
)
picturesToDelete.value = []
sequenceStore.addToastText(t('general.success_text'), 'success')
} catch (e) {

View File

@@ -72,10 +72,7 @@
<li
v-if="userSequences.length"
v-for="item in userSequences"
:class="[
'sequence-item',
item.id === seqId ? 'button-item-hover' : ''
]"
class="sequence-item"
@mouseover="goToSequence(item)"
>
<router-link
@@ -233,9 +230,9 @@ let mapWidth = ref<number>(window.innerWidth / 3)
let listWidth = ref<number>(window.innerWidth / 1.5)
const windowWidth = ref<number>(window.innerWidth)
const windowHeight = ref<number>(window.innerHeight - 80)
const viewerRef = ref<any>(null)
const headerList = ref<any>(null)
const list = ref<any>(null)
const viewerRef = ref<InstanceType<typeof Viewer>>()
const headerList = ref<HTMLDivElement | null>(null)
const list = ref<HTMLDListElement | null>(null)
const listPos = ref<PositionInterface | null>(null)
const headerLisPos = ref<PositionInterface | null>(null)
@@ -252,7 +249,7 @@ async function patchCollection(sequence: SequenceLinkInterface): Promise<void> {
else visible = 'true'
await patchACollection(sequence.id, visible)
await fetchAndFormatSequence()
viewerRef.value.viewer.reloadVectorTiles()
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
isLoading.value = false
}
async function deleteCollection(
@@ -262,7 +259,7 @@ async function deleteCollection(
if (confirm(t('pages.sequence.confirm_sequence_dialog'))) {
await deleteACollection(sequence.id)
await fetchAndFormatSequence()
viewerRef.value.viewer.reloadVectorTiles()
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
}
isLoading.value = false
}
@@ -313,15 +310,21 @@ function bboxIsInsideOther(mainBbox: number[], bboxInside: number[]): boolean {
)
}
function goToSequence(sequence: SequenceLinkInterface): void {
seqId.value = sequence.id
viewerRef.value.viewer.select(seqId.value)
if (!viewerRef.value) return
const currentBbox = [
viewerRef.value.viewer._map.getBounds()._ne.lng,
viewerRef.value.viewer._map.getBounds()._ne.lat,
viewerRef.value.viewer._map.getBounds()._sw.lng,
viewerRef.value.viewer._map.getBounds()._sw.lat
]
if (bboxIsInsideOther(currentBbox, sequence.extent.spatial.bbox[0])) return
if (
seqId.value === sequence.id &&
bboxIsInsideOther(currentBbox, sequence.extent.spatial.bbox[0])
) {
return
}
seqId.value = sequence.id
viewerRef.value.viewer.select(seqId.value)
viewerRef.value.viewer._map.flyTo({
center: [
sequence.extent.spatial.bbox[0][0],
@@ -386,9 +389,13 @@ watchEffect(() => {
viewerRef.value.viewer.addEventListener(
'hover',
(e: { detail: { seqId: string } }) => {
if (seqId.value === e.detail.seqId) return
seqId.value = e.detail.seqId
scrollIntoSelected(e.detail.seqId, userSequences.value)
viewerRef.value.viewer.select(e.detail.seqId)
scrollIntoSelected(
e.detail.seqId,
userSequences.value.map((e) => e.id)
)
if (viewerRef.value) viewerRef.value.viewer.select(e.detail.seqId)
}
)
}
@@ -454,6 +461,16 @@ watchEffect(() => {
&:nth-child(2n) {
background-color: var(--white);
}
&:hover {
background-color: var(--blue);
color: var(--white);
.button-item {
& > *,
& > :nth-child(2) {
color: var(--white);
}
}
}
}
.wrapper-button {
position: absolute;
@@ -468,18 +485,6 @@ watchEffect(() => {
margin-bottom: toRem(1);
}
}
.button-item-hover {
background-color: var(--blue);
&:nth-child(2n) {
background-color: var(--blue);
}
.button-item {
& > *,
& > :nth-child(2) {
color: var(--white);
}
}
}
.item-head-fixed {
position: fixed;
top: toRem(8);

View File

@@ -229,7 +229,7 @@ async function uploadPicture(): Promise<void> {
body.append('picture', el)
try {
const pictureUploaded = await createAPictureToASequence(data.id, body)
const pictures = { ...pictureUploaded.data, name: el.name }
const pictures = { ...pictureUploaded, name: el.name }
picturesUploadingSize.value = picturesUploadingSize.value + el.size
uploadedSequence.value.pictures = [
...uploadedSequence.value.pictures,

View File

@@ -7,9 +7,8 @@ function imageStatus(imageStatus: string, sequenceStatus: string): string {
if (sequenceStatus === 'hidden') return sequenceStatus
return imageStatus
}
//TODO REMOVE ANY
function scrollIntoSelected(id: string, userPhotos: any): void {
const itemPosition = userPhotos.map((el: any) => el.id).indexOf(id)
function scrollIntoSelected(id: string, userPhotos: string[]): void {
const itemPosition = userPhotos.map((el: string) => el).indexOf(id)
const elementTarget = document.querySelector(`#el-list${itemPosition}`)
if (elementTarget) elementTarget.scrollIntoView({ behavior: 'smooth' })
}

View File

@@ -19,12 +19,32 @@ interface SequenceCreatedInterface {
}
}
interface PictureCreatedInterface {
data: {
assets: object
bbox: number[]
collection: string
geometry: object
id: string
links: object[]
properties: object
providers: object[]
stac_extensions: string[]
stac_version: string
type: string
}
}
function createASequence(title: string): Promise<SequenceCreatedInterface> {
return axios.post('api/collections', { title: title })
}
async function createAPictureToASequence(id: string, body: any): Promise<any> {
return await axios.post(`api/collections/${id}/items`, body)
async function createAPictureToASequence(
id: string,
body: FormData
): Promise<PictureCreatedInterface> {
const { data } = await axios.post(`api/collections/${id}/items`, body)
return data
}
export { createASequence, createAPictureToASequence }