@ecored-sena/base-kit 0.0.1

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.
Files changed (67) hide show
  1. package/README.md +1 -0
  2. package/package.json +49 -0
  3. package/plugin/components/AccordionRED.vue +78 -0
  4. package/plugin/components/AcordionA.vue +78 -0
  5. package/plugin/components/Audio.vue +20 -0
  6. package/plugin/components/BannerHero.vue +104 -0
  7. package/plugin/components/CarouselCard.vue +70 -0
  8. package/plugin/components/CarouselRED.vue +65 -0
  9. package/plugin/components/Complementario.vue +81 -0
  10. package/plugin/components/Creditos.vue +101 -0
  11. package/plugin/components/Dialogo.vue +30 -0
  12. package/plugin/components/DialogoActividad.vue +274 -0
  13. package/plugin/components/DialogoBurbuja.vue +46 -0
  14. package/plugin/components/DialogoChat.vue +88 -0
  15. package/plugin/components/Footer.vue +42 -0
  16. package/plugin/components/GlobalComponents.js +39 -0
  17. package/plugin/components/Glosario.vue +100 -0
  18. package/plugin/components/ImagenInfografica.vue +100 -0
  19. package/plugin/components/ImagenInfograficaB.vue +68 -0
  20. package/plugin/components/Inicio.vue +128 -0
  21. package/plugin/components/LineaTiempoA.vue +30 -0
  22. package/plugin/components/LineaTiempoB.vue +36 -0
  23. package/plugin/components/LineaTiempoC.vue +95 -0
  24. package/plugin/components/LineaTiempoD.vue +51 -0
  25. package/plugin/components/LineaTiempoE.vue +25 -0
  26. package/plugin/components/ModalA.vue +22 -0
  27. package/plugin/components/PasosA.vue +59 -0
  28. package/plugin/components/PasosB.vue +90 -0
  29. package/plugin/components/Referencias.vue +45 -0
  30. package/plugin/components/ScrollHorizontal.vue +105 -0
  31. package/plugin/components/Separador.vue +12 -0
  32. package/plugin/components/SlyderA.vue +65 -0
  33. package/plugin/components/SlyderB.vue +48 -0
  34. package/plugin/components/SlyderC.vue +53 -0
  35. package/plugin/components/SlyderD.vue +50 -0
  36. package/plugin/components/SlyderE.vue +58 -0
  37. package/plugin/components/SlyderF.vue +141 -0
  38. package/plugin/components/TabsA.vue +44 -0
  39. package/plugin/components/TabsB.vue +40 -0
  40. package/plugin/components/TabsC.vue +39 -0
  41. package/plugin/components/TarjetaAudio.vue +65 -0
  42. package/plugin/components/TimeLineRED.vue +51 -0
  43. package/plugin/components/actividad/ActividadController.vue +34 -0
  44. package/plugin/components/actividad/actividadCompletar/ActividadCompletar.vue +283 -0
  45. package/plugin/components/actividad/actividadCompletar/ActividadCompletarFooter.vue +63 -0
  46. package/plugin/components/actividad/actividadCompletar/ActividadParrafo.vue +218 -0
  47. package/plugin/components/actividad/actividadCompletar/ActividadResultados.vue +215 -0
  48. package/plugin/components/actividad/actividadCuestionario/Actividad.vue +222 -0
  49. package/plugin/components/actividad/actividadCuestionario/ActividadBarraAvance.vue +116 -0
  50. package/plugin/components/actividad/actividadCuestionario/ActividadPregunta.vue +146 -0
  51. package/plugin/components/actividad/actividadCuestionario/ActividadResultados.vue +215 -0
  52. package/plugin/components/audioMixins.js +73 -0
  53. package/plugin/components/componentSlotMixins.js +87 -0
  54. package/plugin/components/dialogoMixins.js +28 -0
  55. package/plugin/components/globalMixins.js +11 -0
  56. package/plugin/components/plantilla/Accesibilidad.vue +101 -0
  57. package/plugin/components/plantilla/AsideMenu.vue +242 -0
  58. package/plugin/components/plantilla/BannerInterno.vue +66 -0
  59. package/plugin/components/plantilla/BannerPrincipal.vue +104 -0
  60. package/plugin/components/plantilla/BarraAvance.vue +379 -0
  61. package/plugin/components/plantilla/Curso.vue +12 -0
  62. package/plugin/components/plantilla/Footer.vue +42 -0
  63. package/plugin/components/plantilla/Header.vue +152 -0
  64. package/plugin/components/plantilla/ScrollHorizontal.vue +105 -0
  65. package/plugin/components/plantillaMixins.js +34 -0
  66. package/plugin/components/slyderMixins.js +18 -0
  67. package/plugin/plugin.js +49 -0
