@windward/core 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.
- package/.editorconfig +13 -0
- package/.eslintrc.js +11 -0
- package/.prettierrc +4 -0
- package/README.md +86 -0
- package/babel.config.js +1 -0
- package/components/Content/Blocks/Accordion.vue +133 -0
- package/components/Content/Blocks/ClickableIcons.vue +98 -0
- package/components/Content/Blocks/Feedback.vue +323 -0
- package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionLikert.vue +95 -0
- package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionOpenResponse.vue +45 -0
- package/components/Content/Blocks/FeedbackTemplates/FeedbackQuestionTrueFalse.vue +55 -0
- package/components/Content/Blocks/Image.vue +116 -0
- package/components/Content/Blocks/Math.vue +87 -0
- package/components/Content/Blocks/Tab.vue +89 -0
- package/components/Content/Blocks/Table.vue +68 -0
- package/components/Content/Blocks/UserUpload/DisplayUserFilesTable.vue +157 -0
- package/components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue +68 -0
- package/components/Content/Blocks/UserUpload.vue +240 -0
- package/components/Content/Blocks/Video.vue +245 -0
- package/components/Navigation/Items/CourseGlossaryToolNav.vue +39 -0
- package/components/Navigation/Items/GlossaryNav.vue +32 -0
- package/components/Navigation/Items/UserUploadNav.vue +35 -0
- package/components/Settings/AccordionSettings.vue +153 -0
- package/components/Settings/ClickableIconsSettings.vue +189 -0
- package/components/Settings/FeedbackSettings.vue +92 -0
- package/components/Settings/ImageSettings.vue +124 -0
- package/components/Settings/MathSettings.vue +81 -0
- package/components/Settings/TabSettings.vue +139 -0
- package/components/Settings/TextEditorSettings.vue +249 -0
- package/components/Settings/UserUploadSettings.vue +151 -0
- package/components/Settings/VideoSettings.vue +699 -0
- package/components/utils/ContentViewer.vue +69 -0
- package/components/utils/MathExpressionEditor.vue +294 -0
- package/components/utils/MathLiveWrapper.vue +86 -0
- package/components/utils/TinyMCEWrapper.vue +103 -0
- package/components/utils/glossary/CourseGlossary.vue +284 -0
- package/components/utils/glossary/CourseGlossaryForm.vue +106 -0
- package/components/utils/glossary/GlossaryToolTip.vue +87 -0
- package/config/tinymce.config.js +136 -0
- package/helpers/GlossaryHelper.ts +137 -0
- package/helpers/GlossaryTerm.ts +31 -0
- package/helpers/MathHelper.ts +236 -0
- package/helpers/tinymce/plugin.ts +83 -0
- package/i18n/en-US/components/content/blocks/feedback.ts +28 -0
- package/i18n/en-US/components/content/blocks/image.ts +5 -0
- package/i18n/en-US/components/content/blocks/index.ts +15 -0
- package/i18n/en-US/components/content/blocks/tab.ts +4 -0
- package/i18n/en-US/components/content/blocks/table.ts +4 -0
- package/i18n/en-US/components/content/blocks/user_upload.ts +12 -0
- package/i18n/en-US/components/content/blocks/video.ts +53 -0
- package/i18n/en-US/components/content/index.ts +5 -0
- package/i18n/en-US/components/index.ts +12 -0
- package/i18n/en-US/components/navigation/image.ts +4 -0
- package/i18n/en-US/components/navigation/index.ts +7 -0
- package/i18n/en-US/components/navigation/user_upload.ts +3 -0
- package/i18n/en-US/components/settings/clickable_icon.ts +9 -0
- package/i18n/en-US/components/settings/image.ts +1 -0
- package/i18n/en-US/components/settings/index.ts +13 -0
- package/i18n/en-US/components/settings/text_editor.ts +7 -0
- package/i18n/en-US/components/settings/user_upload.ts +11 -0
- package/i18n/en-US/components/settings/video.ts +13 -0
- package/i18n/en-US/components/utils/index.ts +5 -0
- package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +7 -0
- package/i18n/en-US/index.ts +16 -0
- package/i18n/en-US/modules/index.ts +5 -0
- package/i18n/en-US/pages/glossary.ts +7 -0
- package/i18n/en-US/pages/index.ts +7 -0
- package/i18n/en-US/pages/user_upload.ts +3 -0
- package/i18n/en-US/shared/content_blocks.ts +20 -0
- package/i18n/en-US/shared/index.ts +11 -0
- package/i18n/en-US/shared/menu.ts +3 -0
- package/i18n/en-US/shared/permission.ts +15 -0
- package/i18n/en-US/shared/settings.ts +15 -0
- package/index.js +15 -0
- package/jest.config.js +15 -0
- package/models/SurveyResult.ts +8 -0
- package/models/SurveyTemplate.ts +8 -0
- package/models/UserFileAsset.ts +12 -0
- package/package.json +48 -0
- package/pages/glossary.vue +31 -0
- package/pages/userUpload.vue +204 -0
- package/plugin.js +299 -0
- package/test/Components/Content/Blocks/Accordion.spec.js +21 -0
- package/test/Components/Content/Blocks/ClickableIcons.spec.js +21 -0
- package/test/Components/Content/Blocks/Feedback.spec.js +31 -0
- package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionLikert.spec.js +23 -0
- package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionOpenResponse.spec.js +23 -0
- package/test/Components/Content/Blocks/FeedbackTemplates/FeedbackQuestionTrueFalse.spec.js +23 -0
- package/test/Components/Content/Blocks/Image.spec.js +34 -0
- package/test/Components/Content/Blocks/Math.spec.js +34 -0
- package/test/Components/Content/Blocks/Tab.spec.js +20 -0
- package/test/Components/Content/Blocks/Table.spec.js +21 -0
- package/test/Components/Content/Blocks/UserUpload.spec.js +25 -0
- package/test/Components/Content/Blocks/Video.spec.js +112 -0
- package/test/Components/Settings/AccordionSettings.spec.js +45 -0
- package/test/Components/Settings/ClickableIconsSettings.spec.js +20 -0
- package/test/Components/Settings/FeedbackSettings.spec.js +20 -0
- package/test/Components/Settings/ImageSettings.spec.js +20 -0
- package/test/Components/Settings/MathSettings.spec.js +20 -0
- package/test/Components/Settings/TabSettings.spec.js +45 -0
- package/test/Components/Settings/UserUploadSettings.spec.js +20 -0
- package/test/__mocks__/componentsMock.js +83 -0
- package/test/__mocks__/contentBlockMock.js +119 -0
- package/test/__mocks__/contentSettingsMock.js +54 -0
- package/test/__mocks__/fileMock.js +1 -0
- package/test/__mocks__/helpersMock.js +53 -0
- package/test/__mocks__/modelMock.js +82 -0
- package/test/__mocks__/styleMock.js +1 -0
- package/test/helpers/GlossaryHelper.spec.js +227 -0
- package/test/helpers/MathHelper.spec.js +128 -0
- package/test/mocks.js +140 -0
- package/tsconfig.json +15 -0
- package/utils/index.js +18 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container fluid>
|
|
3
|
+
<p class="question">
|
|
4
|
+
{{ value.body }}
|
|
5
|
+
</p>
|
|
6
|
+
<div class="d-flex justify-space-around">
|
|
7
|
+
<v-radio-group
|
|
8
|
+
:rules="[
|
|
9
|
+
(v) =>
|
|
10
|
+
!!v ||
|
|
11
|
+
$t(
|
|
12
|
+
'plugin.core.components.content.blocks.feedback.required'
|
|
13
|
+
),
|
|
14
|
+
]"
|
|
15
|
+
row
|
|
16
|
+
class="radio-group"
|
|
17
|
+
v-model="value.response"
|
|
18
|
+
>
|
|
19
|
+
<v-radio
|
|
20
|
+
class="likert-radio"
|
|
21
|
+
color="green"
|
|
22
|
+
:label="
|
|
23
|
+
$t(
|
|
24
|
+
'plugin.core.components.content.blocks.feedback.scale.strongly_agree'
|
|
25
|
+
)
|
|
26
|
+
"
|
|
27
|
+
value="5"
|
|
28
|
+
></v-radio>
|
|
29
|
+
<v-radio
|
|
30
|
+
class="likert-radio"
|
|
31
|
+
color="light-green"
|
|
32
|
+
:label="
|
|
33
|
+
$t(
|
|
34
|
+
'plugin.core.components.content.blocks.feedback.scale.agree'
|
|
35
|
+
)
|
|
36
|
+
"
|
|
37
|
+
value="4"
|
|
38
|
+
></v-radio>
|
|
39
|
+
<v-radio
|
|
40
|
+
class="likert-radio"
|
|
41
|
+
color="amber"
|
|
42
|
+
:label="
|
|
43
|
+
$t(
|
|
44
|
+
'plugin.core.components.content.blocks.feedback.scale.neutral'
|
|
45
|
+
)
|
|
46
|
+
"
|
|
47
|
+
value="3"
|
|
48
|
+
></v-radio>
|
|
49
|
+
<v-radio
|
|
50
|
+
class="likert-radio"
|
|
51
|
+
color="orange"
|
|
52
|
+
:label="
|
|
53
|
+
$t(
|
|
54
|
+
'plugin.core.components.content.blocks.feedback.scale.disagree'
|
|
55
|
+
)
|
|
56
|
+
"
|
|
57
|
+
value="2"
|
|
58
|
+
></v-radio>
|
|
59
|
+
<v-radio
|
|
60
|
+
class="likert-radio"
|
|
61
|
+
color="red"
|
|
62
|
+
:label="
|
|
63
|
+
$t(
|
|
64
|
+
'plugin.core.components.content.blocks.feedback.scale.strongly_disagree'
|
|
65
|
+
)
|
|
66
|
+
"
|
|
67
|
+
value="1"
|
|
68
|
+
></v-radio>
|
|
69
|
+
</v-radio-group>
|
|
70
|
+
</div>
|
|
71
|
+
</v-container>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<script>
|
|
75
|
+
export default {
|
|
76
|
+
name: 'FeedbackQuestionLikert',
|
|
77
|
+
props: {
|
|
78
|
+
value: { type: Object, required: true, default: '' },
|
|
79
|
+
},
|
|
80
|
+
data() {
|
|
81
|
+
return {}
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
</script>
|
|
85
|
+
<style scoped>
|
|
86
|
+
.question {
|
|
87
|
+
font-weight: bold;
|
|
88
|
+
}
|
|
89
|
+
.radio-group {
|
|
90
|
+
width: 100% !important;
|
|
91
|
+
}
|
|
92
|
+
.likert-radio {
|
|
93
|
+
margin-left: 55px;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container fluid>
|
|
3
|
+
<p class="question">
|
|
4
|
+
{{ value.body }}
|
|
5
|
+
</p>
|
|
6
|
+
<div v-if="!feedbackExist">
|
|
7
|
+
<TextEditor v-model="value.response"></TextEditor>
|
|
8
|
+
</div>
|
|
9
|
+
<div v-else>
|
|
10
|
+
<div v-if="value.response">
|
|
11
|
+
<TextViewer v-model="value.response" text-viewer></TextViewer>
|
|
12
|
+
</div>
|
|
13
|
+
<div v-else>
|
|
14
|
+
<TextViewer v-model="noResponse" text-viewer></TextViewer>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</v-container>
|
|
18
|
+
</template>
|
|
19
|
+
<script>
|
|
20
|
+
import TextEditor from '~/components/Text/TextEditor.vue'
|
|
21
|
+
import TextViewer from '~/components/Text/TextViewer.vue'
|
|
22
|
+
export default {
|
|
23
|
+
name: 'FeedbackQuestionOpenResponse',
|
|
24
|
+
components: {
|
|
25
|
+
TextEditor,
|
|
26
|
+
TextViewer,
|
|
27
|
+
},
|
|
28
|
+
props: {
|
|
29
|
+
value: { type: Object, required: true, default: '' },
|
|
30
|
+
feedbackExist: { type: Boolean, required: false, default: false },
|
|
31
|
+
},
|
|
32
|
+
data() {
|
|
33
|
+
return {
|
|
34
|
+
noResponse: this.$t(
|
|
35
|
+
'plugin.core.components.content.blocks.feedback.no_response_entered'
|
|
36
|
+
),
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
<style scoped>
|
|
42
|
+
.question {
|
|
43
|
+
font-weight: bold;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container fluid>
|
|
3
|
+
<p class="question">
|
|
4
|
+
{{ value.body }}
|
|
5
|
+
</p>
|
|
6
|
+
<v-radio-group
|
|
7
|
+
:rules="[
|
|
8
|
+
(v) =>
|
|
9
|
+
!!v ||
|
|
10
|
+
$t(
|
|
11
|
+
'plugin.core.components.content.blocks.feedback.required'
|
|
12
|
+
),
|
|
13
|
+
]"
|
|
14
|
+
row
|
|
15
|
+
v-model="value.response"
|
|
16
|
+
class="radio-group"
|
|
17
|
+
>
|
|
18
|
+
<v-radio
|
|
19
|
+
class="likert-radio"
|
|
20
|
+
:label="
|
|
21
|
+
$t('plugin.core.components.content.blocks.feedback.yes')
|
|
22
|
+
"
|
|
23
|
+
value="true"
|
|
24
|
+
></v-radio>
|
|
25
|
+
<v-radio
|
|
26
|
+
class="likert-radio"
|
|
27
|
+
:label="$t('plugin.core.components.content.blocks.feedback.no')"
|
|
28
|
+
value="false"
|
|
29
|
+
></v-radio>
|
|
30
|
+
</v-radio-group>
|
|
31
|
+
</v-container>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
export default {
|
|
36
|
+
name: 'FeedbackQuestionTrueFalse',
|
|
37
|
+
props: {
|
|
38
|
+
value: { type: Object, required: true, default: '' },
|
|
39
|
+
},
|
|
40
|
+
data() {
|
|
41
|
+
return {}
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
</script>
|
|
45
|
+
<style scoped>
|
|
46
|
+
.question {
|
|
47
|
+
font-weight: bold;
|
|
48
|
+
}
|
|
49
|
+
.radio-group {
|
|
50
|
+
width: 100% !important;
|
|
51
|
+
}
|
|
52
|
+
.likert-radio {
|
|
53
|
+
margin-left: 55px;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<p v-if="!block.body">
|
|
4
|
+
<v-img
|
|
5
|
+
class="img-holder"
|
|
6
|
+
src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNCyiabrwN6YV6s3Mj5IzREZCnQqqwT4A3Bw&usqp=CAU"
|
|
7
|
+
contain
|
|
8
|
+
></v-img>
|
|
9
|
+
</p>
|
|
10
|
+
<v-responsive :aspect-ratio="aspectRatio">
|
|
11
|
+
<v-img
|
|
12
|
+
v-if="block.body"
|
|
13
|
+
:alt="block.metadata.config.alt"
|
|
14
|
+
:aria-describedby="block.metadata.config.aria_described_by"
|
|
15
|
+
class="img-display"
|
|
16
|
+
:src="block.body"
|
|
17
|
+
contain
|
|
18
|
+
>
|
|
19
|
+
<template v-slot:placeholder>
|
|
20
|
+
<v-skeleton-loader
|
|
21
|
+
type="image, image, list-item-avatar"
|
|
22
|
+
height="100%"
|
|
23
|
+
width="100%"
|
|
24
|
+
></v-skeleton-loader>
|
|
25
|
+
</template>
|
|
26
|
+
</v-img>
|
|
27
|
+
</v-responsive>
|
|
28
|
+
<TextViewer
|
|
29
|
+
v-if="describedById"
|
|
30
|
+
v-model="describedByText"
|
|
31
|
+
:id="describedById"
|
|
32
|
+
class="sr-only"
|
|
33
|
+
></TextViewer>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script>
|
|
38
|
+
import _ from 'lodash'
|
|
39
|
+
import TextViewer from '~/components/Text/TextViewer.vue'
|
|
40
|
+
import Crypto from '~/helpers/Crypto'
|
|
41
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
name: 'ContentBlockImage',
|
|
45
|
+
extends: BaseContentBlock,
|
|
46
|
+
components: {
|
|
47
|
+
TextViewer,
|
|
48
|
+
},
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
aspectRatio: undefined,
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
extends: BaseContentBlock,
|
|
55
|
+
beforeMount() {
|
|
56
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
57
|
+
this.block.metadata.config = {}
|
|
58
|
+
}
|
|
59
|
+
if (_.isEmpty(this.block.metadata.config.alt)) {
|
|
60
|
+
this.block.metadata.config.alt = ''
|
|
61
|
+
}
|
|
62
|
+
if (_.isEmpty(this.block.metadata.config.aria_describedby)) {
|
|
63
|
+
this.block.metadata.config.aria_describedby = ''
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
data() {
|
|
67
|
+
return {
|
|
68
|
+
id: 'image_' + Crypto.id(),
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
computed: {
|
|
72
|
+
describedById() {
|
|
73
|
+
// If there's a described by
|
|
74
|
+
if (_.get(this.block.metadata, 'config.aria_describedby', null)) {
|
|
75
|
+
return this.id
|
|
76
|
+
} else {
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
describedByText() {
|
|
81
|
+
return _.get(this.block.metadata, 'config.aria_describedby', null)
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
watch: {
|
|
85
|
+
value(newValue) {
|
|
86
|
+
if (
|
|
87
|
+
!_.isEmpty(newValue.metadata.config.height) &&
|
|
88
|
+
!_.isEmpty(newValue.metadata.config.width)
|
|
89
|
+
) {
|
|
90
|
+
this.aspectRatio =
|
|
91
|
+
newValue.metadata.config.width +
|
|
92
|
+
'/' +
|
|
93
|
+
newValue.metadata.config.height
|
|
94
|
+
} else {
|
|
95
|
+
this.aspectRatio = undefined
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
mounted() {},
|
|
100
|
+
methods: {},
|
|
101
|
+
}
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<style scoped>
|
|
105
|
+
.img-display {
|
|
106
|
+
border-radius: 3px;
|
|
107
|
+
}
|
|
108
|
+
.img-holder {
|
|
109
|
+
max-height: 300px;
|
|
110
|
+
}
|
|
111
|
+
::v-deep .v-skeleton-loader.v-skeleton-loader--is-loading {
|
|
112
|
+
.v-skeleton-loader__image {
|
|
113
|
+
height: 100%;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
</style>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<br />
|
|
4
|
+
<math-expression-editor
|
|
5
|
+
v-if="!render && block.metadata.config.expand"
|
|
6
|
+
:key="key"
|
|
7
|
+
v-model="block.metadata.config.formula"
|
|
8
|
+
mode="standalone"
|
|
9
|
+
:value="block.metadata.config.formula"
|
|
10
|
+
></math-expression-editor>
|
|
11
|
+
<div
|
|
12
|
+
v-if="!block.metadata.config.expand"
|
|
13
|
+
class="text-viewer"
|
|
14
|
+
v-html="formulaConvertedToHtml"
|
|
15
|
+
></div>
|
|
16
|
+
<br />
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
import MathExpressionEditor from '../../utils/MathExpressionEditor'
|
|
22
|
+
import MathHelper from '../../../helpers/MathHelper'
|
|
23
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
24
|
+
import Crypto from '~/helpers/Crypto'
|
|
25
|
+
import _ from 'lodash'
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
name: 'ContentBlockMath',
|
|
29
|
+
components: { MathExpressionEditor },
|
|
30
|
+
extends: BaseContentBlock,
|
|
31
|
+
beforeMount() {
|
|
32
|
+
if (_.isEmpty(this.block)) {
|
|
33
|
+
this.block = {}
|
|
34
|
+
}
|
|
35
|
+
if (_.isEmpty(this.block.body)) {
|
|
36
|
+
this.block.body = 'Math Editor'
|
|
37
|
+
}
|
|
38
|
+
if (_.isEmpty(this.block.metadata)) {
|
|
39
|
+
this.block.metadata = {}
|
|
40
|
+
}
|
|
41
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
42
|
+
this.block.metadata.config = {}
|
|
43
|
+
}
|
|
44
|
+
if (_.isEmpty(this.block.metadata.config.formula)) {
|
|
45
|
+
this.block.metadata.config.formula = ''
|
|
46
|
+
}
|
|
47
|
+
if (_.isEmpty(this.block.metadata.config.expand)) {
|
|
48
|
+
this.block.metadata.config.expand = false
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
data() {
|
|
52
|
+
return {
|
|
53
|
+
key: '0',
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
computed: {
|
|
57
|
+
formulaConvertedToHtml() {
|
|
58
|
+
if (_.isEmpty(this.block.metadata.config.formula)) {
|
|
59
|
+
this.block.metadata.config.formula = ''
|
|
60
|
+
}
|
|
61
|
+
return MathHelper.convertMathContentToHtml(
|
|
62
|
+
this.block.metadata.config.formula
|
|
63
|
+
)
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
watch: {
|
|
67
|
+
value(newValue) {
|
|
68
|
+
if (newValue.metadata.config.expand === true) {
|
|
69
|
+
this.key = Crypto.id()
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
methods: {},
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<style scoped>
|
|
78
|
+
.text-viewer {
|
|
79
|
+
min-height: 100px;
|
|
80
|
+
}
|
|
81
|
+
@media (max-width: 600px) {
|
|
82
|
+
.text-viewer {
|
|
83
|
+
display: flex !important;
|
|
84
|
+
flex-wrap: wrap !important;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<v-container>
|
|
4
|
+
<v-tabs background-color="primary">
|
|
5
|
+
<v-tab
|
|
6
|
+
v-for="(tab, tabIndex) in block.metadata.config.items"
|
|
7
|
+
:key="tabIndex"
|
|
8
|
+
>
|
|
9
|
+
{{
|
|
10
|
+
tab.tabHeader === '' || tab.tabHeader === null
|
|
11
|
+
? 'Item ' + (tabIndex + 1)
|
|
12
|
+
: tab.tabHeader
|
|
13
|
+
}}
|
|
14
|
+
</v-tab>
|
|
15
|
+
<v-tab-item
|
|
16
|
+
v-for="(tabContent, tabContentIndex) in block.metadata
|
|
17
|
+
.config.items"
|
|
18
|
+
:key="'tabContent ' + tabContentIndex"
|
|
19
|
+
>
|
|
20
|
+
<v-container>
|
|
21
|
+
<TextViewer
|
|
22
|
+
v-if="!tabContent.expand"
|
|
23
|
+
v-model="
|
|
24
|
+
tabContent.content === '' ||
|
|
25
|
+
tabContent.content === null
|
|
26
|
+
? 'Item ' + (tabContentIndex + 1)
|
|
27
|
+
: tabContent.content
|
|
28
|
+
"
|
|
29
|
+
text-viewer
|
|
30
|
+
></TextViewer>
|
|
31
|
+
<TextEditor
|
|
32
|
+
v-if="!render && tabContent.expand"
|
|
33
|
+
v-model="tabContent.content"
|
|
34
|
+
></TextEditor>
|
|
35
|
+
</v-container>
|
|
36
|
+
</v-tab-item>
|
|
37
|
+
</v-tabs>
|
|
38
|
+
</v-container>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script>
|
|
43
|
+
import _ from 'lodash'
|
|
44
|
+
import TextEditor from '~/components/Text/TextEditor.vue'
|
|
45
|
+
import TextViewer from '~/components/Text/TextViewer.vue'
|
|
46
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
name: 'ContentBlockTab',
|
|
50
|
+
components: {
|
|
51
|
+
TextEditor,
|
|
52
|
+
TextViewer,
|
|
53
|
+
},
|
|
54
|
+
extends: BaseContentBlock,
|
|
55
|
+
beforeMount() {
|
|
56
|
+
this.block.body = 'tab'
|
|
57
|
+
if (_.isEmpty(this.block.metadata.config.items)) {
|
|
58
|
+
const defaultObject = {
|
|
59
|
+
tabHeader: '',
|
|
60
|
+
expand: false,
|
|
61
|
+
content: '',
|
|
62
|
+
}
|
|
63
|
+
this.block.metadata.config.items = []
|
|
64
|
+
this.block.metadata.config.items.push(defaultObject)
|
|
65
|
+
} else {
|
|
66
|
+
this.block.metadata.config.items.forEach((element) => {
|
|
67
|
+
if (element.content == null) {
|
|
68
|
+
element.content = ''
|
|
69
|
+
}
|
|
70
|
+
if (element.tabHeader == null) {
|
|
71
|
+
element.tabHeader = ''
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
data() {
|
|
77
|
+
return {}
|
|
78
|
+
},
|
|
79
|
+
methods: {
|
|
80
|
+
async onBeforeSave() {
|
|
81
|
+
this.block.metadata.config.items.forEach((element) => {
|
|
82
|
+
element.expand = false
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<style scoped></style>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-container>
|
|
3
|
+
<TextEditor
|
|
4
|
+
v-if="!render && block.metadata.config.expand"
|
|
5
|
+
v-model="block.body"
|
|
6
|
+
/>
|
|
7
|
+
<TextViewer
|
|
8
|
+
v-if="render || !block.metadata.config.expand"
|
|
9
|
+
v-model="block.body"
|
|
10
|
+
/>
|
|
11
|
+
</v-container>
|
|
12
|
+
</template>
|
|
13
|
+
<script>
|
|
14
|
+
import _ from 'lodash'
|
|
15
|
+
import TextViewer from '~/components/Text/TextViewer.vue'
|
|
16
|
+
import TextEditor from '~/components/Text/TextEditor.vue'
|
|
17
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
18
|
+
export default {
|
|
19
|
+
name: 'ContentBlockTable',
|
|
20
|
+
components: { TextEditor, TextViewer },
|
|
21
|
+
extends: BaseContentBlock,
|
|
22
|
+
beforeMount() {
|
|
23
|
+
// Apply the default config
|
|
24
|
+
if (_.isEmpty(this.block.body)) {
|
|
25
|
+
this.block.body = this.tablePreset
|
|
26
|
+
}
|
|
27
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
28
|
+
this.block.metadata.config = { expand: false }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
data() {
|
|
32
|
+
return {
|
|
33
|
+
tablePreset: `<table style="border-collapse: collapse; width: 99.951%;" border="1">
|
|
34
|
+
<tbody>
|
|
35
|
+
<tr>
|
|
36
|
+
<td style="width: 19.7426%;"> </td>
|
|
37
|
+
<td style="width: 19.7426%;"> </td>
|
|
38
|
+
<td style="width: 19.7426%;"> </td>
|
|
39
|
+
<td style="width: 19.7555%;"> </td>
|
|
40
|
+
</tr>
|
|
41
|
+
<tr>
|
|
42
|
+
<td style="width: 19.7426%;"> </td>
|
|
43
|
+
<td style="width: 19.7426%;"> </td>
|
|
44
|
+
<td style="width: 19.7426%;"> </td>
|
|
45
|
+
<td style="width: 19.7555%;"> </td>
|
|
46
|
+
</tr>
|
|
47
|
+
<tr>
|
|
48
|
+
<td style="width: 19.7426%;"> </td>
|
|
49
|
+
<td style="width: 19.7426%;"> </td>
|
|
50
|
+
<td style="width: 19.7426%;"> </td>
|
|
51
|
+
<td style="width: 19.7555%;"> </td>
|
|
52
|
+
</tr>
|
|
53
|
+
<tr>
|
|
54
|
+
<td style="width: 19.7426%;"> </td>
|
|
55
|
+
<td style="width: 19.7426%;"> </td>
|
|
56
|
+
<td style="width: 19.7426%;"> </td>
|
|
57
|
+
<td style="width: 19.7555%;"> </td>
|
|
58
|
+
</tr>
|
|
59
|
+
</tbody>
|
|
60
|
+
</table>`,
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
mounted() {},
|
|
64
|
+
methods: {},
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<style scoped></style>
|