Skip to content

Commit 44f8bc0

Browse files
committed
Présentation widget et modal d'importation
1 parent c629ae6 commit 44f8bc0

File tree

2 files changed

+242
-109
lines changed

2 files changed

+242
-109
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<template>
2+
<ion-modal
3+
:is-open="modalOpenRef"
4+
swipe-to-close
5+
:presenting-element="$parent.$refs.ionRouterOutlet"
6+
@didDismiss="closeModal()"
7+
>
8+
<ion-page>
9+
<ion-header collapse="fade">
10+
<ion-toolbar>
11+
<ion-title>Importation CrewConnect</ion-title>
12+
</ion-toolbar>
13+
</ion-header>
14+
<ion-content>
15+
<ion-list inset>
16+
<ion-item button @click="importLast3Months()" :disabled="state.isLoading">
17+
<ion-icon :icon="cloudDownloadOutline" slot="start" />
18+
Importer les 3 derniers mois
19+
</ion-item>
20+
<ion-item button @click="importLast12Months()" :disabled="state.isLoading">
21+
<ion-icon :icon="cloudDownloadOutline" slot="start" />
22+
Importer les 12 derniers mois
23+
</ion-item>
24+
</ion-list>
25+
<ion-list-header>
26+
<ion-label>Dates personnalisées</ion-label>
27+
</ion-list-header>
28+
<ion-note class="list-note">
29+
Sélectionnez les dates de début et de fin de l'interval à importer.<br>
30+
(Maximum 1 an)
31+
</ion-note>
32+
<ion-list inset class="ion-margin-top">
33+
<ion-accordion-group>
34+
<ion-accordion value="from">
35+
<ion-item slot="header" :disabled="state.isLoading">
36+
<ion-icon :icon="calendarOutline" slot="start" />
37+
<ion-label>Du</ion-label>
38+
<ion-note>{{ toLocaleString(state.fromDate, DATE_FORMAT) }}</ion-note>
39+
</ion-item>
40+
<ion-item slot="content">
41+
<ion-datetime
42+
v-model="state.fromDate"
43+
presentation="date"
44+
size="cover"
45+
:min="minDate"
46+
:max="maxDate" />
47+
</ion-item>
48+
</ion-accordion>
49+
<ion-accordion value="to">
50+
<ion-item slot="header" :disabled="state.isLoading">
51+
<ion-icon :icon="calendarOutline" slot="start" />
52+
<ion-label>Au</ion-label>
53+
<ion-note>{{ toLocaleString(state.toDate, DATE_FORMAT) }}</ion-note>
54+
</ion-item>
55+
<ion-item slot="content">
56+
<ion-datetime
57+
v-model="state.toDate"
58+
presentation="date"
59+
size="cover"
60+
:min="minDate"
61+
:max="maxDate" />
62+
</ion-item>
63+
</ion-accordion>
64+
</ion-accordion-group>
65+
</ion-list>
66+
<loading-button
67+
@click="importCustomInterval()"
68+
:loading="state.isLoading"
69+
expand="block"
70+
class="ion-margin-start ion-margin-end">
71+
Importer
72+
</loading-button>
73+
<ion-note v-if="state.error" class="list-note ion-text-center" color="danger">
74+
{{ state.error }}
75+
</ion-note>
76+
</ion-content>
77+
</ion-page>
78+
</ion-modal>
79+
</template>
80+
81+
<script setup>
82+
import { useConnect, useMainStore, usePlanning } from '@/store'
83+
import { cloudDownloadOutline, calendarOutline } from 'ionicons/icons'
84+
import LoadingButton from './LoadingButton.vue'
85+
import { toLocaleString } from '@/helpers/dates'
86+
import { DateTime } from 'luxon'
87+
import { computed, ref, reactive, watch } from 'vue'
88+
89+
const DATE_FORMAT = { month: 'long', day: 'numeric', year: 'numeric' }
90+
91+
const mainStore = useMainStore()
92+
const connect = useConnect()
93+
const planning = usePlanning()
94+
95+
const state = reactive({
96+
fromDate: '2021-01-01',
97+
toDate: '2021-12-31',
98+
isLoading: false,
99+
error: ''
100+
})
101+
102+
const minDate = '2010-01-01'
103+
const absMaxDate = DateTime.local().endOf('day').plus({ days: 31 }).toISODate()
104+
const maxDate = computed(() => {
105+
const oneYearMax = DateTime.fromISO(state.fromDate).plus({ year: 1 }).toISODate()
106+
return absMaxDate < oneYearMax ? absMaxDate : oneYearMax
107+
})
108+
109+
watch(
110+
() => state.fromDate,
111+
fromDate => {
112+
if (state.toDate < state.fromDate) {
113+
state.toDate = state.fromDate
114+
} else {
115+
const oneYearMax = DateTime.fromISO(state.fromDate).plus({ year: 1 }).toISODate()
116+
if (state.toDate > oneYearMax) {
117+
state.toDate = oneYearMax
118+
}
119+
}
120+
}
121+
)
122+
123+
async function importLast3Months() {
124+
const dateFrom = DateTime.local().startOf('month').minus({ months: 3 }).toUTC().toISO()
125+
const dateTo = DateTime.local().endOf('day').toUTC().toISO()
126+
return importRosterCalendars(dateFrom, dateTo)
127+
}
128+
129+
async function importLast12Months() {
130+
const dateFrom = DateTime.local().startOf('month').minus({ months: 12 }).toUTC().toISO()
131+
const dateTo = DateTime.local().endOf('day').toUTC().toISO()
132+
return importRosterCalendars(dateFrom, dateTo)
133+
}
134+
135+
async function importCustomInterval() {
136+
return importRosterCalendars(
137+
DateTime.fromISO(state.fromDate).toUTC().toISO(),
138+
DateTime.fromISO(state.toDate).toUTC().toISO()
139+
)
140+
}
141+
142+
async function importRosterCalendars(dateFrom, dateTo) {
143+
state.isLoading = true
144+
state.error = ''
145+
try {
146+
await mainStore.syncPlanningInterval({ dateFrom, dateTo })
147+
} catch (error) {
148+
state.error = error?.message || error?.error || "Une erreur s'est produite lors de l'importation"
149+
} finally {
150+
state.isLoading = false
151+
}
152+
}
153+
154+
155+
// eslint-disable-next-line no-undef
156+
const emit = defineEmits(['modal:close', 'modal:confirm'])
157+
158+
const modalOpenRef = ref(false)
159+
160+
function openModal() {
161+
modalOpenRef.value = true
162+
}
163+
164+
function closeModal() {
165+
modalOpenRef.value = false
166+
}
167+
168+
// eslint-disable-next-line no-undef
169+
defineExpose({
170+
openModal,
171+
closeModal
172+
})
173+
174+
function onCloseClick() {
175+
closeModal()
176+
emit('modal:close')
177+
}
178+
179+
function onConfirmClick() {
180+
closeModal()
181+
emit('modal:confirm')
182+
}
183+
</script>
184+
185+
<style lang="scss" scoped>
186+
ion-datetime {
187+
--background: transparent;
188+
}
189+
.list-note {
190+
display: block;
191+
padding-inline-start: 20px;
192+
padding-inline-end: 20px;
193+
}
194+
</style>

0 commit comments

Comments
 (0)