Skip to content

Commit 1fe3818

Browse files
fix: calendar import
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
1 parent 4bf8f5a commit 1fe3818

12 files changed

Lines changed: 910 additions & 261 deletions

File tree

css/import.scss

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,60 @@
1919
gap: 5px;
2020
}
2121

22+
.import-modal__counters {
23+
display: grid;
24+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
25+
gap: 12px;
26+
margin-top: 20px;
27+
align-items: stretch;
28+
}
29+
30+
.import-modal__counter {
31+
display: flex;
32+
align-items: center;
33+
gap: 10px;
34+
padding: 12px 14px;
35+
border: 1px solid var(--color-border-maxcontrast);
36+
border-radius: var(--border-radius-large);
37+
background: var(--color-background-hover);
38+
min-width: 0;
39+
}
40+
41+
.import-modal__counter-icon {
42+
display: inline-flex;
43+
align-items: center;
44+
justify-content: center;
45+
width: 32px;
46+
height: 32px;
47+
flex: 0 0 32px;
48+
border-radius: 50%;
49+
color: var(--color-primary-element);
50+
border: 1px solid var(--color-primary-element);
51+
background: transparent;
52+
53+
svg {
54+
width: 18px;
55+
height: 18px;
56+
}
57+
}
58+
59+
.import-modal__counter-content {
60+
display: flex;
61+
flex-direction: column;
62+
min-width: 0;
63+
}
64+
65+
.import-modal__counter strong {
66+
font-size: 1rem;
67+
line-height: 1.2;
68+
}
69+
70+
.import-modal__counter span:last-child {
71+
color: var(--color-text-maxcontrast);
72+
font-size: 0.875rem;
73+
line-height: 1.3;
74+
}
75+
2276
.import-modal-file-item {
2377
display: flex;
2478
margin-top: calc(var(--default-grid-baseline) * 2);

src/components/AppNavigation/Settings.vue

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ import {
186186
} from '../../models/consts.js'
187187
import { getCurrentUserPrincipal } from '../../services/caldavService.js'
188188
import useCalendarsStore from '../../store/calendars.js'
189-
import useImportFilesStore from '../../store/importFiles.js'
189+
import useImportStore from '../../store/import.ts'
190190
import usePrincipalsStore from '../../store/principals.js'
191191
import useSettingsStore from '../../store/settings.js'
192192
import {
@@ -248,7 +248,7 @@ export default {
248248
},
249249
250250
computed: {
251-
...mapStores(useSettingsStore, useCalendarsStore, useImportFilesStore, usePrincipalsStore),
251+
...mapStores(useSettingsStore, useCalendarsStore, useImportStore, usePrincipalsStore),
252252
...mapState(useSettingsStore, [
253253
'eventLimit',
254254
'showTasks',
@@ -278,25 +278,13 @@ export default {
278278
},
279279
280280
files() {
281-
return this.importFilesStore.importFiles
281+
return this.importStore.importFiles
282282
},
283283
284284
hasBirthdayCalendar() {
285285
return !!this.calendarsStore.getBirthdayCalendar
286286
},
287287
288-
showUploadButton() {
289-
return this.importStateStore.importState.stage === IMPORT_STAGE_DEFAULT
290-
},
291-
292-
showImportModal() {
293-
return this.importStateStore.importState.stage === IMPORT_STAGE_PROCESSING
294-
},
295-
296-
showProgressBar() {
297-
return this.importStateStore.importState.stage === IMPORT_STAGE_IMPORTING
298-
},
299-
300288
settingsTitle() {
301289
return this.$t('calendar', 'Calendar settings')
302290
},

src/components/AppNavigation/Settings/ImportScreen.vue

Lines changed: 144 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,172 @@
99
size="large"
1010
:name="$t('calendar', 'Import destination selection')"
1111
@close="cancelImport">
12-
<h2 class="import-modal__title">
13-
{{ $t('calendar', 'Import calendars') }}
14-
</h2>
15-
<h4 class="import-modal__subtitle">
16-
<!-- eslint-disable-next-line no-irregular-whitespace -->
17-
{{ $t('calendar', 'Please select a calendar to import into …') }}
18-
</h4>
19-
20-
<transition-group class="import-modal__file-list" tag="ul">
21-
<li key="import-header-row" class="import-modal-file-item import-modal-file-item--header">
22-
<div class="import-modal-file-item__filename">
23-
{{ $t('calendar', 'Filename') }}
12+
<template v-if="isSelecting">
13+
<h2 class="import-modal__title">
14+
{{ $t('calendar', 'Import calendars') }}
15+
</h2>
16+
<h4 class="import-modal__subtitle">
17+
{{ $t('calendar', 'Please select a calendar to import into …') }}
18+
</h4>
19+
20+
<transition-group class="import-modal__file-list" tag="ul">
21+
<li key="import-header-row" class="import-modal-file-item import-modal-file-item--header">
22+
<div class="import-modal-file-item__filename">
23+
{{ $t('calendar', 'Filename') }}
24+
</div>
25+
<div class="import-modal-file-item__calendar-select">
26+
{{ $t('calendar', 'Calendar to import into') }}
27+
</div>
28+
</li>
29+
<ImportScreenRow v-for="(file, index) in files" :key="`import-file-${index}`" :file="file" />
30+
</transition-group>
31+
32+
<div class="import-modal__actions">
33+
<NcButton @click="cancelImport">
34+
{{ $t('calendar', 'Cancel') }}
35+
</NcButton>
36+
<NcButton class="primary" @click="importCalendar">
37+
{{ $n('calendar', 'Import calendar', 'Import calendars', files.length) }}
38+
</NcButton>
39+
</div>
40+
</template>
41+
42+
<template v-else>
43+
<h2 class="import-modal__title">
44+
{{ $t('calendar', 'Importing calendars') }}
45+
</h2>
46+
<h4 class="import-modal__subtitle">
47+
{{ activeFileLabel }}
48+
</h4>
49+
50+
<progress
51+
class="settings-fieldset-interior-item__import-progress-bar"
52+
:value="totals.processed"
53+
:max="Math.max(totals.discovered, 1)" />
54+
55+
<div class="import-modal__counters">
56+
<div class="import-modal__counter">
57+
<span class="import-modal__counter-icon" aria-hidden="true">
58+
<ProgressQuestionIcon :size="18" decorative />
59+
</span>
60+
<div class="import-modal__counter-content">
61+
<strong>{{ totals.discovered }}</strong>
62+
<span>{{ $t('calendar', 'Discovered') }}</span>
63+
</div>
64+
</div>
65+
<div class="import-modal__counter">
66+
<span class="import-modal__counter-icon" aria-hidden="true">
67+
<ProgressClockIcon :size="18" decorative />
68+
</span>
69+
<div class="import-modal__counter-content">
70+
<strong>{{ totals.processed }}</strong>
71+
<span>{{ $t('calendar', 'Processed') }}</span>
72+
</div>
2473
</div>
25-
<div class="import-modal-file-item__calendar-select">
26-
{{ $t('calendar', 'Calendar to import into') }}
74+
<div class="import-modal__counter">
75+
<span class="import-modal__counter-icon" aria-hidden="true">
76+
<CheckBoldIcon :size="18" decorative />
77+
</span>
78+
<div class="import-modal__counter-content">
79+
<strong>{{ totals.created }}</strong>
80+
<span>{{ $t('calendar', 'Created') }}</span>
81+
</div>
2782
</div>
28-
</li>
29-
<ImportScreenRow v-for="(file, index) in files" :key="`import-file-${index}`" :file="file" />
30-
</transition-group>
31-
32-
<div class="import-modal__actions">
33-
<NcButton @click="cancelImport">
34-
{{ $t('calendar', 'Cancel') }}
35-
</NcButton>
36-
<NcButton class="primary" @click="importCalendar">
37-
{{ $n('calendar', 'Import calendar', 'Import calendars', files.length) }}
38-
</NcButton>
39-
</div>
83+
<div class="import-modal__counter">
84+
<span class="import-modal__counter-icon" aria-hidden="true">
85+
<ReloadIcon :size="18" decorative />
86+
</span>
87+
<div class="import-modal__counter-content">
88+
<strong>{{ totals.updated }}</strong>
89+
<span>{{ $t('calendar', 'Updated') }}</span>
90+
</div>
91+
</div>
92+
<div class="import-modal__counter">
93+
<span class="import-modal__counter-icon" aria-hidden="true">
94+
<CloseIcon :size="18" decorative />
95+
</span>
96+
<div class="import-modal__counter-content">
97+
<strong>{{ totals.exists }}</strong>
98+
<span>{{ $t('calendar', 'Skipped') }}</span>
99+
</div>
100+
</div>
101+
<div class="import-modal__counter">
102+
<span class="import-modal__counter-icon" aria-hidden="true">
103+
<AlertCircleOutlineIcon :size="18" decorative />
104+
</span>
105+
<div class="import-modal__counter-content">
106+
<strong>{{ totals.error }}</strong>
107+
<span>{{ $t('calendar', 'Errors') }}</span>
108+
</div>
109+
</div>
110+
</div>
111+
</template>
40112
</Modal>
41113
</template>
42114

43115
<script>
44116
import { NcModal as Modal, NcButton } from '@nextcloud/vue'
117+
import AlertCircleOutlineIcon from 'vue-material-design-icons/AlertCircleOutline'
118+
import CheckBoldIcon from 'vue-material-design-icons/CheckBold'
119+
import CloseIcon from 'vue-material-design-icons/Close'
120+
import ProgressClockIcon from 'vue-material-design-icons/ProgressClock'
121+
import ProgressQuestionIcon from 'vue-material-design-icons/ProgressQuestion'
122+
import ReloadIcon from 'vue-material-design-icons/Reload'
45123
import ImportScreenRow from './ImportScreenRow.vue'
46124
47125
export default {
48126
name: 'ImportScreen',
49127
components: {
128+
AlertCircleOutlineIcon,
129+
CheckBoldIcon,
130+
CloseIcon,
50131
NcButton,
51132
ImportScreenRow,
52133
Modal,
134+
ProgressClockIcon,
135+
ProgressQuestionIcon,
136+
ReloadIcon,
53137
},
54138
55139
props: {
56140
files: {
57141
type: Array,
58142
required: true,
59143
},
144+
145+
stage: {
146+
type: String,
147+
required: true,
148+
},
149+
150+
totals: {
151+
type: Object,
152+
required: true,
153+
},
154+
155+
activeSession: {
156+
type: Object,
157+
default: null,
158+
},
159+
},
160+
161+
emits: ['cancelImport', 'importCalendar'],
162+
163+
computed: {
164+
isSelecting() {
165+
return this.stage === 'selecting'
166+
},
167+
168+
activeFileLabel() {
169+
if (!this.activeSession) {
170+
return this.$t('calendar', 'Preparing import…')
171+
}
172+
173+
return this.$t('calendar', 'Importing {fileName} into {calendar}', {
174+
fileName: this.activeSession.fileName,
175+
calendar: this.activeSession.targetDisplayName || this.$t('calendar', 'selected calendar'),
176+
})
177+
},
60178
},
61179
62180
methods: {

src/components/AppNavigation/Settings/ImportScreenRow.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { getLanguage } from '@nextcloud/l10n'
2727
import { mapStores } from 'pinia'
2828
import CalendarPicker from '../../Shared/CalendarPicker.vue'
2929
import useCalendarsStore from '../../../store/calendars.js'
30-
import useImportFilesStore from '../../../store/importFiles.js'
30+
import useImportStore from '../../../store/import.ts'
3131
import usePrincipalsStore from '../../../store/principals.js'
3232
import { uidToHexColor } from '../../../utils/color.js'
3333
@@ -45,7 +45,7 @@ export default {
4545
},
4646
4747
computed: {
48-
...mapStores(usePrincipalsStore, useImportFilesStore, useCalendarsStore),
48+
...mapStores(usePrincipalsStore, useImportStore, useCalendarsStore),
4949
newCalendar() {
5050
return {
5151
id: 'new',
@@ -57,7 +57,7 @@ export default {
5757
},
5858
5959
calendar() {
60-
const calendarId = this.importFilesStore.importCalendarRelation[this.file.id]
60+
const calendarId = this.importStore.importCalendarRelation[this.file.id]
6161
if (calendarId === this.newCalendar.id) {
6262
return this.newCalendar
6363
}
@@ -127,7 +127,7 @@ export default {
127127
},
128128
129129
selectCalendar(newCalendar) {
130-
this.importFilesStore.setCalendarForFileId({
130+
this.importStore.setCalendarForFileId({
131131
fileId: this.file.id,
132132
calendarId: newCalendar.id,
133133
})

0 commit comments

Comments
 (0)