@@ -0,0 +1,274 @@
1
+ <template lang="pug">
2
+ .dialogo
3
+ .dialogo__header.px-3.px-lg-4.py-2.py-lg-3
4
+ .mb-1
5
+ slot(name="nombre-actividad") Arrastrar y soltar
6
+ .h3.mb-0
7
+ slot(name="titulo-actividad") Titulo de actividad - Completa la conversación
8
+ .px-2.py-3.p-lg-4
9
+ .row.g-0
10
+ .col-md-8.dialogo__chat(:ref="`chat-${uid}`")
11
+ .row.g-0.flex-nowrap.dialogo__chat__item.mb-3(v-for="(line, lineIdx) in dialogoComputed")
12
+ .col-auto.dialogo__chat__item__person
13
+ img(:src="line.personaje.img")
14
+ span.text-small(v-html="line.personaje.nombre")
15
+ .col.dialogo__chat__item__message__container
16
+ .dialogo__chat__item__message
17
+ .row.g-0.align-items-center.dialogo__chat__item__message__bubble.dialogo__chat__item__message__bubble--tail
18
+ .col.dialogo__chat__item__message__text.me-2
19
+ .dialogo__chat__item__message__text__eng.h5.mb-0
20
+ template(v-for="(phrase, phraseIdx) in line.textoIng")
21
+ .d-inline.dialogo__chat__item__message__text__drop(
22
+ v-if="phrase === '*'"
23
+ @drop.prevent="onDrop(line.id)"
24
+ @dragenter.prevent="onDragEnter(line.id)"
25
+ @dragleave.prevent="onDragLeave()"
26
+ @dragover.prevent
27
+ :key="`phrase-${line.id}-${phraseIdx}`"
28
+ :ref="`phrase-${line.id}`"
29
+ :class="{'is-active': dropId === line.id}"
30
+ )
31
+ span.dialogo__chat__item__message__text__drop__response(
32
+ v-if="answers[line.id]"
33
+ v-html="answers[line.id].palabra"
34
+ )
35
+ span.dialogo__chat__item__message__text__drop__default(v-else)
36
+ span(v-else :key="`phrase-${line.id}-${phraseIdx}`" v-html="phrase")
37
+ .dialogo__chat__item__message__text__esp.text-small(
38
+ v-if="translations.includes(line.id)"
39
+ )
40
+ hr.my-2
41
+ template(v-for="phrase in line.textoEsp")
42
+ .d-inline.dialogo__chat__item__message__text__drop(
43
+ v-if="phrase === '*'"
44
+ )
45
+ span.dialogo__chat__item__message__text__drop__default
46
+ span(v-else v-html="phrase")
47
+ .col-auto.dialogo__chat__item__message__audio
48
+ Audio(
49
+ :audio="line.audio"
50
+ @audio-hover="mostrarIndicadorAudio = false"
51
+ )
52
+ .d-flex.justify-content-end.me-3
53
+ button.dialogo__chat__item__message__translate-btn.text-small(
54
+ @click="toggleTranslate(line.id)"
55
+ ) Ver traducción
56
+ .col-1
57
+ .col-12.d-md-none
58
+ hr.mb-3.mt-4
59
+ .col.dialogo__words
60
+ .dialogo__words__content
61
+ .dialogo__words__content__explanation
62
+ slot(name="descripcion-actividad") Arrastra y suelta las palabras en la conversación
63
+ .dialogo__words__content__words__container.mt-md-3.mb-3.mb-md-0(v-if="wordsToShow.length")
64
+ template(v-if="touchScreen")
65
+ .h5.dialogo__words__word(
66
+ v-for="word in wordsToShow"
67
+ :key="`word-${word.id}`"
68
+ :ref="`word-${word.id}`"
69
+ @touchstart.prevent="onTouchStart(word.id)"
70
+ @touchmove.prevent="onTouchMove($event,word.id)"
71
+ @touchend.prevent="onTouchEnd($event,word.id)"
72
+ @touchcancel.prevent="onTouchCancel($event,word.id)"
73
+ :class="{'grabbing': word.id === dragId}"
74
+ v-html="word.palabra"
75
+ )
76
+ template(v-else)
77
+ .h5.dialogo__words__word(
78
+ v-for="word in wordsToShow"
79
+ :key="`word-${word.id}`"
80
+ @dragstart="onStartDrag(word.id)"
81
+ @dragend="onEndDrag()"
82
+ draggable
83
+ :class="{'grabbing': word.id === dragId}"
84
+ v-html="word.palabra"
85
+ )
86
+ .dialogo__words__footer
87
+ .dialogo__score.mt-3(v-if="score")
88
+ .dialogo__score.p-3.approved(v-if="score === 'approved'")
89
+ .row.align-items-center
90
+ .col-2
91
+ .dialogo__score__icon
92
+ img(src="@/assets/template/green-check.svg")
93
+ .col
94
+ slot.dialogo__score__text.h5.mb-0(name="feedback-correcto") ¡Muy bien!
95
+
96
+ .dialogo__score.px-3.py-2.disapproved(v-if="score === 'disapproved'")
97
+ .row.align-items-center
98
+ .col-2
99
+ .dialogo__score__icon
100
+ img(src="@/assets/template/red-x.svg")
101
+ .col
102
+ slot.dialogo__score__text.h5.mb-0(name="feedback-incorrecto") Incorrecto
103
+
104
+ .dialogo__words__footer__actions.text-end.mt-3(
105
+ v-if="Object.values(answers).length === words.length"
106
+ )
107
+ button(v-if="score === null" @click="onCheck") Comprobar
108
+ button(v-else-if="score === 'disapproved'" @click="reset") Prueba otra vez
109
+
110
+ </template>
111
+
112
+ <script>
113
+ import Audio from './Audio.vue'
114
+ import dialogoMixins from './dialogoMixins'
115
+ export default {
116
+ name: 'DialogoActividad',
117
+ components: {
118
+ Audio,
119
+ },
120
+ mixins: [dialogoMixins],
121
+ props: {
122
+ dialogo: {
123
+ type: Object,
124
+ default: () => ({}),
125
+ },
126
+ },
127
+ data: () => ({
128
+ uid: Math.floor(Math.random() * 10 ** 10),
129
+ touchScreen: false,
130
+ dragId: null,
131
+ dropId: null,
132
+ answers: {},
133
+ translations: [],
134
+ score: null,
135
+ }),
136
+ computed: {
137
+ dialogoComputed() {
138
+ return this.dialogoMerge(this.dialogo, true)
139
+ },
140
+ words() {
141
+ return this.shuffle(
142
+ this.dialogoComputed
143
+ .map(line => ({ palabra: line.palabra, id: line.id }))
144
+ .filter(line => line.palabra),
145
+ )
146
+ },
147
+ answerWordsIds() {
148
+ return Object.values(this.answers).map(answer => answer.dragId)
149
+ },
150
+ wordsToShow() {
151
+ return this.words.filter(word => !this.answerWordsIds.includes(word.id))
152
+ },
153
+ },
154
+ created() {
155
+ this.touchScreen = 'ontouchstart' in document.documentElement
156
+ },
157
+ methods: {
158
+ // DRAG EVENTS
159
+ onStartDrag(dragId) {
160
+ this.dragId = dragId
161
+ },
162
+ onEndDrag() {
163
+ this.dragId = null
164
+ },
165
+ onDrop(dropId) {
166
+ if (!this.dragId) return
167
+ this.$set(this.answers, dropId, {
168
+ dragId: this.dragId,
169
+ dropId: dropId,
170
+ palabra: this.words.find(wordObj => wordObj.id === this.dragId).palabra,
171
+ })
172
+ this.dropId = null
173
+ },
174
+ onDragEnter(dropId) {
175
+ this.dropId = dropId
176
+ },
177
+ onDragLeave() {
178
+ this.dropId = null
179
+ },
180
+ // TOUCH EVENTS
181
+ onTouchStart(dragId) {
182
+ const dragElm = this.$refs[`word-${dragId}`][0]
183
+ dragElm.classList.add('touch-drag')
184
+ },
185
+ onTouchMove(event, dragId) {
186
+ const dragElm = this.$refs[`word-${dragId}`][0]
187
+ const dragElmRect = dragElm.getBoundingClientRect()
188
+ const touch = event.touches[0]
189
+ dragElm.style.top = `${touch.clientY - dragElmRect.height / 2}px`
190
+ dragElm.style.left = `${touch.clientX - dragElmRect.width / 2}px`
191
+ },
192
+ onTouchEnd(event, dragId) {
193
+ if (event.changedTouches.length > 1) {
194
+ this.resetDragElm(dragId)
195
+ return
196
+ }
197
+ const contElm = this.$refs[`chat-${this.uid}`]
198
+ const contElmRect = contElm.getBoundingClientRect()
199
+ const touch = event.changedTouches[0]
200
+ const isInsideContX =
201
+ touch.clientX > contElmRect.x &&
202
+ touch.clientX < contElmRect.x + contElmRect.width
203
+ const isInsideContY =
204
+ touch.clientY > contElmRect.y &&
205
+ touch.clientY < contElmRect.y + contElmRect.height
206
+
207
+ if (!isInsideContX || !isInsideContY) {
208
+ this.resetDragElm(dragId)
209
+ return
210
+ }
211
+
212
+ let dropId
213
+ const isTouching = this.words.some(wordObj => {
214
+ const drop = this.$refs[`phrase-${wordObj.id}`][0]
215
+ const dropRect = drop.getBoundingClientRect()
216
+ const extraDrop = 25
217
+ const isInsideX =
218
+ touch.clientX > dropRect.x - extraDrop &&
219
+ touch.clientX < dropRect.x + dropRect.width + extraDrop
220
+ const isInsideY =
221
+ touch.clientY > dropRect.y - extraDrop &&
222
+ touch.clientY < dropRect.y + dropRect.height + extraDrop
223
+
224
+ if (isInsideX && isInsideY) {
225
+ dropId = wordObj.id
226
+ }
227
+ return isInsideX && isInsideY
228
+ })
229
+ if (isTouching) {
230
+ this.$set(this.answers, dropId, {
231
+ dragId: dragId,
232
+ dropId: dropId,
233
+ palabra: this.words.find(wordObj => wordObj.id === dragId).palabra,
234
+ })
235
+ }
236
+ this.resetDragElm(dragId)
237
+ },
238
+ onTouchCancel(dragId) {
239
+ this.resetDragElm(dragId)
240
+ },
241
+ resetDragElm(id) {
242
+ const dragElm = this.$refs[`word-${id}`][0]
243
+ dragElm.classList.remove('touch-drag')
244
+ },
245
+ // HELPERS
246
+ toggleTranslate(id) {
247
+ if (this.translations.includes(id)) {
248
+ this.translations = this.translations.filter(tId => tId !== id)
249
+ } else {
250
+ this.translations.push(id)
251
+ }
252
+ },
253
+ onCheck() {
254
+ const finalCheck = Object.values(this.answers).every(
255
+ answer => answer.dragId === answer.dropId,
256
+ )
257
+ this.score = finalCheck ? 'approved' : 'disapproved'
258
+ },
259
+ reset() {
260
+ this.answers = {}
261
+ this.score = null
262
+ },
263
+ shuffle(array) {
264
+ for (let i = array.length - 1; i > 0; i--) {
265
+ let j = Math.floor(Math.random() * (i + 1))
266
+ ;[array[i], array[j]] = [array[j], array[i]]
267
+ }
268
+ return array
269
+ },
270
+ },
271
+ }
272
+ </script>
273
+
274
+ <style lang="sass"></style>
@@ -0,0 +1,46 @@
1
+ <template lang="pug">
2
+ .row.g-0.flex-nowrap.dialogo__chat__item
3
+ .col-auto.dialogo__chat__item__person(
4
+ v-if='dialogoItem.personaje && dialogoItem.personaje.img && dialogoItem.personaje.nombre'
5
+ )
6
+ img(:src='dialogoItem.personaje.img')
7
+ span.text-small(v-html='dialogoItem.personaje.nombre')
8
+ .col.dialogo__chat__item__message__container
9
+ .dialogo__chat__item__message
10
+ .row.g-0.align-items-center.dialogo__chat__item__message__bubble(
11
+ :class='{ "dialogo__chat__item__message__bubble--tail": dialogoItem.personaje && dialogoItem.personaje.img && dialogoItem.personaje.nombre }'
12
+ )
13
+ .col.dialogo__chat__item__message__text
14
+ .dialogo__chat__item__message__text__eng.h5.mb-0
15
+ div(v-html='dialogoItem.textoIng')
16
+ .dialogo__chat__item__message__text__esp.text-small(
17
+ v-if="showTranslation"
18
+ )
19
+ hr.my-2
20
+ div(v-html='dialogoItem.textoEsp')
21
+ .col-auto.dialogo__chat__item__message__audio.ms-2(v-if='dialogoItem.audio')
22
+ Audio(:audio='dialogoItem.audio')
23
+ .d-flex.justify-content-end.me-3
24
+ button.dialogo__chat__item__message__translate-btn.text-small(
25
+ @click='showTranslation = !showTranslation'
26
+ ) {{ showTranslation ? "Ocultar" : "Ver" }} traducción
27
+ .col-1
28
+
29
+ </template>
30
+
31
+ <script>
32
+ export default {
33
+ name: 'DialogoBurbuja',
34
+ props: {
35
+ dialogoItem: {
36
+ type: Object,
37
+ default: () => ({}),
38
+ },
39
+ },
40
+ data: () => ({
41
+ showTranslation: false,
42
+ }),
43
+ }
44
+ </script>
45
+
46
+ <style lang="sass" scoped></style>
@@ -0,0 +1,88 @@
1
+ <template lang="pug">
2
+ .dialogoChat.p-5
3
+ .row.justify-content-center.align-items-center.g-0
4
+ .col-md-12
5
+ .row.g-0.flex-nowrap.dialogoChat__chat__item.mb-3(v-for="(line, lineIdx) in dialogoComputed")
6
+ .col-auto.dialogoChat__chat__item__person
7
+ img(:src="line.personaje.img")
8
+ span.text-small(v-html="line.personaje.nombre")
9
+ .col.dialogoChat__chat__item__message__container
10
+ .dialogoChat__chat__item__message
11
+ .row.g-0.align-items-center.dialogoChat__chat__item__message__bubble
12
+ .col.dialogoChat__chat__item__message__text.me-2
13
+ .dialogoChat__chat__item__message__text__eng.h5.mb-0
14
+ template(v-for="(phrase, phraseIdx) in line.textoIng")
15
+ .d-inline.dialogoChat__chat__item__message__text__drop(
16
+ v-if="phrase === '*'"
17
+ )
18
+ span.dialogoChat__chat__item__message__text__drop__response(
19
+ v-if="answers[line.id]"
20
+ v-html="answers[line.id].palabra"
21
+ )
22
+ span.dialogoChat__chat__item__message__text__drop__default(v-else)
23
+ span(v-else :key="`phrase-${line.id}-${phraseIdx}`" v-html="phrase")
24
+ .dialogoChat__chat__item__message__text__esp.text-small(
25
+ v-if="translations.includes(line.id)"
26
+ )
27
+ .col-auto.dialogoChat__chat__item__message__audio
28
+ Audio(
29
+ :audio="line.audio"
30
+ @audio-hover="mostrarIndicadorAudio = false"
31
+ )
32
+
33
+
34
+ </template>
35
+
36
+ <script>
37
+ import Audio from './Audio.vue'
38
+
39
+ const dialogo = {
40
+ type: Object,
41
+ default: () => ({}),
42
+ }
43
+
44
+ export default {
45
+ name: 'Chat',
46
+ components: {
47
+ Audio,
48
+ },
49
+ props: {
50
+ dialogo,
51
+ },
52
+ data: () => ({
53
+ uid: Math.floor(Math.random() * 10 ** 10),
54
+ touchScreen: false,
55
+ dragId: null,
56
+ dropId: null,
57
+ answers: {},
58
+ translations: [],
59
+ score: null,
60
+ }),
61
+ computed: {
62
+ dialogoComputed() {
63
+ if (!this.dialogo.dialogo) return []
64
+ return this.dialogo.dialogo.map((line, idx) => ({
65
+ ...line,
66
+ id: this.uid + idx + 1,
67
+ textoIng: this.splitPhrase(line.textoIng),
68
+ personaje: this.dialogo.personajes.find(
69
+ personaje => personaje.nombre === line.personaje,
70
+ ),
71
+ }))
72
+ },
73
+ },
74
+
75
+ methods: {
76
+ // HELPERS
77
+ splitPhrase(phrase) {
78
+ return phrase
79
+ .replace(/^\s+|\s+$/g, '&nbsp;')
80
+ .replace('***', '___*___')
81
+ .split('___')
82
+ .filter(Boolean)
83
+ },
84
+ },
85
+ }
86
+ </script>
87
+
88
+ <style lang="sass"></style>
@@ -0,0 +1,42 @@
1
+ <template lang="pug">
2
+ footer.container.footer.tarjeta.p-3.px-sm-5.py-sm-4(:class="[allRound && 'footer__all-round']")
3
+ .row.align-items-center.justify-content-center
4
+ .col-auto.mb-2.mb-sm-0
5
+ img(src="@/assets/bullets/cc.svg")
6
+ .col-12.col-sm
7
+ p.mb-0.text-small Este material puede ser distribuido, copiado y exhibido por terceros si se muestra en los créditos. No se puede obtener ningún beneficio comercial y las obras derivadas tienen que estar bajo los mismos términos de la licencia que el trabajo original.
8
+
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ name: 'Footer',
14
+ props: {
15
+ allRound: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ },
20
+ computed: {
21
+ versiones() {
22
+ return {
23
+ base: this.$package.version,
24
+ pkg: this.$package.dependencies['ecored-base-pkg'],
25
+ }
26
+ },
27
+ },
28
+ }
29
+ </script>
30
+
31
+ <style lang="sass">
32
+ .footer
33
+ background-color: $color-sistema-d
34
+ border-bottom-right-radius: 0 !important
35
+ border-bottom-left-radius: 0 !important
36
+ &__all-round
37
+ border-bottom-right-radius: 20px !important
38
+ border-bottom-left-radius: 20px !important
39
+ p
40
+ color: $color-sistema-b
41
+ line-height: 1.2em
42
+ </style>
@@ -0,0 +1,39 @@
1
+ export { default as AsideMenu } from './plantilla/AsideMenu.vue'
2
+ export { default as Header } from './plantilla/Header.vue'
3
+ export { default as BarraAvance } from './plantilla/BarraAvance.vue'
4
+ export { default as BannerInterno } from './plantilla/BannerInterno.vue'
5
+ export { default as Accesibilidad } from './plantilla/Accesibilidad.vue'
6
+ export { default as AccordionRED } from './AccordionRED.vue'
7
+ export { default as TimeLineRED } from './TimeLineRED.vue'
8
+ export { default as CarouselRED } from './CarouselRED.vue'
9
+ export { default as Separador } from './Separador.vue'
10
+ export { default as Footer } from './Footer.vue'
11
+ export { default as BannerHero } from './BannerHero.vue'
12
+ export { default as Inicio } from './Inicio.vue'
13
+ export { default as ScrollHorizontal } from './ScrollHorizontal.vue'
14
+ export { default as TabsC } from './TabsC.vue'
15
+ export { default as TabsB } from './TabsB.vue'
16
+ export { default as TabsA } from './TabsA.vue'
17
+ export { default as CarouselCard } from './CarouselCard.vue'
18
+ export { default as AcordionA } from './AcordionA.vue'
19
+ export { default as ImagenInfografica } from './ImagenInfografica.vue'
20
+ export { default as ImagenInfograficaB } from './ImagenInfograficaB.vue'
21
+ export { default as Audio } from './Audio.vue'
22
+ export { default as TarjetaAudio } from './TarjetaAudio.vue'
23
+ export { default as SlyderA } from './SlyderA.vue'
24
+ export { default as PasosA } from './PasosA.vue'
25
+ export { default as PasosB } from './PasosB.vue'
26
+ export { default as LineaTiempoA } from './LineaTiempoA.vue'
27
+ export { default as LineaTiempoB } from './LineaTiempoB.vue'
28
+ export { default as LineaTiempoC } from './LineaTiempoC.vue'
29
+ export { default as LineaTiempoD } from './LineaTiempoD.vue'
30
+ export { default as LineaTiempoE } from './LineaTiempoE.vue'
31
+ export { default as SlyderF } from './SlyderF.vue'
32
+ export { default as SlyderB } from './SlyderB.vue'
33
+ export { default as SlyderC } from './SlyderC.vue'
34
+ export { default as SlyderD } from './SlyderD.vue'
35
+ export { default as SlyderE } from './SlyderE.vue'
36
+ export { default as ModalA } from './ModalA.vue'
37
+ export { default as Dialogo } from './Dialogo.vue'
38
+ export { default as DialogoActividad } from './DialogoActividad.vue'
39
+ export { default as DialogoBurbuja } from './DialogoBurbuja.vue'
@@ -0,0 +1,100 @@
1
+ <template lang="pug">
2
+ .curso-main-container.glosario
3
+ BannerInterno(icono="fas fa-atlas" titulo="Glosario")
4
+ .container.tarjeta.tarjeta--blanca.p-4.p-md-5.mb-5
5
+ .glosario__letra-item.mb-2(v-for="letra in orderedData" :key="'letra-'+letra.letra")
6
+ .glosario__letra-item__letra.me-4
7
+ .glosario__letra-item__letra__icono
8
+ span {{letra.letra}}
9
+ .glosario__letra-item__texto
10
+ p.mb-3(v-for="termino in letra.terminos")
11
+ strong
12
+ i.lista-ul__vineta
13
+ strong(v-html="termino.terminoHtml || termino.termino")
14
+ strong :
15
+ span(v-html="termino.significado")
16
+ </template>
17
+
18
+ <script>
19
+ import plantillaMixins from './plantillaMixins'
20
+ export default {
21
+ name: 'Glosario',
22
+ mixins: [plantillaMixins],
23
+ computed: {
24
+ glosarioData() {
25
+ return this.$config.glosario
26
+ },
27
+ orderedData() {
28
+ const newGlosarioData = [...this.glosarioData]
29
+ newGlosarioData.forEach(element => {
30
+ element.significado =
31
+ element.significado.charAt(0).toLowerCase() +
32
+ element.significado.slice(1)
33
+ })
34
+
35
+ const sortedData = [...newGlosarioData].reduce((r, e) => {
36
+ const letra = this.quitarAcentos(e.termino.toLowerCase())[0]
37
+ if (!r[letra]) r[letra] = { letra, terminos: [e] }
38
+ else r[letra].terminos.push(e)
39
+ return r
40
+ }, {})
41
+
42
+ const soloLetras = Object.keys(sortedData).sort()
43
+ const newSortedData = []
44
+
45
+ soloLetras.forEach(element => {
46
+ const letraObj = sortedData[element]
47
+ let terminos = letraObj.terminos
48
+
49
+ if (terminos.length > 1) {
50
+ const terminosOrdenados = []
51
+ const soloTerminos = letraObj.terminos
52
+ .map(termObj => termObj.termino)
53
+ .sort((a, b) => {
54
+ const an = this.quitarAcentos(a).toLowerCase()
55
+ const bn = this.quitarAcentos(b).toLowerCase()
56
+ if (an < bn) return -1
57
+ if (bn < an) return 1
58
+ return 0
59
+ })
60
+ soloTerminos.forEach(term => {
61
+ terminosOrdenados.push(
62
+ terminos.find(termino => termino.termino === term),
63
+ )
64
+ })
65
+ terminos = terminosOrdenados
66
+ }
67
+ newSortedData.push({
68
+ letra: letraObj.letra.toUpperCase(),
69
+ terminos: terminos,
70
+ })
71
+ })
72
+ return newSortedData
73
+ },
74
+ },
75
+ }
76
+ </script>
77
+
78
+ <style lang="sass">
79
+ .glosario
80
+ &__letra-item
81
+ display: flex
82
+ &__texto
83
+ padding-top: 5px
84
+ &__letra
85
+ &__icono
86
+ width: 32px
87
+ height: 32px
88
+ position: relative
89
+ line-height: 1em
90
+ border-radius: 50%
91
+ background-color: $color-sistema-d
92
+
93
+ span
94
+ position: absolute
95
+ left: 50%
96
+ top: 50%
97
+ transform: translate(-50%,-50%)
98
+ font-size: 1.1em
99
+ font-weight: $base-black-font-weight
100
+ </style>
@@ -0,0 +1,100 @@
1
+ <template lang="pug">
2
+ .img-infografica
3
+ .img-infografica__img(:ref="'img-ref-'+mainId")
4
+ slot(name="imagen")
5
+ .img-infografica__content(v-if="elements.length")
6
+ .img-infografica__item(
7
+ v-for="(item, index) in elements"
8
+ :key="'img-infografica-btn-'+item.id"
9
+ :style="[{top: item.y},{left: item.x}]"
10
+ @mouseover="selected = item.id"
11
+ @mouseleave="selected = 0"
12
+ )
13
+ .img-infografica__item__dot
14
+ .img-infografica__item__numero(v-if="item.hasOwnProperty('numero')") {{item.numero}}
15
+ .img-infografica__card(
16
+ v-for="item in elements"
17
+ :key="'img-infografica-card-'+item.id"
18
+ :ref="'card-ref-'+item.id"
19
+ :style="getCardCords(item.id)"
20
+ :class="{'img-infografica__card--selected' : selected === item.id}"
21
+ @mouseover="selected = item.id"
22
+ @mouseleave="selected = 0"
23
+ v-child="item.elm"
24
+ )
25
+ .img-infografica__indicador(
26
+ v-if="firstElement && showIndicator"
27
+ :style="[{top: firstElement.y},{left: firstElement.x}]"
28
+ )
29
+ .indicador--hover
30
+
31
+ .hidden-slot
32
+ slot
33
+ </template>
34
+
35
+ <script>
36
+ import componentSlotMixins from './componentSlotMixins'
37
+ export default {
38
+ name: 'ImagenInfografica',
39
+ mixins: [componentSlotMixins],
40
+ data: () => ({
41
+ firstSelection: false,
42
+ showIndicator: true,
43
+ }),
44
+ computed: {
45
+ firstElement() {
46
+ return this.elements.length && this.elements[0]
47
+ },
48
+ },
49
+ watch: {
50
+ selected() {
51
+ if (this.showIndicator) {
52
+ this.showIndicator = false
53
+ }
54
+ },
55
+ },
56
+ methods: {
57
+ getCardCords(cardId) {
58
+ const ref = 'card-ref-' + cardId
59
+ if (!(ref in this.$refs)) {
60
+ return [{ top: 0 }, { left: 0 }]
61
+ }
62
+
63
+ const currentCard = this.elements.find(card => card.id === cardId)
64
+ const imgElement = this.$refs['img-ref-' + this.mainId]
65
+ const imgObj = {
66
+ w: imgElement.clientWidth,
67
+ h: imgElement.clientHeight,
68
+ }
69
+ const cardElement = this.$refs[ref][0]
70
+ const cardObj = {
71
+ x: parseInt(currentCard.x, 10),
72
+ y: parseInt(currentCard.y, 10),
73
+ w: cardElement.clientWidth,
74
+ h: cardElement.clientHeight,
75
+ }
76
+
77
+ const cardPosY = (cardObj.y / 100) * imgObj.h
78
+ const cardPosX = (cardObj.x / 100) * imgObj.w
79
+
80
+ const finalObj = []
81
+
82
+ if (cardPosY + cardObj.h > imgObj.h) {
83
+ finalObj.push({ bottom: 0 })
84
+ } else {
85
+ finalObj.push({ top: currentCard.y })
86
+ }
87
+
88
+ if (cardPosX + cardObj.w > imgObj.w) {
89
+ finalObj.push({ right: 0 })
90
+ } else {
91
+ finalObj.push({ left: currentCard.x })
92
+ }
93
+
94
+ return finalObj
95
+ },
96
+ },
97
+ }
98
+ </script>
99
+
100
+ <style lang="sass"></style>