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