Skip to content

Commit af3ed5f

Browse files
authored
Merge pull request #7902 from BacLuc/fix-create-camp-without-template
Fix create camp without template
2 parents 3bb3b1d + 3809981 commit af3ed5f

File tree

7 files changed

+93
-17
lines changed

7 files changed

+93
-17
lines changed

e2e/cypress.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = defineConfig({
1111
downloadsFolder: 'data/downloads',
1212
trashAssetsBeforeRuns: false,
1313
e2e: {
14+
experimentalStudio: true,
1415
setupNodeEvents(on, config) {
1516
on('task', {
1617
deleteDownloads: () => deleteDownloads(config),

e2e/specs/zz-createCamp.cy.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { bipiUser } from './constants'
2+
3+
const tomorrow = new Date()
4+
tomorrow.setDate(tomorrow.getDate() + 1)
5+
6+
const in2Days = new Date()
7+
in2Days.setDate(in2Days.getDate() + 2)
8+
9+
const campTitle = 'title'
10+
describe('create new camp', () => {
11+
it('without prototype', () => {
12+
cy.login(bipiUser)
13+
14+
cy.visit('/camps')
15+
16+
cy.get('[data-testid="create-camp-button"]').click()
17+
18+
cy.get('[data-testid="create-camp-title-input"] input').type(campTitle)
19+
cy.get('[data-testid="create-camp-organizer"] input').type('org')
20+
cy.get('[data-testid="create-camp-motto"] input').type('motto')
21+
cy.get('[data-testid="start-date-picker"] input').type(
22+
tomorrow.toLocaleDateString('de-CH')
23+
)
24+
cy.get('[data-testid="end-date-picker"] input').type(
25+
in2Days.toLocaleDateString('de-CH')
26+
)
27+
28+
cy.get('[data-testid="create-camp-next-step"]').click()
29+
cy.get('.v-select__selections > [data-testid="prototype-select"]').click()
30+
cy.contains('Keine Vorlage').click()
31+
cy.get('[data-testid="create-camp-button"]').click()
32+
33+
cy.contains('Lagerinfos').should('be.visible')
34+
cy.get('[data-testid="title"] input').should('have.value', campTitle)
35+
})
36+
})

frontend/src/components/campAdmin/CampSettings.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ Displays details on a single camp and allows to edit them.
1010
<v-skeleton-loader v-if="camp._meta.loading" type="article" />
1111
<div v-else class="mt-3">
1212
<api-form :entity="camp" name="camp">
13-
<api-text-field path="title" vee-rules="required|max:32" :disabled="disabled" />
13+
<api-text-field
14+
path="title"
15+
vee-rules="required|max:32"
16+
:disabled="disabled"
17+
data-testid="title"
18+
/>
1419

1520
<api-text-field
1621
path="shortTitle"

frontend/src/components/campAdmin/CreateCampPeriods.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
:max="period.end"
5151
:my="2"
5252
:filled="false"
53+
data-testid="start-date-picker"
5354
required
5455
/>
5556
</v-col>
@@ -62,6 +63,7 @@
6263
:min="period.start"
6364
:my="2"
6465
:filled="false"
66+
data-testid="end-date-picker"
6567
required
6668
/>
6769
</v-col>

frontend/src/components/campCreate/CampCreateStep1.vue

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@
99
path="title"
1010
:placeholder="$tc('components.campCreate.campCreateStep1.titlePlaceholder')"
1111
vee-rules="required|max:32"
12+
data-testid="create-camp-title-input"
1213
required
1314
/>
14-
<e-text-field v-model="localCamp.organizer" path="organizer" />
15-
<e-text-field v-model="localCamp.motto" path="motto" />
15+
<e-text-field
16+
v-model="localCamp.organizer"
17+
path="organizer"
18+
data-testid="create-camp-organizer"
19+
/>
20+
<e-text-field
21+
v-model="localCamp.motto"
22+
path="motto"
23+
data-testid="create-camp-motto"
24+
/>
1625
<CreateCampPeriods
1726
:add-period="addPeriod"
1827
:periods="localCamp.periods"
@@ -24,7 +33,11 @@
2433
<ContentActions>
2534
<v-spacer />
2635
<ButtonCancel :disabled="isSaving" @click="$router.go(-1)" />
27-
<ButtonContinue v-if="valid" @click="$emit('next-step')" />
36+
<ButtonContinue
37+
v-if="valid"
38+
data-testid="create-camp-next-step"
39+
@click="$emit('next-step')"
40+
/>
2841
<v-tooltip v-else top>
2942
<template #activator="{ attrs, on }">
3043
<v-btn

frontend/src/components/campCreate/CampCreateStep2.vue

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@
77
<server-error :server-error="serverError" />
88

99
<e-select
10-
v-model="localCamp.campPrototype"
10+
v-model="selectedPrototypeValue"
1111
:vee-rules="{ required: true }"
1212
:skip-if-empty="false"
1313
:label="$tc('entity.camp.prototype')"
1414
:hint="prototypeHint"
1515
persistent-hint
1616
:items="campTemplates"
1717
:menu-props="{ offsetY: true }"
18+
data-testid="prototype-select"
1819
/>
1920
<div
20-
v-if="localCamp.campPrototype === 'other'"
21+
v-if="selectedPrototypeValue === 'other'"
2122
class="e-form-container d-flex gap-2"
2223
>
2324
<e-text-field
@@ -177,7 +178,12 @@
177178
</v-btn>
178179
<div class="ml-auto">
179180
<ButtonCancel :disabled="isSaving" @click="$router.go(-1)" />
180-
<ButtonAdd v-if="valid" type="submit" :loading="isSaving">
181+
<ButtonAdd
182+
v-if="valid"
183+
type="submit"
184+
:loading="isSaving"
185+
data-testid="create-camp-button"
186+
>
181187
{{ $tc('components.campCreate.campCreateStep2.create') }}
182188
</ButtonAdd>
183189
<v-tooltip v-else top>
@@ -213,7 +219,7 @@ import ClipboardInfoDialog from '@/components/generic/ClipboardInfoDialog.vue'
213219
import { useClipboardEntity } from '@/components/generic/useClipboardEntity.js'
214220
import router from '@/router.js'
215221
import { apiStore as api } from '@/plugins/store/index.js'
216-
import { reactive, ref } from 'vue'
222+
import { reactive, ref, watchEffect } from 'vue'
217223
218224
export default {
219225
name: 'CampCreateStep2',
@@ -237,6 +243,14 @@ export default {
237243
setup({ camp }) {
238244
const localCamp = reactive(camp)
239245
const copyCampUrl = ref('')
246+
const selectedPrototypeValue = ref(null)
247+
watchEffect(() => {
248+
if (['other', 'none', null].includes(selectedPrototypeValue.value)) {
249+
localCamp.campPrototype = null
250+
} else {
251+
localCamp.campPrototype = selectedPrototypeValue.value
252+
}
253+
})
240254
241255
const clipboard = useClipboardEntity({
242256
fetchClipboardEntity: async (url) => {
@@ -248,11 +262,11 @@ export default {
248262
return await api.get().camps({ id: match.params.campId })
249263
},
250264
onEntityLoaded(entity) {
251-
localCamp.campPrototype = entity._meta.self
265+
selectedPrototypeValue.value = entity._meta.self
252266
},
253267
onEntityLoadFailed() {
254268
// If "other" is selected, leave the selection as it is, so the user can try again
255-
if (localCamp.campPrototype !== 'other') localCamp.campPrototype = ''
269+
if (selectedPrototypeValue.value !== 'other') selectedPrototypeValue.value = ''
256270
},
257271
})
258272
@@ -266,6 +280,7 @@ export default {
266280
setClipboardEntityUrl,
267281
localCamp,
268282
copyCampUrl,
283+
selectedPrototypeValue,
269284
}
270285
},
271286
computed: {
@@ -291,28 +306,28 @@ export default {
291306
},
292307
prototypeHint() {
293308
const campPrototypeUris = this.campPrototypes.map((prototype) => prototype.value)
294-
switch (this.localCamp.campPrototype) {
309+
switch (this.selectedPrototypeValue) {
295310
case '':
296311
return this.$tc('components.campCreate.campCreateStep2.prototypeHint')
297312
case 'none':
298313
return this.$tc('components.campCreate.campCreateStep2.prototypeHintEmpty')
299314
case 'other':
300315
return ''
301316
default:
302-
if (!campPrototypeUris.includes(this.localCamp.campPrototype)) {
317+
if (!campPrototypeUris.includes(this.selectedPrototypeValue)) {
303318
return this.$tc('components.campCreate.campCreateStep2.prototypeHintOther')
304319
}
305320
return this.$tc('components.campCreate.campCreateStep2.prototypeHintSelected')
306321
}
307322
},
308323
prototypePreview() {
309324
if (
310-
this.localCamp.campPrototype === 'none' ||
311-
this.localCamp.campPrototype === 'other'
325+
this.selectedPrototypeValue === 'none' ||
326+
this.selectedPrototypeValue === 'other'
312327
) {
313328
return null
314329
}
315-
if (this.localCamp.campPrototype) {
330+
if (this.localCamp?.campPrototype) {
316331
return this.api.get(this.localCamp.campPrototype)
317332
}
318333
return null
@@ -335,7 +350,7 @@ export default {
335350
},
336351
},
337352
watch: {
338-
'localCamp.campPrototype'(newPrototype) {
353+
selectedPrototypeValue(newPrototype) {
339354
if (newPrototype === 'other') {
340355
this.$nextTick(() => {
341356
if (this.$refs.clipboardInfoDialog) {

frontend/src/views/Camps.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
<v-list-item>
2121
<v-list-item-content />
2222
<v-list-item-action>
23-
<button-add icon="mdi-plus" :to="{ name: 'camps/create' }">
23+
<button-add
24+
data-testid="create-camp-button"
25+
icon="mdi-plus"
26+
:to="{ name: 'camps/create' }"
27+
>
2428
{{ $tc('views.camps.create') }}
2529
</button-add>
2630
</v-list-item-action>

0 commit comments

Comments
 (0)