forked from Ivasoft/geovisio-website
Compare commits
33 Commits
57-filter-
...
tech-add-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0a9d0eb27 | ||
|
|
5488ac8521 | ||
|
|
80089126c4 | ||
|
|
4fed5f7938 | ||
|
|
5a6d144196 | ||
|
|
9c2ab2453c | ||
|
|
be2cdbb62b | ||
|
|
2e2f23de69 | ||
|
|
669f0528e5 | ||
|
|
6e0f19a5f1 | ||
|
|
661ba984fd | ||
|
|
aa3dbdaf03 | ||
|
|
aa257adbcf | ||
|
|
d1779da92d | ||
|
|
379c44c5ce | ||
|
|
8452b50ea0 | ||
|
|
30b49a8c7d | ||
|
|
482372fccb | ||
|
|
f37dc950cb | ||
|
|
02ba0efe8d | ||
|
|
a3bec701ea | ||
|
|
87da6714a2 | ||
|
|
1bf633b284 | ||
|
|
7b56fb5c33 | ||
|
|
7eb090492b | ||
|
|
e580887969 | ||
|
|
56e2908f70 | ||
|
|
2afabb82f4 | ||
|
|
8d4a0968ea | ||
|
|
a006811b44 | ||
|
|
387f84b1a7 | ||
|
|
86a54fed85 | ||
|
|
6f6e16c2c7 |
@@ -20,10 +20,6 @@ describe('In the contribute page', () => {
|
||||
})
|
||||
interface contributeInterface {
|
||||
textButtonContribute: string
|
||||
textButtonDocPython: string
|
||||
textButtonCli: string
|
||||
textButtonDocCli: string
|
||||
textButtonTiles: string
|
||||
textButtonDoc: string
|
||||
}
|
||||
export {}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
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 {}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"textLinkLogin": "Sign In",
|
||||
"textLinkUpload": "Mes photos",
|
||||
"textTitle": "My title",
|
||||
"textButtonTitle": "Valider",
|
||||
"textButtonUpload": "Glissez vos images ici ou cliquez sur"
|
||||
}
|
||||
@@ -1,8 +1,3 @@
|
||||
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>`
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
>
|
||||
<div class="wrapper-input">
|
||||
<Input
|
||||
id="upload-title"
|
||||
:text="text || ''"
|
||||
:placeholder="$t('pages.upload.edit_placeholder_input')"
|
||||
@input="changeTextValue"
|
||||
|
||||
@@ -128,6 +128,7 @@ onClickOutside(list, () => closeModal())
|
||||
function closeModal(): void {
|
||||
menuIsClosed.value = true
|
||||
}
|
||||
|
||||
function toggleMenu(): void {
|
||||
menuIsClosed.value = !menuIsClosed.value
|
||||
}
|
||||
|
||||
@@ -3,18 +3,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
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, createSequenceLink } from '@/components-viewer/reportLink'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { hasASessionCookieDecoded } from '@/utils/auth'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import type { ViewerInterface, MapInterface } from '@/views/interfaces/common'
|
||||
|
||||
const sequenceStore = useSequenceStore()
|
||||
import { getIgnTiles } from '@/utils/mapAndViewer'
|
||||
import { Viewer, StandaloneMap } from 'geovisio'
|
||||
import { createUrlLink } from '@/utils'
|
||||
import { createLink } from '@/components-viewer/reportLink'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
let mapIsLoaded = ref<boolean>(false)
|
||||
let viewer = ref()
|
||||
@@ -25,152 +20,119 @@ 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
|
||||
})
|
||||
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> {
|
||||
onMounted(async () => {
|
||||
const tiles = import.meta.env.VITE_TILES
|
||||
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 = { map: { startWide: true } }
|
||||
if (center && center !== '') {
|
||||
const centerMap = center.split(',').map((el: string) => parseInt(el))
|
||||
paramsViewer = {
|
||||
map: {
|
||||
...paramsViewer.map,
|
||||
center: centerMap
|
||||
}
|
||||
}
|
||||
}
|
||||
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 paramsViewer: ViewerInterface
|
||||
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) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
onUnmounted((): void => {
|
||||
onUnmounted(() => {
|
||||
if (viewer.value && props.geovisioViewer) viewer.value.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
"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",
|
||||
"sequence_title": "See the séquence"
|
||||
"report_button_text": "Report this picture"
|
||||
},
|
||||
"settings": {
|
||||
"title": "My tokens",
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
"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",
|
||||
"sequence_title": "Voir la séquence"
|
||||
"report_button_text": "Signaler la photo"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Mes Tokens",
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
"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",
|
||||
"sequence_title": "lásd a sorrendet"
|
||||
"report_button_text": "Fénykép jelentése"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Saját tokenek",
|
||||
|
||||
@@ -3,8 +3,7 @@ import { defineStore } from 'pinia'
|
||||
export const useSequenceStore = defineStore('sequence', {
|
||||
state: () => ({
|
||||
toastText: <string>'',
|
||||
toastLook: <string>'',
|
||||
picId: <string>''
|
||||
toastLook: <string>''
|
||||
}),
|
||||
actions: {
|
||||
addToastText(text: string, look: string): void {
|
||||
@@ -13,9 +12,6 @@ export const useSequenceStore = defineStore('sequence', {
|
||||
setTimeout(() => {
|
||||
this.toastText = ''
|
||||
}, 3000)
|
||||
},
|
||||
addSequence(id: string): void {
|
||||
this.picId = id
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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: { id: string }) => el.id === 'toponyme - parcellaire - adresse'
|
||||
(el: any) => el.id === 'toponyme - parcellaire - adresse'
|
||||
)
|
||||
data.layers[objIndex].layout = {
|
||||
...data.layers[objIndex].layout,
|
||||
|
||||
@@ -245,7 +245,7 @@ let isLoading = ref<boolean>(false)
|
||||
const collapseMenu = ref<HTMLDivElement>()
|
||||
const deleteAll = ref<HTMLDivElement>()
|
||||
const menuHeight = ref<string>()
|
||||
const viewerRef = ref<InstanceType<typeof Viewer>>()
|
||||
const viewerRef = ref()
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
@@ -266,54 +266,37 @@ onMounted(async () => {
|
||||
)
|
||||
pictures.value = collectionItems
|
||||
setHeightValue()
|
||||
if (
|
||||
itemSelected.value.length ||
|
||||
!getCurrentPicId(collectionItemsReady[0].id)
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (!viewerRef.value) return
|
||||
if (itemSelected.value.length || !collectionItemsReady[0]) return
|
||||
viewerRef.value.viewer._api.onceReady().then(() => {
|
||||
if (!viewerRef.value) return
|
||||
viewerRef.value.viewer.goToPicture(
|
||||
getCurrentPicId(collectionItemsReady[0].id),
|
||||
collectionItemsReady[0].id,
|
||||
sequence.value?.id
|
||||
)
|
||||
})
|
||||
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)
|
||||
)
|
||||
itemSelected.value = collectionItemsReady[0].id
|
||||
scrollIntoSelected(collectionItemsReady[0].id, pictures.value)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
|
||||
watchEffect(async () => {
|
||||
if (!viewerRef || !viewerRef.value || !viewerRef.value.viewer) return
|
||||
if (!viewerExist(viewerRef)) return
|
||||
viewerRef.value.viewer.addEventListener(
|
||||
'picture-loaded',
|
||||
async (e: { detail: { picId: string } }): Promise<void> => {
|
||||
if (!pictureExistInList(getCurrentPicId(e.detail.picId))) {
|
||||
await goToTheGoodPage(getCurrentPicId(e.detail.picId))
|
||||
if (itemSelected.value === e.detail.picId) return
|
||||
if (!pictureExistInList(e.detail.picId)) {
|
||||
await goToTheGoodPage(e.detail.picId)
|
||||
}
|
||||
itemSelected.value = getCurrentPicId(e.detail.picId)
|
||||
scrollIntoSelected(
|
||||
getCurrentPicId(e.detail.picId),
|
||||
pictures.value.map((e) => e.id)
|
||||
)
|
||||
itemSelected.value = e.detail.picId
|
||||
scrollIntoSelected(e.detail.picId, pictures.value)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
function getCurrentPicId(id: string): string {
|
||||
const parseParams = new URLSearchParams(window.location.search)
|
||||
const pict = parseParams.get('currentPic')
|
||||
return pict && pict.length ? pict : id
|
||||
function viewerExist(viewerRef: any): boolean {
|
||||
return !!(viewerRef && viewerRef.value && viewerRef.value.viewer)
|
||||
}
|
||||
|
||||
const isSequenceOwner = computed((): boolean => {
|
||||
@@ -438,7 +421,7 @@ async function patchCollection(): Promise<void> {
|
||||
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
|
||||
pictures.value = data.features
|
||||
}
|
||||
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
|
||||
viewerRef.value.viewer.reloadVectorTiles()
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
@@ -452,10 +435,7 @@ 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.map((e) => e.id)
|
||||
)
|
||||
scrollIntoSelected(pictures.value[0].id, pictures.value)
|
||||
picturesToDelete.value = []
|
||||
isLoading.value = false
|
||||
setHeightValue()
|
||||
@@ -504,26 +484,16 @@ 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'
|
||||
) {
|
||||
if (viewerRef.value) {
|
||||
const viewerMap = await viewerRef.value.viewer
|
||||
viewerMap.goToPicture(item.id, sequence.value?.id)
|
||||
}
|
||||
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.map((e) => e.id)
|
||||
)
|
||||
scrollIntoSelected(item.id, pictures.value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,14 +553,9 @@ async function patchOrDeleteCollectionItems(
|
||||
const { data } = await fetchCollectionItems(route.params.id, '?limit=100')
|
||||
pictures.value = data.features
|
||||
isLoading.value = false
|
||||
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)
|
||||
)
|
||||
viewerRef.value.viewer.reloadVectorTiles()
|
||||
viewerRef.value.viewer.goToPicture(pictures.value[0].id, route.params.id)
|
||||
scrollIntoSelected(picturesToDelete.value[0], pictures.value)
|
||||
picturesToDelete.value = []
|
||||
sequenceStore.addToastText(t('general.success_text'), 'success')
|
||||
} catch (e) {
|
||||
|
||||
@@ -72,7 +72,10 @@
|
||||
<li
|
||||
v-if="userSequences.length"
|
||||
v-for="item in userSequences"
|
||||
class="sequence-item"
|
||||
:class="[
|
||||
'sequence-item',
|
||||
item.id === seqId ? 'button-item-hover' : ''
|
||||
]"
|
||||
@mouseover="goToSequence(item)"
|
||||
>
|
||||
<router-link
|
||||
@@ -230,9 +233,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<InstanceType<typeof Viewer>>()
|
||||
const headerList = ref<HTMLDivElement | null>(null)
|
||||
const list = ref<HTMLDListElement | null>(null)
|
||||
const viewerRef = ref<any>(null)
|
||||
const headerList = ref<any>(null)
|
||||
const list = ref<any>(null)
|
||||
const listPos = ref<PositionInterface | null>(null)
|
||||
const headerLisPos = ref<PositionInterface | null>(null)
|
||||
|
||||
@@ -249,7 +252,7 @@ async function patchCollection(sequence: SequenceLinkInterface): Promise<void> {
|
||||
else visible = 'true'
|
||||
await patchACollection(sequence.id, visible)
|
||||
await fetchAndFormatSequence()
|
||||
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
|
||||
viewerRef.value.viewer.reloadVectorTiles()
|
||||
isLoading.value = false
|
||||
}
|
||||
async function deleteCollection(
|
||||
@@ -259,7 +262,7 @@ async function deleteCollection(
|
||||
if (confirm(t('pages.sequence.confirm_sequence_dialog'))) {
|
||||
await deleteACollection(sequence.id)
|
||||
await fetchAndFormatSequence()
|
||||
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
|
||||
viewerRef.value.viewer.reloadVectorTiles()
|
||||
}
|
||||
isLoading.value = false
|
||||
}
|
||||
@@ -310,21 +313,15 @@ function bboxIsInsideOther(mainBbox: number[], bboxInside: number[]): boolean {
|
||||
)
|
||||
}
|
||||
function goToSequence(sequence: SequenceLinkInterface): void {
|
||||
if (!viewerRef.value) return
|
||||
seqId.value = sequence.id
|
||||
viewerRef.value.viewer.select(seqId.value)
|
||||
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 (
|
||||
seqId.value === sequence.id &&
|
||||
bboxIsInsideOther(currentBbox, sequence.extent.spatial.bbox[0])
|
||||
) {
|
||||
return
|
||||
}
|
||||
seqId.value = sequence.id
|
||||
viewerRef.value.viewer.select(seqId.value)
|
||||
if (bboxIsInsideOther(currentBbox, sequence.extent.spatial.bbox[0])) return
|
||||
viewerRef.value.viewer._map.flyTo({
|
||||
center: [
|
||||
sequence.extent.spatial.bbox[0][0],
|
||||
@@ -389,13 +386,9 @@ 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.map((e) => e.id)
|
||||
)
|
||||
if (viewerRef.value) viewerRef.value.viewer.select(e.detail.seqId)
|
||||
scrollIntoSelected(e.detail.seqId, userSequences.value)
|
||||
viewerRef.value.viewer.select(e.detail.seqId)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -461,16 +454,6 @@ 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;
|
||||
@@ -485,6 +468,18 @@ 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);
|
||||
|
||||
@@ -229,7 +229,7 @@ async function uploadPicture(): Promise<void> {
|
||||
body.append('picture', el)
|
||||
try {
|
||||
const pictureUploaded = await createAPictureToASequence(data.id, body)
|
||||
const pictures = { ...pictureUploaded, name: el.name }
|
||||
const pictures = { ...pictureUploaded.data, name: el.name }
|
||||
picturesUploadingSize.value = picturesUploadingSize.value + el.size
|
||||
uploadedSequence.value.pictures = [
|
||||
...uploadedSequence.value.pictures,
|
||||
|
||||
@@ -7,8 +7,9 @@ function imageStatus(imageStatus: string, sequenceStatus: string): string {
|
||||
if (sequenceStatus === 'hidden') return sequenceStatus
|
||||
return imageStatus
|
||||
}
|
||||
function scrollIntoSelected(id: string, userPhotos: string[]): void {
|
||||
const itemPosition = userPhotos.map((el: string) => el).indexOf(id)
|
||||
//TODO REMOVE ANY
|
||||
function scrollIntoSelected(id: string, userPhotos: any): void {
|
||||
const itemPosition = userPhotos.map((el: any) => el.id).indexOf(id)
|
||||
const elementTarget = document.querySelector(`#el-list${itemPosition}`)
|
||||
if (elementTarget) elementTarget.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
|
||||
@@ -19,32 +19,12 @@ 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: FormData
|
||||
): Promise<PictureCreatedInterface> {
|
||||
const { data } = await axios.post(`api/collections/${id}/items`, body)
|
||||
return data
|
||||
async function createAPictureToASequence(id: string, body: any): Promise<any> {
|
||||
return await axios.post(`api/collections/${id}/items`, body)
|
||||
}
|
||||
|
||||
export { createASequence, createAPictureToASequence }
|
||||
|
||||
Reference in New Issue
Block a user