forked from Ivasoft/geovisio-website
923 lines
25 KiB
Vue
923 lines
25 KiB
Vue
<template>
|
|
<main class="entry-page">
|
|
<section :style="{ width: `${mapWidth}px` }" class="section-viewer">
|
|
<vue-draggable-resizable
|
|
:style="{ width: `${mapWidth}px` }"
|
|
:w="mapWidth"
|
|
:h="windowHeight"
|
|
:max-width="windowWidth"
|
|
:handles="['mr']"
|
|
:draggable="false"
|
|
class-name-active="resize-active-map"
|
|
class-name-handle="resize-handle-map"
|
|
@resizing="onResizeMap"
|
|
>
|
|
<Viewer
|
|
v-if="collectionBbox.length"
|
|
:fetch-options="{
|
|
fetchOptions: {
|
|
credentials: 'include'
|
|
}
|
|
}"
|
|
:geovisio-viewer="false"
|
|
:user-id="getUserId"
|
|
:bbox="collectionBbox"
|
|
ref="viewerRef"
|
|
/>
|
|
<div v-else class="no-map">
|
|
<img
|
|
src="@/assets/images/how-to-share-map.png"
|
|
:alt="$t('pages.share_pictures.alt_img_map')"
|
|
class="no-map-img"
|
|
/>
|
|
</div>
|
|
</vue-draggable-resizable>
|
|
<div class="bbox-filter-button">
|
|
<Button
|
|
look="button--white background-white"
|
|
icon="bi bi-search"
|
|
:text="$t('pages.sequences.filter_bbox_button')"
|
|
@trigger="triggerBboxFilter"
|
|
/>
|
|
<div class="reset-bbox">
|
|
<Button
|
|
v-if="filterBbox"
|
|
look="no-text-blue-dark"
|
|
icon="bi bi-x-circle-fill"
|
|
@trigger="triggerResetBbox"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section
|
|
:style="{ width: `${listWidth}px` }"
|
|
class="section-sequence"
|
|
@scroll="handleScroll"
|
|
>
|
|
<div class="header-title">
|
|
<h1 id="sequenceTitle" class="sequences-title">
|
|
{{ $t('pages.sequences.title') }}
|
|
</h1>
|
|
<Button
|
|
v-if="
|
|
filterDate.start || filterDate.end || sortDate.sortBy || filterBbox
|
|
"
|
|
look="button-border--black"
|
|
:text="$t('pages.sequences.reset_filter_button')"
|
|
@trigger="resetAllFilter"
|
|
/>
|
|
</div>
|
|
<div
|
|
ref="headerList"
|
|
:class="['sequence-item sequence-item-head', headerListClass]"
|
|
:style="{ width: `${listWidth}px`, borderRadius: '0px' }"
|
|
>
|
|
<div class="sequence-header-item"></div>
|
|
<div class="sequence-header-item">
|
|
<span>{{ $t('pages.sequences.sequence_name') }}</span>
|
|
</div>
|
|
<div class="sequence-header-item">
|
|
<span>{{ $t('pages.sequences.sequence_photos') }}</span>
|
|
</div>
|
|
<div class="sequence-header-item">
|
|
<Button
|
|
look="link--black no-text"
|
|
:icon="iconButtonSort('datetime')"
|
|
data-test="button-sort-date"
|
|
@trigger="sortList('datetime')"
|
|
/>
|
|
<span class="title">{{ $t('pages.sequences.sequence_date') }}</span>
|
|
<div class="button-filter">
|
|
<Button
|
|
:look="filterClass"
|
|
:icon="iconButtonFilter('datetime')"
|
|
:tooltip="$t('pages.sequences.sequence_date_tooltip')"
|
|
@trigger="displayModal('datetime')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="sequence-header-item">
|
|
<Button
|
|
look="link--black no-text"
|
|
:icon="iconButtonSort('created')"
|
|
data-test="button-sort-date"
|
|
@trigger="sortList('created')"
|
|
/>
|
|
<span class="title">{{
|
|
$t('pages.sequences.sequence_creation')
|
|
}}</span>
|
|
<div class="button-filter">
|
|
<Button
|
|
:look="filterClass"
|
|
:icon="iconButtonFilter('created')"
|
|
:tooltip="$t('pages.sequences.sequence_creation_tooltip')"
|
|
@trigger="displayModal('created')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="sequence-header-item">
|
|
<span>{{ $t('pages.sequences.sequence_status') }}</span>
|
|
</div>
|
|
</div>
|
|
<ul v-if="!isLoading" ref="list" class="sequence-list">
|
|
<li
|
|
v-if="userSequences.length"
|
|
v-for="item in userSequences"
|
|
:class="['sequence-item', { 'sequence-selected': item.id === seqId }]"
|
|
@mouseover="goToSequence(item)"
|
|
>
|
|
<router-link
|
|
class="button-item"
|
|
:to="{
|
|
name: 'sequence',
|
|
params: { id: item.id }
|
|
}"
|
|
>
|
|
<div class="wrapper-thumb">
|
|
<img
|
|
v-if="item['stats:items'].count > 0"
|
|
loading="lazy"
|
|
:src="`${item.href}/thumb.jpg`"
|
|
alt=""
|
|
class="thumb"
|
|
/>
|
|
<div class="wrapper-thumb-hover">
|
|
<img
|
|
v-if="item['stats:items'].count > 0"
|
|
loading="lazy"
|
|
:src="`${item.href}/thumb.jpg`"
|
|
alt=""
|
|
class="thumb-hover"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="sequence-title">
|
|
<span>
|
|
{{ item.title }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<i class="bi bi-images"></i>
|
|
<span>
|
|
{{ item['stats:items'].count }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<span>
|
|
{{
|
|
formatDate(
|
|
item.extent.temporal.interval[0][0],
|
|
'Do MMM YYYY HH:mm:ss'
|
|
)
|
|
}}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<span>
|
|
{{ formatDate(item.created, 'Do MMM YYYY HH:mm:ss') }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<span :class="item['geovisio:status']">{{
|
|
sequenceStatus(item['geovisio:status'])
|
|
}}</span>
|
|
</div>
|
|
</router-link>
|
|
<div class="wrapper-button">
|
|
<Button
|
|
:text="sequenceButtonText(item['geovisio:status'])"
|
|
look="link--blue row-reverse"
|
|
:icon="
|
|
item['geovisio:status'] === 'ready'
|
|
? 'bi bi-eye-slash'
|
|
: 'bi bi-eye'
|
|
"
|
|
class="disable-button"
|
|
@trigger="patchCollection(item)"
|
|
/>
|
|
<Button
|
|
:text="$t('pages.sequences.delete_button')"
|
|
look="link--red row-reverse"
|
|
icon="bi bi-trash"
|
|
@trigger="deleteCollection(item)"
|
|
/>
|
|
</div>
|
|
</li>
|
|
<div v-else-if="!userSequences.length && noSequencesFound">
|
|
<p class="no-sequence-found">
|
|
{{ $t('pages.sequences.no_sequence_found') }}
|
|
</p>
|
|
</div>
|
|
<div v-else class="no-sequence">
|
|
<p class="no-sequence-text">
|
|
{{ $t('pages.sequences.no_sequences_text') }}
|
|
</p>
|
|
<Link
|
|
:text="$t('general.header.upload_text')"
|
|
look="button button--blue"
|
|
:route="{ name: 'why-contribute' }"
|
|
/>
|
|
</div>
|
|
</ul>
|
|
<div v-else class="loader">
|
|
<Loader look="sm" :is-loaded="false" />
|
|
</div>
|
|
<div class="entry-pagination">
|
|
<Pagination
|
|
v-for="item in paginationLinks"
|
|
:type="item.rel"
|
|
:href="item.href"
|
|
:self-link="selfLink[0]"
|
|
@trigger="goToNextPage"
|
|
/>
|
|
</div>
|
|
<Toast :text="toastText" :look="toastLook" @trigger="toastText = ''" />
|
|
</section>
|
|
<Modal ref="modal" :title="modalTitle">
|
|
<template v-slot:body>
|
|
<CalendarFilter
|
|
v-if="calendarType === filterDate.type"
|
|
:type="calendarType"
|
|
:range-selected="{
|
|
start: filterDate.start,
|
|
end: filterDate.end,
|
|
type: filterDate.type
|
|
}"
|
|
@triggerCloseModal="closeModal"
|
|
@triggerDate="updateFilters"
|
|
/>
|
|
<CalendarFilter
|
|
v-else
|
|
:type="calendarType"
|
|
:range-selected="{ start: null, end: null, type: '' }"
|
|
@triggerCloseModal="closeModal"
|
|
@triggerDate="updateFilters"
|
|
/>
|
|
</template>
|
|
</Modal>
|
|
</main>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onMounted, ref, watchEffect, computed, nextTick } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useSequenceStore } from '@/store/sequence'
|
|
import { storeToRefs } from 'pinia'
|
|
import {
|
|
scrollIntoSelected,
|
|
formatPaginationItems
|
|
} from '@/views/utils/sequence/index'
|
|
import { useCookies } from 'vue3-cookies'
|
|
import axios from 'axios'
|
|
import Viewer from '@/components/Viewer.vue'
|
|
import type ViewerType from '@/components/Viewer.vue'
|
|
import Button from '@/components/Button.vue'
|
|
import Link from '@/components/Link.vue'
|
|
import Toast from '@/components/Toast.vue'
|
|
import Loader from '@/components/Loader.vue'
|
|
import Modal from '@/components/Modal.vue'
|
|
import CalendarFilter from '@/components/filters/CalendarFilter.vue'
|
|
import Pagination from '@/components/Pagination.vue'
|
|
import type { SequenceLinkInterface } from './interfaces/MySequencesView'
|
|
import type { ResponseUserPhotoLinksInterface } from './interfaces/MySequenceView'
|
|
import { formatDate } from '@/utils/dates'
|
|
import {
|
|
deleteACollection,
|
|
patchACollection
|
|
} from '@/views/utils/sequence/request'
|
|
|
|
const { t } = useI18n()
|
|
const { cookies } = useCookies()
|
|
const sequenceStore = useSequenceStore()
|
|
const { toastText, toastLook } = storeToRefs(sequenceStore)
|
|
interface PositionInterface {
|
|
bottom: number
|
|
top: number
|
|
right: number
|
|
left: number
|
|
y: number
|
|
x: number
|
|
}
|
|
let userSequences = ref<SequenceLinkInterface[]>([])
|
|
let paginationLinks = ref<ResponseUserPhotoLinksInterface[] | []>([])
|
|
let selfLink = ref<ResponseUserPhotoLinksInterface[] | []>([])
|
|
let collectionBbox = ref<number[]>([])
|
|
let isLoading = ref<boolean>(false)
|
|
let sortedBy = ref<string>('')
|
|
let isSorted = ref<boolean>(false)
|
|
let noSequencesFound = ref<boolean>(false)
|
|
let seqId = ref<string>('')
|
|
let calendarType = ref<string>('')
|
|
let width = ref<number>(0)
|
|
let mapWidth = ref<number>(window.innerWidth / 3)
|
|
let listWidth = ref<number>(window.innerWidth / 1.5)
|
|
let filterDate = ref<{
|
|
end: string | null
|
|
start: string | null
|
|
type: string
|
|
}>({
|
|
start: null,
|
|
end: null,
|
|
type: ''
|
|
})
|
|
let filterBbox = ref<number[] | null>(null)
|
|
let sortDate = ref<{ sortBy: string | null }>({ sortBy: null })
|
|
let uri = ref<string>('api/users/me/collection?limit=50')
|
|
let modal = ref()
|
|
const windowWidth = ref<number>(window.innerWidth)
|
|
const windowHeight = ref<number>(window.innerHeight - 80)
|
|
const viewerRef = ref<InstanceType<typeof ViewerType>>()
|
|
const headerList = ref<HTMLDivElement | null>(null)
|
|
const list = ref<HTMLDListElement | null>(null)
|
|
const listPos = ref<PositionInterface | null>(null)
|
|
const headerLisPos = ref<PositionInterface | null>(null)
|
|
|
|
async function resetAllFilter(): Promise<void> {
|
|
filterDate.value = { start: null, end: null, type: '' }
|
|
sortDate.value = { sortBy: null }
|
|
filterBbox.value = null
|
|
formatUri()
|
|
await updateSequence(uri.value)
|
|
}
|
|
async function triggerResetBbox(): Promise<void> {
|
|
filterBbox.value = null
|
|
formatUri()
|
|
await updateSequence(uri.value)
|
|
}
|
|
function triggerBboxFilter(): void {
|
|
if (viewerRef.value) {
|
|
isLoading.value = true
|
|
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
|
|
]
|
|
filterBbox.value = currentBbox
|
|
formatUri()
|
|
updateSequence(uri.value)
|
|
}
|
|
}
|
|
function displayModal(type: string): void {
|
|
calendarType.value = type
|
|
if (modal.value) modal.value.show()
|
|
}
|
|
function closeModal(): void {
|
|
if (modal.value) modal.value.close()
|
|
}
|
|
function iconButtonSort(type: string): string {
|
|
if (isSorted.value && sortedBy.value === type) return 'bi bi-sort-numeric-up'
|
|
return 'bi bi-sort-numeric-down'
|
|
}
|
|
function iconButtonFilter(type: string): string {
|
|
if (
|
|
filterDate.value.start &&
|
|
filterDate.value.end &&
|
|
filterDate.value.type === type
|
|
) {
|
|
return 'bi bi-funnel-fill'
|
|
}
|
|
return 'bi bi-funnel'
|
|
}
|
|
async function fetchAndFormatSequence(): Promise<void> {
|
|
const { data } = await axios.get('api/users/me/collection?limit=50')
|
|
collectionBbox.value = data.extent.spatial.bbox[0]
|
|
userSequences.value = getLinkByRel(data.links, 'child')
|
|
}
|
|
|
|
async function patchCollection(sequence: SequenceLinkInterface): Promise<void> {
|
|
isLoading.value = true
|
|
let visible
|
|
if (sequence['geovisio:status'] === 'ready') visible = 'false'
|
|
else visible = 'true'
|
|
await patchACollection(sequence.id, { visible: visible })
|
|
await fetchAndFormatSequence()
|
|
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
|
|
isLoading.value = false
|
|
}
|
|
async function deleteCollection(
|
|
sequence: SequenceLinkInterface
|
|
): Promise<void> {
|
|
isLoading.value = true
|
|
if (confirm(t('pages.sequence.confirm_sequence_dialog'))) {
|
|
await deleteACollection(sequence.id)
|
|
await fetchAndFormatSequence()
|
|
if (viewerRef.value) viewerRef.value.viewer.reloadVectorTiles()
|
|
}
|
|
isLoading.value = false
|
|
}
|
|
function sequenceStatus(status: string): string {
|
|
if (status === 'ready') return t('pages.sequences.sequence_published')
|
|
if (status === 'hidden') return t('pages.sequences.sequence_hidden')
|
|
return t('pages.sequences.sequence_waiting')
|
|
}
|
|
function sequenceButtonText(status: string): string {
|
|
if (status === 'hidden') return t('pages.sequences.show_button')
|
|
return t('pages.sequences.hide_button')
|
|
}
|
|
function onResizeMap(width: any): void {
|
|
if (width && collectionBbox.value.length) {
|
|
width.value = width
|
|
mapWidth.value = width.value.width
|
|
listWidth.value = window.innerWidth - width.value.width
|
|
}
|
|
}
|
|
const handleScroll = async () => {
|
|
await nextTick()
|
|
if (headerList.value && headerList.value.getBoundingClientRect()) {
|
|
headerLisPos.value = headerList.value.getBoundingClientRect()
|
|
}
|
|
if (list.value && list.value.getBoundingClientRect()) {
|
|
listPos.value = list.value.getBoundingClientRect()
|
|
}
|
|
}
|
|
async function updateSequence(uri: string) {
|
|
try {
|
|
const { data } = await axios.get(uri)
|
|
selfLink.value = getLinkByRel(data.links, 'self')
|
|
paginationLinks.value = formatPaginationItems(data.links)
|
|
userSequences.value = getLinkByRel(data.links, 'child')
|
|
scrollToElement()
|
|
isLoading.value = false
|
|
if (!userSequences.value.length) noSequencesFound.value = true
|
|
} catch (e) {
|
|
userSequences.value = []
|
|
noSequencesFound.value = true
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
async function sortList(dateToSort: string): Promise<void> {
|
|
isLoading.value = true
|
|
sortedBy.value = dateToSort
|
|
let sortBy = `+${dateToSort}`
|
|
if (isSorted.value) sortBy = `-${dateToSort}`
|
|
sortDate.value.sortBy = encodeURIComponent(sortBy)
|
|
formatUri()
|
|
await updateSequence(uri.value)
|
|
isSorted.value = !isSorted.value
|
|
}
|
|
|
|
function bboxIsInsideOther(mainBbox: number[], bboxInside: number[]): boolean {
|
|
return (
|
|
bboxInside[0] <= mainBbox[0] &&
|
|
bboxInside[1] <= mainBbox[1] &&
|
|
bboxInside[2] >= mainBbox[2] &&
|
|
bboxInside[3] >= mainBbox[3]
|
|
)
|
|
}
|
|
function goToSequence(sequence: SequenceLinkInterface): void {
|
|
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 (
|
|
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],
|
|
sequence.extent.spatial.bbox[0][1]
|
|
],
|
|
duration: 0
|
|
})
|
|
}
|
|
function getLinkByRel(
|
|
sequences: SequenceLinkInterface[],
|
|
rel: string
|
|
): SequenceLinkInterface[] {
|
|
return sequences.filter((el: SequenceLinkInterface) => el.rel === rel)
|
|
}
|
|
function scrollToElement(): void {
|
|
const elementTarget = document.querySelector('#sequenceTitle')
|
|
if (elementTarget) elementTarget.scrollIntoView({ behavior: 'smooth' })
|
|
}
|
|
async function goToNextPage(value: string): Promise<void> {
|
|
isLoading.value = true
|
|
await updateSequence(value)
|
|
}
|
|
const filterClass = computed<string>((): string => {
|
|
return 'no-text-green'
|
|
})
|
|
const modalTitle = computed<string>((): string => {
|
|
if (calendarType.value === 'datetime') {
|
|
return t('pages.sequences.filter_date_title')
|
|
}
|
|
return t('pages.sequences.filter_date_upload_title')
|
|
})
|
|
const getUserId = computed<string>((): string => cookies.get('user_id'))
|
|
const headerListClass = computed<string>((): string => {
|
|
if (headerLisPos.value && listPos.value) {
|
|
const classCondition = headerLisPos.value.y != 0 && listPos.value.top < 174
|
|
return classCondition ? 'item-head-fixed' : ''
|
|
}
|
|
return ''
|
|
})
|
|
onMounted(async () => {
|
|
isLoading.value = true
|
|
try {
|
|
const { data } = await axios.get('api/users/me/collection?limit=50')
|
|
selfLink.value = getLinkByRel(data.links, 'self')
|
|
paginationLinks.value = formatPaginationItems(data.links)
|
|
userSequences.value = getLinkByRel(data.links, 'child')
|
|
if (userSequences.value[0]) {
|
|
collectionBbox.value = [
|
|
userSequences.value[0].extent.spatial.bbox[0][0],
|
|
userSequences.value[0].extent.spatial.bbox[0][1],
|
|
userSequences.value[0].extent.spatial.bbox[0][2],
|
|
userSequences.value[0].extent.spatial.bbox[0][3]
|
|
]
|
|
}
|
|
isLoading.value = false
|
|
} catch (err) {
|
|
isLoading.value = false
|
|
console.log(err)
|
|
}
|
|
})
|
|
function formatUri(): void {
|
|
let params: string[] = []
|
|
if (filterBbox && filterBbox.value) {
|
|
const bboxFilter = `${filterBbox.value[0]},${filterBbox.value[1]},${filterBbox.value[2]},${filterBbox.value[3]}`
|
|
params = [...params, `&bbox=${bboxFilter}`]
|
|
}
|
|
if (filterDate.value.start && filterDate.value.end) {
|
|
const rangeFilter = encodeURIComponent(
|
|
`${filterDate.value.type} BETWEEN '${filterDate.value.start}' AND '${filterDate.value.end}'`
|
|
)
|
|
params = [...params, `&filter=${rangeFilter}`]
|
|
}
|
|
if (sortDate.value.sortBy) {
|
|
params = [...params, `&sortby=${sortDate.value.sortBy}`]
|
|
}
|
|
if (params.length) {
|
|
const constructParams = params.join('')
|
|
uri.value = `api/users/me/collection?limit=50${constructParams}`
|
|
} else uri.value = 'api/users/me/collection?limit=50'
|
|
}
|
|
async function updateFilters(value: {
|
|
start: null
|
|
end: null
|
|
type: ''
|
|
}): Promise<void> {
|
|
isLoading.value = true
|
|
noSequencesFound.value = false
|
|
filterDate.value = { start: value.start, end: value.end, type: value.type }
|
|
formatUri()
|
|
await updateSequence(uri.value)
|
|
}
|
|
watchEffect(() => {
|
|
if (viewerRef.value && viewerRef.value.viewer) {
|
|
viewerRef.value.viewer.addEventListener(
|
|
'select',
|
|
(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)
|
|
}
|
|
)
|
|
}
|
|
})
|
|
</script>
|
|
<style lang="scss">
|
|
.resize-handle-map-mr {
|
|
top: 0;
|
|
right: toRem(0);
|
|
cursor: e-resize;
|
|
background-color: var(--black);
|
|
display: block !important;
|
|
}
|
|
.resize-handle-map {
|
|
z-index: 999999;
|
|
box-sizing: border-box;
|
|
position: absolute;
|
|
height: 100%;
|
|
width: toRem(0.5);
|
|
&:hover {
|
|
cursor: col-resize;
|
|
}
|
|
}
|
|
</style>
|
|
<style lang="scss" scoped>
|
|
.entry-page {
|
|
display: flex;
|
|
height: calc(100vh - #{toRem(8)});
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
.section-viewer {
|
|
height: 100%;
|
|
position: relative;
|
|
}
|
|
.bbox-filter-button {
|
|
padding: toRem(2);
|
|
width: fit-content;
|
|
height: fit-content;
|
|
position: relative;
|
|
}
|
|
.reset-bbox {
|
|
position: absolute;
|
|
right: 0;
|
|
top: toRem(0.5);
|
|
}
|
|
.no-map {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100%;
|
|
width: 100%;
|
|
background-color: var(--blue-pale);
|
|
}
|
|
.section-sequence {
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
height: 100%;
|
|
position: relative;
|
|
}
|
|
.header-title {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
position: relative;
|
|
margin: toRem(3);
|
|
}
|
|
.sequences-title {
|
|
@include text(h1);
|
|
color: var(--blue-dark);
|
|
}
|
|
.date-filter-title {
|
|
@include text(s-r-regular);
|
|
}
|
|
.wrapper-date-filter-title {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
.sequence-list {
|
|
box-shadow: 0px 2px 30px 0px #0000000f;
|
|
padding: 0;
|
|
}
|
|
.sequence-item {
|
|
@include text(s-regular);
|
|
position: relative;
|
|
border: none;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin: auto;
|
|
background-color: var(--blue-pale);
|
|
padding-right: toRem(2);
|
|
padding-left: toRem(2);
|
|
&:nth-child(2n) {
|
|
background-color: var(--white);
|
|
}
|
|
&:hover,
|
|
&.sequence-selected {
|
|
background-color: var(--blue-semi);
|
|
}
|
|
}
|
|
.wrapper-button {
|
|
position: absolute;
|
|
right: toRem(1);
|
|
bottom: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
height: 100%;
|
|
.button--white:first-child {
|
|
margin-bottom: toRem(1);
|
|
}
|
|
}
|
|
.item-head-fixed {
|
|
position: fixed;
|
|
top: toRem(8);
|
|
width: 100%;
|
|
z-index: 2;
|
|
}
|
|
.sequence-item-head {
|
|
margin-bottom: toRem(1);
|
|
padding: toRem(1) toRem(2);
|
|
border-bottom: toRem(0.1) solid var(--grey);
|
|
border-radius: toRem(2) toRem(2) 0rem 0rem;
|
|
background-color: var(--white);
|
|
}
|
|
.sequence-item-head:hover {
|
|
background-color: var(--white);
|
|
color: initial;
|
|
}
|
|
.wrapper-title {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.wrapper-thumb {
|
|
position: relative;
|
|
}
|
|
.wrapper-thumb-hover {
|
|
display: none;
|
|
border-radius: toRem(0.3);
|
|
border: toRem(1) solid var(--grey);
|
|
position: absolute;
|
|
bottom: 0;
|
|
height: toRem(15);
|
|
z-index: 1;
|
|
}
|
|
.sequence-title {
|
|
text-decoration: underline;
|
|
}
|
|
.ready {
|
|
color: var(--green);
|
|
}
|
|
.hidden {
|
|
color: var(--red-pale);
|
|
}
|
|
.waiting-for-process {
|
|
color: var(--yellow);
|
|
}
|
|
.thumb-hover {
|
|
height: 100%;
|
|
}
|
|
.wrapper-thumb:hover {
|
|
.wrapper-thumb-hover {
|
|
display: block;
|
|
}
|
|
}
|
|
.thumb {
|
|
height: 100%;
|
|
width: 100%;
|
|
object-fit: cover;
|
|
border-radius: toRem(0.5);
|
|
position: relative;
|
|
}
|
|
.button-item {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
background-color: transparent;
|
|
border: none;
|
|
text-decoration: none;
|
|
& > * {
|
|
padding: toRem(1);
|
|
text-align: initial;
|
|
width: calc(31% - #{toRem(4.75)});
|
|
color: var(--black);
|
|
}
|
|
> :first-child {
|
|
color: var(--blue);
|
|
width: toRem(6);
|
|
}
|
|
& > :first-child {
|
|
padding: 0;
|
|
margin-right: toRem(2);
|
|
}
|
|
& > :nth-child(3) {
|
|
width: toRem(13);
|
|
}
|
|
& > :nth-child(2) {
|
|
color: var(--blue-dark);
|
|
}
|
|
}
|
|
.bi-images {
|
|
margin-right: toRem(0.5);
|
|
}
|
|
.sequence-header-item {
|
|
display: flex;
|
|
align-items: center;
|
|
width: calc(31% - #{toRem(4.75)});
|
|
color: var(--grey-semi-dark);
|
|
&:first-child {
|
|
margin-right: toRem(2);
|
|
}
|
|
&:first-child {
|
|
width: toRem(6);
|
|
}
|
|
&:nth-child(3) {
|
|
width: toRem(13);
|
|
}
|
|
.title {
|
|
color: var(--black);
|
|
}
|
|
}
|
|
.button-filter {
|
|
margin-left: toRem(-1);
|
|
.icon {
|
|
font-size: toRem(1);
|
|
}
|
|
}
|
|
.no-sequence {
|
|
padding-top: toRem(2);
|
|
padding-bottom: toRem(4);
|
|
width: fit-content;
|
|
@include text(m-regular);
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin: auto;
|
|
}
|
|
.no-sequence-text {
|
|
margin-bottom: toRem(4);
|
|
}
|
|
.no-sequence-found {
|
|
text-align: center;
|
|
padding: toRem(2);
|
|
}
|
|
.loader {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100%;
|
|
}
|
|
.ay11-link {
|
|
padding: toRem(2);
|
|
margin-left: auto;
|
|
width: fit-content;
|
|
}
|
|
.entry-pagination {
|
|
margin-top: toRem(4);
|
|
margin-bottom: toRem(4);
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
@media (max-width: toRem(102.4)) {
|
|
.section-viewer {
|
|
width: 30%;
|
|
}
|
|
.section-sequence {
|
|
width: 70%;
|
|
}
|
|
}
|
|
@media (max-width: toRem(76.8)) {
|
|
.entry-page {
|
|
padding-right: toRem(2);
|
|
padding-left: toRem(2);
|
|
padding-top: toRem(14);
|
|
height: 100%;
|
|
}
|
|
.section-viewer {
|
|
display: none;
|
|
}
|
|
.section-sequence {
|
|
width: 100% !important;
|
|
}
|
|
.sequence-item-head {
|
|
width: 100% !important;
|
|
flex-direction: row !important;
|
|
padding-right: 0;
|
|
padding-left: 0;
|
|
}
|
|
.sequence-header-item {
|
|
width: 50%;
|
|
justify-content: center;
|
|
&:first-child,
|
|
&:last-child,
|
|
&:nth-child(2),
|
|
&:nth-child(3) {
|
|
display: none;
|
|
}
|
|
}
|
|
.button-item {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding-right: toRem(1);
|
|
padding-left: toRem(1);
|
|
& > * {
|
|
text-align: center;
|
|
width: 100%;
|
|
}
|
|
.wrapper-thumb {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
.sequence-item {
|
|
border-top-right-radius: toRem(1);
|
|
border-top-left-radius: toRem(1);
|
|
flex-direction: column;
|
|
}
|
|
.wrapper-button {
|
|
flex-direction: row;
|
|
position: relative;
|
|
right: 0;
|
|
bottom: 0;
|
|
justify-content: center;
|
|
margin-top: toRem(1);
|
|
margin-bottom: 0;
|
|
.button--white:first-child {
|
|
margin-right: toRem(1);
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|