@windward/games 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/components/content/blocks/crosswordPuzzle/CrosswordPuzzle.vue +10 -3
- package/components/content/blocks/flashcards/CardFace.vue +2 -1
- package/components/content/blocks/flashcards/Flashcard.vue +15 -5
- package/components/content/blocks/multipleChoice/MultipleChoice.vue +90 -41
- package/components/settings/FlashCardSlidesManager.vue +88 -0
- package/i18n/en-US/components/content/blocks/crossword.ts +4 -0
- package/i18n/en-US/components/content/blocks/multiple_choice.ts +1 -0
- package/i18n/en-US/components/settings/flashcard.ts +5 -0
- package/i18n/es-ES/components/content/blocks/crossword.ts +4 -0
- package/i18n/es-ES/components/content/blocks/flashcard.ts +1 -0
- package/i18n/es-ES/components/content/blocks/multiple_choice.ts +1 -0
- package/i18n/es-ES/components/settings/flashcard.ts +5 -0
- package/i18n/sv-SE/components/content/blocks/crossword.ts +4 -0
- package/i18n/sv-SE/components/content/blocks/flashcard.ts +1 -0
- package/i18n/sv-SE/components/content/blocks/multiple_choice.ts +1 -0
- package/i18n/sv-SE/components/settings/flashcard.ts +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -33,7 +33,15 @@
|
|
|
33
33
|
)
|
|
34
34
|
}}
|
|
35
35
|
</p>
|
|
36
|
-
<p>
|
|
36
|
+
<p>
|
|
37
|
+
{{
|
|
38
|
+
render
|
|
39
|
+
? $t(
|
|
40
|
+
'windward.games.components.content.blocks.crossword.error.unable_to_load_student'
|
|
41
|
+
)
|
|
42
|
+
: error
|
|
43
|
+
}}
|
|
44
|
+
</p>
|
|
37
45
|
</v-alert>
|
|
38
46
|
<div
|
|
39
47
|
v-if="!error"
|
|
@@ -284,7 +292,6 @@ export default {
|
|
|
284
292
|
)
|
|
285
293
|
}
|
|
286
294
|
}
|
|
287
|
-
|
|
288
295
|
// this is true if render is toggled back to true
|
|
289
296
|
if (generate && this.error === '') {
|
|
290
297
|
this.generateGrid(this.wordMap)
|
|
@@ -443,7 +450,7 @@ export default {
|
|
|
443
450
|
|
|
444
451
|
if (grid.length > MATRIX_LENGTH) {
|
|
445
452
|
this.error = this.$t(
|
|
446
|
-
'windward.games.components.content.blocks.crossword.error.
|
|
453
|
+
'windward.games.components.content.blocks.crossword.error.unable_to_load_editor'
|
|
447
454
|
)
|
|
448
455
|
return false
|
|
449
456
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-container
|
|
3
|
+
:key="updateCardKey"
|
|
3
4
|
style="height: 100%"
|
|
4
5
|
class="div-container"
|
|
5
|
-
:key="updateCardKey"
|
|
6
6
|
>
|
|
7
7
|
<v-card
|
|
8
|
-
|
|
9
|
-
@click="toggleCard"
|
|
8
|
+
ref="cardFront"
|
|
10
9
|
v-show="side"
|
|
10
|
+
outlined
|
|
11
11
|
:class="cardClass"
|
|
12
12
|
style="height: 90%"
|
|
13
|
+
@keyup.enter="toggleCard"
|
|
14
|
+
@click="toggleCard"
|
|
13
15
|
>
|
|
14
16
|
<v-card-text class="fill-height">
|
|
15
17
|
<CardFace
|
|
@@ -20,11 +22,13 @@
|
|
|
20
22
|
</v-card-text>
|
|
21
23
|
</v-card>
|
|
22
24
|
<v-card
|
|
23
|
-
|
|
24
|
-
@click="toggleCard"
|
|
25
|
+
ref="cardBack"
|
|
25
26
|
v-show="!side"
|
|
27
|
+
outlined
|
|
26
28
|
:class="cardClass"
|
|
27
29
|
style="height: 90%"
|
|
30
|
+
@keyup.enter="toggleCard"
|
|
31
|
+
@click="toggleCard"
|
|
28
32
|
>
|
|
29
33
|
<v-card-title class="card-title">
|
|
30
34
|
<v-row align="center" justify="center">{{
|
|
@@ -118,6 +122,12 @@ export default {
|
|
|
118
122
|
this.side = !this.side
|
|
119
123
|
// update container with correct side
|
|
120
124
|
this.updateCardKey = Crypto.id()
|
|
125
|
+
this.$nextTick(() => {
|
|
126
|
+
const target = this.side
|
|
127
|
+
? this.$refs.cardFront
|
|
128
|
+
: this.$refs.cardBack
|
|
129
|
+
target.$el.focus()
|
|
130
|
+
})
|
|
121
131
|
},
|
|
122
132
|
},
|
|
123
133
|
}
|
|
@@ -68,9 +68,13 @@
|
|
|
68
68
|
outlined
|
|
69
69
|
tile
|
|
70
70
|
@click="onChooseAnswer(answer, question)"
|
|
71
|
+
@keyup.enter="onChooseAnswer(answer, question)"
|
|
71
72
|
>
|
|
72
73
|
<div class="d-flex justify-space-between">
|
|
73
|
-
<p
|
|
74
|
+
<p
|
|
75
|
+
class="mb-0"
|
|
76
|
+
:aria-labelledby="answer.value"
|
|
77
|
+
>
|
|
74
78
|
{{
|
|
75
79
|
getCharacter(question, answer) +
|
|
76
80
|
'. ' +
|
|
@@ -79,6 +83,24 @@
|
|
|
79
83
|
</p>
|
|
80
84
|
<div>
|
|
81
85
|
<v-icon
|
|
86
|
+
v-if="
|
|
87
|
+
handleInformationOutline(
|
|
88
|
+
question,
|
|
89
|
+
answer
|
|
90
|
+
) !== undefined
|
|
91
|
+
"
|
|
92
|
+
:ref="
|
|
93
|
+
'icon-information-' +
|
|
94
|
+
question.id +
|
|
95
|
+
'-' +
|
|
96
|
+
answer.id
|
|
97
|
+
"
|
|
98
|
+
tabindex="0"
|
|
99
|
+
:aria-label="
|
|
100
|
+
$t(
|
|
101
|
+
'windward.games.components.content.blocks.multiple_choice.information'
|
|
102
|
+
)
|
|
103
|
+
"
|
|
82
104
|
:class="
|
|
83
105
|
handleInformationClass(
|
|
84
106
|
question,
|
|
@@ -86,7 +108,10 @@
|
|
|
86
108
|
)
|
|
87
109
|
"
|
|
88
110
|
@click="
|
|
89
|
-
onAnswerDescription(
|
|
111
|
+
onAnswerDescription(
|
|
112
|
+
question,
|
|
113
|
+
answer
|
|
114
|
+
)
|
|
90
115
|
"
|
|
91
116
|
>{{
|
|
92
117
|
handleInformationOutline(
|
|
@@ -105,6 +130,7 @@
|
|
|
105
130
|
<v-col cols="12" md="12">
|
|
106
131
|
<v-row class="d-flex justify-center">
|
|
107
132
|
<v-btn
|
|
133
|
+
:ref="'btn-hint-' + question.id"
|
|
108
134
|
color="primary"
|
|
109
135
|
text
|
|
110
136
|
elevation="0"
|
|
@@ -172,7 +198,6 @@
|
|
|
172
198
|
:trigger="false"
|
|
173
199
|
@click:outside="close"
|
|
174
200
|
@click:close="close"
|
|
175
|
-
@keydown.esc="close"
|
|
176
201
|
>
|
|
177
202
|
<template #title>
|
|
178
203
|
<div v-if="hint">
|
|
@@ -240,14 +265,14 @@ export default {
|
|
|
240
265
|
data() {
|
|
241
266
|
return {
|
|
242
267
|
updateKey: 0,
|
|
243
|
-
completedItems: [],
|
|
244
268
|
dialog: false,
|
|
245
269
|
hint: false,
|
|
246
270
|
hintText: '',
|
|
247
271
|
answerDescriptionModal: false,
|
|
248
272
|
answerDescription: '',
|
|
249
273
|
studentResponses: [],
|
|
250
|
-
|
|
274
|
+
activeQuestion: '',
|
|
275
|
+
activeAnswer: '',
|
|
251
276
|
}
|
|
252
277
|
},
|
|
253
278
|
computed: {
|
|
@@ -257,8 +282,8 @@ export default {
|
|
|
257
282
|
enrollment: 'enrollment/get',
|
|
258
283
|
}),
|
|
259
284
|
completedAmount() {
|
|
260
|
-
if (this.
|
|
261
|
-
return _.flatten(this.
|
|
285
|
+
if (this.studentResponses) {
|
|
286
|
+
return _.flatten(this.studentResponses).length
|
|
262
287
|
}
|
|
263
288
|
},
|
|
264
289
|
totalAmountQuestions() {
|
|
@@ -269,7 +294,7 @@ export default {
|
|
|
269
294
|
completedPercent() {
|
|
270
295
|
if (
|
|
271
296
|
this.block.metadata.config.questions.length > 0 &&
|
|
272
|
-
this.
|
|
297
|
+
this.studentResponses.length > 0
|
|
273
298
|
) {
|
|
274
299
|
return (this.completedAmount / this.totalAmountQuestions) * 100
|
|
275
300
|
}
|
|
@@ -277,41 +302,42 @@ export default {
|
|
|
277
302
|
},
|
|
278
303
|
},
|
|
279
304
|
methods: {
|
|
280
|
-
onAnswerDescription(question) {
|
|
305
|
+
onAnswerDescription(question, answer) {
|
|
306
|
+
this.activeQuestion = question
|
|
307
|
+
this.activeAnswer = answer
|
|
281
308
|
//launches modal and displays anwer description
|
|
282
309
|
this.dialog = true
|
|
283
310
|
this.answerDescriptionModal = true
|
|
284
311
|
this.answerDescription = question.answer_description
|
|
285
312
|
},
|
|
286
313
|
onChooseAnswer(answer, question) {
|
|
287
|
-
|
|
288
|
-
this.studentResponses.find(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
//
|
|
314
|
+
// check to see if student already answered this question
|
|
315
|
+
let studentResponse = this.studentResponses.find(
|
|
316
|
+
(obj) => obj.id === question.id
|
|
317
|
+
)
|
|
318
|
+
// if there is no student response for this question or there no student responses to any of the questions
|
|
319
|
+
if (
|
|
320
|
+
_.isEmpty(this.studentResponses) ||
|
|
321
|
+
_.isEmpty(studentResponse)
|
|
322
|
+
) {
|
|
323
|
+
// get question and answer index to update the answer directly
|
|
324
|
+
// on block.metadata.config.questions to prevent buggy behavior
|
|
325
|
+
const questionIndex =
|
|
326
|
+
this.block.metadata.config.questions.findIndex(
|
|
327
|
+
(q) => q.id === question.id
|
|
328
|
+
)
|
|
329
|
+
const answerIndex = this.block.metadata.config.questions[
|
|
330
|
+
questionIndex
|
|
331
|
+
].answer_options.findIndex((a) => a.id === answer.id)
|
|
332
|
+
// lets html side know which answer was chosen, this is important in determine css
|
|
333
|
+
this.block.metadata.config.questions[
|
|
334
|
+
questionIndex
|
|
335
|
+
].answer_options[answerIndex].chosen = true
|
|
336
|
+
// clones question block to break reference
|
|
297
337
|
const clonedQuestion = _.cloneDeep(question)
|
|
298
338
|
clonedQuestion.student_response = answer
|
|
299
339
|
|
|
300
|
-
if (answer.correctAnswer === true) {
|
|
301
|
-
clonedQuestion.isStudentCorrect = true
|
|
302
|
-
} else {
|
|
303
|
-
clonedQuestion.isStudentCorrect = false
|
|
304
|
-
}
|
|
305
|
-
|
|
306
340
|
this.studentResponses.push(clonedQuestion)
|
|
307
|
-
// ensure the object is not already in the completed items array if not push into the array
|
|
308
|
-
const questionDone = this.completedItems.find(
|
|
309
|
-
(item) => item === question
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
if (!questionDone) {
|
|
313
|
-
this.completedItems.push(question)
|
|
314
|
-
}
|
|
315
341
|
|
|
316
342
|
this.updateKey = Crypto.id()
|
|
317
343
|
}
|
|
@@ -365,6 +391,7 @@ export default {
|
|
|
365
391
|
}
|
|
366
392
|
}
|
|
367
393
|
)
|
|
394
|
+
// check if student already responded
|
|
368
395
|
if (studentsQuestionResponse) {
|
|
369
396
|
// requirements for correct and chosen
|
|
370
397
|
if (
|
|
@@ -380,7 +407,12 @@ export default {
|
|
|
380
407
|
return 'mdi-check-circle-outline'
|
|
381
408
|
}
|
|
382
409
|
// requirements for wrong and chosen
|
|
383
|
-
if (
|
|
410
|
+
if (
|
|
411
|
+
answer.id ===
|
|
412
|
+
studentsQuestionResponse.student_response.id &&
|
|
413
|
+
answer.correctAnswer !== true &&
|
|
414
|
+
answer.chosen === true
|
|
415
|
+
) {
|
|
384
416
|
return 'mdi-close-circle'
|
|
385
417
|
}
|
|
386
418
|
}
|
|
@@ -461,12 +493,12 @@ export default {
|
|
|
461
493
|
return letters[answerIndex]
|
|
462
494
|
},
|
|
463
495
|
onHint(question) {
|
|
496
|
+
this.activeQuestion = question
|
|
464
497
|
// launches dialog modal
|
|
465
498
|
this.dialog = true
|
|
466
499
|
this.hint = true
|
|
467
|
-
// sets text for modal, cannot just reference question.hint in html because
|
|
468
|
-
//
|
|
469
|
-
// when mountCourseCounter so it always shows the last question if referenced question.hint
|
|
500
|
+
// sets text for modal, cannot just reference question.hint in html because the carousel loads
|
|
501
|
+
// all elements regardless of if they are on a different slide so it always shows the last question
|
|
470
502
|
this.hintText = question.hint
|
|
471
503
|
},
|
|
472
504
|
onFifty(question) {
|
|
@@ -505,11 +537,28 @@ export default {
|
|
|
505
537
|
return array
|
|
506
538
|
},
|
|
507
539
|
close() {
|
|
540
|
+
if (this.answerDescriptionModal) {
|
|
541
|
+
this.answerDescriptionModal = false
|
|
542
|
+
this.answerDescription = ''
|
|
543
|
+
const iconButton =
|
|
544
|
+
this.$refs[
|
|
545
|
+
'icon-information-' +
|
|
546
|
+
this.activeQuestion.id +
|
|
547
|
+
'-' +
|
|
548
|
+
this.activeAnswer.id
|
|
549
|
+
][0].$el
|
|
550
|
+
iconButton.focus()
|
|
551
|
+
this.activeAnswer = ''
|
|
552
|
+
this.activeQuestion = ''
|
|
553
|
+
} else if (this.hint) {
|
|
554
|
+
this.hint = false
|
|
555
|
+
this.hintText = ''
|
|
556
|
+
const hintButton =
|
|
557
|
+
this.$refs['btn-hint-' + this.activeQuestion.id][0].$el
|
|
558
|
+
hintButton.focus()
|
|
559
|
+
this.activeQuestion = ''
|
|
560
|
+
}
|
|
508
561
|
this.dialog = false
|
|
509
|
-
this.hint = false
|
|
510
|
-
this.answerDescriptionModal = false
|
|
511
|
-
this.hintText = ''
|
|
512
|
-
this.answerDescription = ''
|
|
513
562
|
},
|
|
514
563
|
},
|
|
515
564
|
}
|
|
@@ -277,15 +277,31 @@
|
|
|
277
277
|
indeterminate
|
|
278
278
|
></v-progress-circular>
|
|
279
279
|
</div>
|
|
280
|
+
<v-container class="pa-4 mb-6">
|
|
281
|
+
<v-row>
|
|
282
|
+
<v-col cols="12">
|
|
283
|
+
<GenerateAIQuestionButton
|
|
284
|
+
:course="course"
|
|
285
|
+
:content="content"
|
|
286
|
+
:block="block"
|
|
287
|
+
question-type="flashcard"
|
|
288
|
+
:replace-existing-mode="replaceExisting"
|
|
289
|
+
@click:generate="onGeneratedFlashcards"
|
|
290
|
+
></GenerateAIQuestionButton>
|
|
291
|
+
</v-col>
|
|
292
|
+
</v-row>
|
|
293
|
+
</v-container>
|
|
280
294
|
</div>
|
|
281
295
|
</template>
|
|
282
296
|
|
|
283
297
|
<script>
|
|
284
298
|
import _ from 'lodash'
|
|
299
|
+
import { mapGetters } from 'vuex'
|
|
285
300
|
import {
|
|
286
301
|
MathExpressionEditor,
|
|
287
302
|
MathLiveWrapper,
|
|
288
303
|
ContentViewer,
|
|
304
|
+
GenerateAIQuestionButton
|
|
289
305
|
} from '@windward/core/utils'
|
|
290
306
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
291
307
|
import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
|
|
@@ -305,11 +321,13 @@ export default {
|
|
|
305
321
|
TextEditor,
|
|
306
322
|
SortableExpansionPanel,
|
|
307
323
|
ImageAssetSettings,
|
|
324
|
+
GenerateAIQuestionButton,
|
|
308
325
|
},
|
|
309
326
|
data() {
|
|
310
327
|
return {
|
|
311
328
|
loading: false,
|
|
312
329
|
valid: true,
|
|
330
|
+
replaceExisting: false,
|
|
313
331
|
}
|
|
314
332
|
},
|
|
315
333
|
beforeMount() {
|
|
@@ -342,6 +360,10 @@ export default {
|
|
|
342
360
|
},
|
|
343
361
|
|
|
344
362
|
computed: {
|
|
363
|
+
...mapGetters({
|
|
364
|
+
course: 'course/get',
|
|
365
|
+
content: 'content/get',
|
|
366
|
+
}),
|
|
345
367
|
defaultCard() {
|
|
346
368
|
return {
|
|
347
369
|
front: {
|
|
@@ -440,6 +462,72 @@ export default {
|
|
|
440
462
|
}
|
|
441
463
|
return htmlString.replace(/(<([^>]+)>)/gi, '')
|
|
442
464
|
},
|
|
465
|
+
// Handler for receiving flashcards from GenerateAIQuestionButton
|
|
466
|
+
onGeneratedFlashcards(activityData, replaceCards) {
|
|
467
|
+
this.loading = true
|
|
468
|
+
try {
|
|
469
|
+
// Now process the activity data
|
|
470
|
+
if (activityData && activityData.metadata &&
|
|
471
|
+
activityData.metadata.config &&
|
|
472
|
+
activityData.metadata.config.cards &&
|
|
473
|
+
Array.isArray(activityData.metadata.config.cards)) {
|
|
474
|
+
|
|
475
|
+
// Save new cards
|
|
476
|
+
const newCards = activityData.metadata.config.cards.map(card => ({
|
|
477
|
+
front: { ...card.front },
|
|
478
|
+
back: { ...card.back },
|
|
479
|
+
side: card.side !== undefined ? card.side : true,
|
|
480
|
+
expand: false
|
|
481
|
+
}))
|
|
482
|
+
|
|
483
|
+
if (replaceCards) {
|
|
484
|
+
// Replace mode: Clear existing cards
|
|
485
|
+
this.block.metadata.config.cards.splice(0, this.block.metadata.config.cards.length)
|
|
486
|
+
|
|
487
|
+
// Add all new cards
|
|
488
|
+
newCards.forEach(card => {
|
|
489
|
+
this.block.metadata.config.cards.push(card)
|
|
490
|
+
})
|
|
491
|
+
} else {
|
|
492
|
+
// Merge mode: Add new cards to existing ones
|
|
493
|
+
newCards.forEach(card => {
|
|
494
|
+
this.block.metadata.config.cards.push(card)
|
|
495
|
+
})
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Update title and instructions if provided and we're in replace mode
|
|
499
|
+
if (replaceCards) {
|
|
500
|
+
if (activityData.metadata.config.title) {
|
|
501
|
+
this.block.metadata.config.title = activityData.metadata.config.title
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (activityData.metadata.config.instructions) {
|
|
505
|
+
this.block.metadata.config.instructions = activityData.metadata.config.instructions
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
this.$toast.success(
|
|
510
|
+
replaceCards
|
|
511
|
+
? this.$t('windward.games.components.settings.flashcard.form.replaced_successfully')
|
|
512
|
+
: this.$t('windward.games.components.settings.flashcard.form.added_successfully'),
|
|
513
|
+
{ duration: 3000 }
|
|
514
|
+
)
|
|
515
|
+
} else {
|
|
516
|
+
this.$toast.error(this.$t('windward.games.components.settings.flashcard.form.invalid_response'), {
|
|
517
|
+
duration: 5000
|
|
518
|
+
})
|
|
519
|
+
}
|
|
520
|
+
} catch (error) {
|
|
521
|
+
// Extract error message from the response
|
|
522
|
+
const errorMessage = error.message || 'Unknown error occurred'
|
|
523
|
+
this.$toast.error(`${this.$t('windward.games.components.settings.flashcard.form.failed_to_process')}: ${errorMessage}`, {
|
|
524
|
+
duration: 5000
|
|
525
|
+
})
|
|
526
|
+
} finally {
|
|
527
|
+
this.loading = false
|
|
528
|
+
}
|
|
529
|
+
}
|
|
443
530
|
},
|
|
444
531
|
}
|
|
445
532
|
</script>
|
|
533
|
+
|
|
@@ -14,6 +14,10 @@ export default {
|
|
|
14
14
|
could_not_generate:
|
|
15
15
|
'Could not generate a {0} by {0} crossword with the supplied words',
|
|
16
16
|
unknown: 'An unknown error occurred during the crossword creation',
|
|
17
|
+
unable_to_load_editor:
|
|
18
|
+
'Unable to generate crossword puzzle. Your current word list may have too many words, words that are too short/long, or insufficient shared letters for crossings. You can edit your word list and try again.',
|
|
19
|
+
unable_to_load_student:
|
|
20
|
+
'Unable to generate crossword puzzle with these words. Please try refreshing the page until it loads successfully or contact support if the issue persists.',
|
|
17
21
|
},
|
|
18
22
|
|
|
19
23
|
play_again: 'Randomize Crossword and Play Again',
|
|
@@ -26,5 +26,10 @@ export default {
|
|
|
26
26
|
'The character count for this field must be less than',
|
|
27
27
|
},
|
|
28
28
|
instructions:"Click on each card to reveal the term's definition. Use the arrows to move through the deck.",
|
|
29
|
+
replace_existing: 'Replace existing flashcards',
|
|
30
|
+
replaced_successfully: 'Flashcards replaced successfully',
|
|
31
|
+
added_successfully: 'New flashcards added successfully',
|
|
32
|
+
invalid_response: 'Invalid response from flashcard generation',
|
|
33
|
+
failed_to_process: 'Failed to process generated flashcards'
|
|
29
34
|
},
|
|
30
35
|
}
|
|
@@ -17,6 +17,10 @@ export default {
|
|
|
17
17
|
'No se pudo generar un crucigrama {0} por {0} con las palabras proporcionadas',
|
|
18
18
|
unknown:
|
|
19
19
|
'Se produjo un error desconocido durante la creación del crucigrama',
|
|
20
|
+
unable_to_load_editor:
|
|
21
|
+
'No se puede generar el crucigrama. Tu lista de palabras actual puede tener demasiadas palabras, palabras demasiado cortas o largas, o suficientes letras compartidas para los cruces. Puedes editar tu lista de palabras e intentarlo de nuevo.',
|
|
22
|
+
unable_to_load_student:
|
|
23
|
+
'No se puede generar un crucigrama con estas palabras. Actualice la página hasta que se cargue correctamente o contacte con el soporte si el problema persiste.',
|
|
20
24
|
},
|
|
21
25
|
|
|
22
26
|
play_again: 'Aleatorizar crucigramas y jugar de nuevo',
|
|
@@ -26,5 +26,10 @@ export default {
|
|
|
26
26
|
'El número de caracteres para este campo debe ser menor que',
|
|
27
27
|
},
|
|
28
28
|
instructions:"Haga clic en cada tarjeta para revelar la definición del término. Usa las flechas para moverte por el mazo.",
|
|
29
|
+
replace_existing: 'Reemplazar tarjetas existentes',
|
|
30
|
+
replaced_successfully: 'Tarjetas reemplazadas con éxito',
|
|
31
|
+
added_successfully: 'Nuevas tarjetas agregadas con éxito',
|
|
32
|
+
invalid_response: 'Respuesta inválida de la generación de tarjetas',
|
|
33
|
+
failed_to_process: 'Error al procesar las tarjetas generadas'
|
|
29
34
|
},
|
|
30
35
|
}
|
|
@@ -12,6 +12,10 @@ export default {
|
|
|
12
12
|
could_not_generate:
|
|
13
13
|
'Det gick inte att skapa ett {0} gånger {0} korsord med de angivna orden',
|
|
14
14
|
unknown: 'Ett okänt fel inträffade under korsordsskapandet',
|
|
15
|
+
unable_to_load_editor:
|
|
16
|
+
'Det går inte att skapa korsord. Din nuvarande ordlista kan ha för många ord, ord som är för korta/långa eller otillräckliga delade bokstäver för korsningar. Du kan redigera din ordlista och försöka igen.',
|
|
17
|
+
unable_to_load_student:
|
|
18
|
+
'Det går inte att skapa korsord med dessa ord. Försök att uppdatera sidan tills den läses in eller kontakta supporten om problemet kvarstår.',
|
|
15
19
|
},
|
|
16
20
|
|
|
17
21
|
play_again: 'Randomisera korsord och spela igen',
|
|
@@ -26,5 +26,10 @@ export default {
|
|
|
26
26
|
'Teckenantalet för detta fält måste vara mindre än',
|
|
27
27
|
},
|
|
28
28
|
instructions:"Klicka på varje kort för att avslöja termens definition. Använd pilarna för att flytta genom däcket.",
|
|
29
|
+
replace_existing: 'Ersätt befintliga flashcards',
|
|
30
|
+
replaced_successfully: 'Flashkort har ersatts framgångsrikt',
|
|
31
|
+
added_successfully: 'Nya flashkort har lagts till',
|
|
32
|
+
invalid_response: 'Ogiltigt svar från genereringen av flashkort',
|
|
33
|
+
failed_to_process: 'Kunde inte bearbeta genererade flashkort'
|
|
29
34
|
},
|
|
30
35
|
}
|