WIP Migrate to stimulus.js

This commit is contained in:
Björn Fromme
2021-08-16 14:08:15 +02:00
parent 6db1cb23b3
commit 81d7e192db
19 changed files with 89 additions and 173 deletions
@@ -12,9 +12,7 @@ smoothscroll.polyfill()
// Alpine stuff
import Alpine from 'alpinejs'
import parseAppConfig from './components/appconfig'
import initSliders from './components/sliders'
import appendPaCode from './components/pacode'
import watchlist from './components/watchlist'
import productDetail from './components/product-detail'
import daytripDateSelect from './components/daytrip-date-select'
import searchBar from './components/search-bar'
@@ -23,9 +21,7 @@ import contactForm from './components/contact-form'
const appConfig = parseAppConfig()
appendPaCode(appConfig)
initSliders()
Alpine.store('appconfig', appConfig)
Alpine.data('watchlist', watchlist)
Alpine.data('productDetail', productDetail)
Alpine.data('daytripDateSelect', daytripDateSelect)
Alpine.data('searchBar', searchBar)
@@ -1,126 +0,0 @@
import axios from 'axios'
import flatpickr from 'flatpickr';
import { German } from 'flatpickr/dist/l10n/de';
import defaultFilterSettings from '../_filtersettings'
export default props => ({
loading: false,
show: null,
picker: null,
uri: props.uri,
datePresets: props.datePresets,
filterSettings: props.initialFilterSettings,
defaultFilterSettings,
filterCount: 0,
dateRangeSelected: { from: null, to: null },
dateRangeLabel: null,
contentWrapper: null,
init() {
this.$watch('dateRangeSelected', () => {
this.updateDateRangeLabel()
})
this.contentWrapper = this.$refs.container
this.updateFilterCount()
this.load()
},
refresh() {
this.updateFilterCount()
this.load()
},
load() {
this.loading = true
let data = new URLSearchParams({
'tx_epproducts_ajax[filterSettings]': JSON.stringify(this.filterSettings)
})
axios.post(this.uri, data)
.then(response => {
this.contentWrapper.innerHTML = response.data
})
.finally(() => {
this.loading = false
if (null !== this.filterSettings.dateFrom && null !== this.filterSettings.dateTo) {
this.picker.setDate([ this.filterSettings.dateFrom, this.filterSettings.dateTo ])
this.dateRangeSelected = { from: new Date(this.filterSettings.dateFrom), to: new Date(this.filterSettings.dateTo) }
}
this.$el.scrollIntoView({behavior: 'smooth'})
})
},
reset() {
this.filterSettings = {...this.defaultFilterSettings}
this.dateRangeSelected = { from: null, to: null }
this.dateRangeLabel = null
this.refresh()
},
initDatePicker(minDate, maxDate) {
this.picker = flatpickr(this.$refs.picker, {
mode: 'range',
locale: German,
inline: true,
minDate: minDate,
maxDate: maxDate,
onChange: selectedDates => {
if (selectedDates.length === 2) {
this.dateRangeSelected = { from: selectedDates[0], to: selectedDates[1] }
this.updateFilterSettings({
dateFrom: flatpickr.formatDate(selectedDates[0], 'Y-m-d'),
dateTo: flatpickr.formatDate(selectedDates[1], 'Y-m-d'),
})
this.show = null
this.refresh()
}
}
})
},
updateFilterSettings(values) {
let filterSettings = {...this.filterSettings}
this.filterSettings = {...filterSettings, ...values}
},
selectDateRangePreset(preset) {
let dateFrom = new Date(preset.dateFrom)
let dateTo = new Date(preset.dateTo)
this.picker.setDate([ dateFrom, dateTo ])
this.dateRangeSelected = { from: dateFrom, to: dateTo }
this.updateFilterSettings({
dateFrom: flatpickr.formatDate(dateFrom, 'Y-m-d'),
dateTo: flatpickr.formatDate(dateTo, 'Y-m-d'),
})
this.show = null
this.refresh()
},
resetDateRange() {
this.dateRangeSelected = { from: null, to: null }
this.updateFilterSettings({
dateFrom: null,
dateTo: null,
})
this.picker.clear()
this.picker.jumpToDate()
this.show = null
this.refresh()
},
updateDateRangeLabel() {
let dateRangeLabel = ''
if (null !== this.dateRangeSelected.from && null !== this.dateRangeSelected.to) {
let dateFrom = this.dateRangeSelected.from
let dateTo = this.dateRangeSelected.to
dateRangeLabel = `${flatpickr.formatDate(dateFrom, 'd.m.Y')} - ${flatpickr.formatDate(dateTo, 'd.m.Y')}`
}
this.dateRangeLabel = dateRangeLabel
},
updateFilterCount() {
let count = 0
if (this.filterSettings.dateFrom !== null) count++
if (this.filterSettings.dateTo !== null) count++
if (this.filterSettings.countryUids.length > 0) count++
if (this.filterSettings.regionUids.length > 0) count++
if (this.filterSettings.cityUids.length > 0) count++
if (this.filterSettings.conceptUids.length > 0) count++
if (this.filterSettings.hotelTypes.length > 0) count++
if (this.filterSettings.boardTypes.length > 0) count++
if (this.filterSettings.roomTypes.length > 0) count++
if (this.filterSettings.priceRanges.length > 0) count++
if (this.filterSettings.bus) count++
if (this.filterSettings.pax > 2) count++
this.filterCount = count
},
})
@@ -1,22 +0,0 @@
import axios from 'axios'
export default uri => ({
loading: false,
uri,
init() {
this.load()
},
load() {
this.loading = true
let data = new URLSearchParams({
'tx_epproducts_ajax[watchlistUids]': JSON.stringify(this.$store.watchlist),
})
axios.post(this.uri, data)
.then(response => {
this.$refs.watchlist.innerHTML = response.data
})
.finally(() => {
this.loading = false
})
}
})
@@ -1,3 +1,4 @@
import { Controller } from 'stimulus'
import Splide from '@splidejs/splide'
const defaultOptions = {
@@ -90,13 +91,16 @@ const presets = {
},
}
export default () => {
document.querySelectorAll( '[data-slider]').forEach(element => {
export default class extends Controller {
static values = { preset: String }
connect() {
let options = {}
const preset = element.dataset.slider
let preset = this.presetValue
if (preset in presets) {
options = presets[preset]
}
new Splide(element, options).mount()
})
new Splide(this.element, options).mount()
}
}
@@ -0,0 +1,36 @@
import { Controller } from 'stimulus'
import { useFetch } from '../mixins/use_fetch'
export default class extends Controller {
static targets = [ 'container', 'loadingIndicator' ]
static values = {
uri: String,
loading: Boolean,
}
initialize() {
useFetch(this)
}
connect() {
this.load()
}
load() {
this.loadingValue = true
let data = new URLSearchParams({
'tx_epproducts_ajax[watchlistUids]': sessionStorage.getItem('myep-watchlist'),
})
fetch(this.uriValue, { method: 'POST', body: data })
.then(this.checkStatus)
.then(this.parseHTML)
.then(html => {
this.containerTarget.innerHTML = html
})
.finally(() => {
this.loadingValue = false
})
}
}
@@ -3,7 +3,9 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<div class="lg:-mt-8">
<div class="splide" data-slider="header">
<div class="splide"
data-controller="slider"
data-slider-preset-value="header">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{slides}" as="slide" iteration="iteration">
@@ -17,7 +17,9 @@
<f:if condition="{teasers}">
<f:then>
<a id="teasers" class="anchor"></a>
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="teaser">
@@ -4,7 +4,9 @@
<f:alias map="{images: '{media -> v:iterator.filter(propertyName: \'showinpreview\', filter: 0)}'}">
<f:if condition="{images}">
<div data-slider="content" class="splide">
<div class="splide"
data-controller="slider"
data-slider-preset-value="content">
<div id="carousel-{id}" class="splide__track">
<ul class="splide__list">
<f:for each="{images}" as="image" iteration="iteration">
@@ -6,7 +6,9 @@
<div class="bg-cover bg-center bg-header-season-{product.region.season} mb-8">
<div class="md:container">
<div class="md:flex md:flex-row-reverse md:items-stretch">
<div class="md:w-5/12 md:py-4 splide" data-slider="content">
<div class="md:w-5/12 md:py-4 splide"
data-controller="slider"
data-slider-preset-value="content">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{product.images}" as="image" iteration="iteration">
@@ -22,7 +22,9 @@
{region.skiArea -> f:format.html()}
<f:if condition="{teasers}">
<a id="teasers" class="anchor"></a>
<div class="splide" data-slider="teasersEmbedded">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasersEmbedded">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="teaser">
@@ -9,7 +9,9 @@
<f:render partial="Header/Standalone" arguments="{_all}"/>
<div>
<ep:container data="{data}">
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="city">
@@ -24,7 +24,9 @@
<div class="col-span-3 lg:col-span-2" data-rte-content>
{concept.description -> f:format.html()}
<f:if condition="{teasers}">
<div class="splide mb-4" data-slider="teasersEmbedded">
<div class="splide mb-4"
data-controller="slider"
data-slider-preset-value="teasersEmbedded">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="teaser">
@@ -8,7 +8,9 @@
<f:section name="Main">
<div>
<ep:container data="{data}">
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="concept">
@@ -24,7 +24,9 @@
<div class="col-span-3 lg:col-span-2" id="teasers">
{country.description -> f:format.html()}
<f:if condition="{teasers}">
<div class="splide mb-4" data-slider="teasersEmbedded">
<div class="splide mb-4"
data-controller="slider"
data-slider-preset-value="teasersEmbedded">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="teaser">
@@ -7,7 +7,9 @@
<f:section name="Main">
<div>
<ep:container data="{data}">
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="hotel">
@@ -7,7 +7,9 @@
<f:section name="Main">
<div>
<ep:container data="{data}">
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{bookable}" as="hotel">
@@ -12,7 +12,9 @@
<ep:container data="{data}">
<f:if condition="{data.flexForm.settings.layout} == 'cols'">
<f:then>
<div class="w-full mb-4 splide" data-slider="teasers">
<div class="w-full mb-4 splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:render section="Teasers" arguments="{_all}"/>
@@ -8,7 +8,9 @@
<f:section name="Main">
<div>
<ep:container data="{data}">
<div class="splide" data-slider="teasers">
<div class="splide"
data-controller="slider"
data-slider-preset-value="teasers">
<div class="splide__track">
<ul class="splide__list">
<f:for each="{teasers}" as="region">
@@ -7,9 +7,11 @@
<f:section name="Main">
<ep:container data="{data}">
<div class="relative"
x-data='watchlist("<ep:uri.ajax action="list" controller="AjaxWatchlist" pageUid="{settings.defaultAjaxUid}"/>")'>
<div x-ref="watchlist"></div>
<div x-show="loading" class="absolute top-0 left-0 inset-0 bg-overlay-white">
data-controller="watchlist"
data-watchlist-uri-value="{ep:uri.ajax(action: 'list', controller: 'AjaxWatchlist', pageUid: '{settings.defaultAjaxUid}')}">
<div data-watchlist-target="container"></div>
<div class="absolute top-0 left-0 inset-0 bg-overlay-white hidden"
data-watchlist-target="loadingIndicator">
<f:image class="absolute top-1/2 left-1/2 transform -translate-xy-1/2"
src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif"
alt="Loading"/>