@windward/core 0.0.6 → 0.0.8
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/.idea/codeStyles/Project.xml +58 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/php-docker-settings.xml +24 -0
- package/.idea/php.xml +19 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/watcherTasks.xml +4 -0
- package/.idea/windward-ui-plugin-core.iml +8 -0
- package/components/Content/Blocks/Image.vue +36 -14
- package/components/Content/Blocks/OpenResponse.vue +159 -0
- package/components/Content/Blocks/OpenResponseCollate.vue +185 -0
- package/components/Settings/ImageSettings.vue +10 -0
- package/components/Settings/OpenResponseCollateSettings.vue +171 -0
- package/components/Settings/OpenResponseSettings.vue +81 -0
- package/components/Settings/TextEditorSettings.vue +1 -0
- package/components/utils/TinyMCEWrapper.vue +21 -4
- package/components/utils/assets/tinymce/css/content.scss +1 -1
- package/coverage/clover.xml +223 -0
- package/coverage/coverage-final.json +16 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/components/Content/Blocks/Accordion.vue.html +430 -0
- package/coverage/lcov-report/components/Content/Blocks/Image.vue.html +394 -0
- package/coverage/lcov-report/components/Content/Blocks/Math.vue.html +262 -0
- package/coverage/lcov-report/components/Content/Blocks/RichText.vue.html +295 -0
- package/coverage/lcov-report/components/Content/Blocks/Tab.vue.html +415 -0
- package/coverage/lcov-report/components/Content/Blocks/Table.vue.html +667 -0
- package/coverage/lcov-report/components/Content/Blocks/Video.vue.html +2275 -0
- package/coverage/lcov-report/components/Content/Blocks/index.html +206 -0
- package/coverage/lcov-report/components/utils/ContentViewer.vue.html +199 -0
- package/coverage/lcov-report/components/utils/MathExpressionEditor.vue.html +919 -0
- package/coverage/lcov-report/components/utils/MathLiveWrapper.vue.html +343 -0
- package/coverage/lcov-report/components/utils/TinyMCEWrapper.vue.html +271 -0
- package/coverage/lcov-report/components/utils/index.html +161 -0
- package/coverage/lcov-report/config/index.html +116 -0
- package/coverage/lcov-report/config/tinymce.config.js.html +493 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/helpers/MathHelper.ts.html +793 -0
- package/coverage/lcov-report/helpers/index.html +116 -0
- package/coverage/lcov-report/helpers/tinymce/index.html +116 -0
- package/coverage/lcov-report/helpers/tinymce/plugin.ts.html +334 -0
- package/coverage/lcov-report/index.html +191 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/test/index.html +116 -0
- package/coverage/lcov-report/test/mocks.js.html +457 -0
- package/coverage/lcov.info +403 -0
- package/helpers/tinymce/plugin.ts +1 -1
- package/i18n/en-US/components/content/blocks/index.ts +4 -0
- package/i18n/en-US/components/content/blocks/open_response.ts +5 -0
- package/i18n/en-US/components/content/blocks/open_response_collate.ts +7 -0
- package/i18n/en-US/components/settings/image.ts +3 -1
- package/i18n/en-US/components/settings/index.ts +5 -1
- package/i18n/en-US/components/settings/open_response.ts +5 -0
- package/i18n/en-US/components/settings/open_response_collate.ts +6 -0
- package/i18n/en-US/shared/content_blocks.ts +2 -0
- package/i18n/en-US/shared/settings.ts +3 -1
- package/i18n/es-ES/components/content/blocks/index.ts +4 -0
- package/i18n/es-ES/components/content/blocks/open_response.ts +6 -0
- package/i18n/es-ES/components/content/blocks/open_response_collate.ts +7 -0
- package/i18n/es-ES/components/settings/image.ts +3 -1
- package/i18n/es-ES/components/settings/index.ts +4 -0
- package/i18n/es-ES/components/settings/open_response.ts +5 -0
- package/i18n/es-ES/components/settings/open_response_collate.ts +7 -0
- package/i18n/es-ES/shared/content_blocks.ts +2 -0
- package/i18n/es-ES/shared/settings.ts +3 -0
- package/i18n/sv-SE/components/content/blocks/index.ts +4 -0
- package/i18n/sv-SE/components/content/blocks/open_response.ts +6 -0
- package/i18n/sv-SE/components/content/blocks/open_response_collate.ts +7 -0
- package/i18n/sv-SE/components/settings/image.ts +3 -1
- package/i18n/sv-SE/components/settings/index.ts +5 -1
- package/i18n/sv-SE/components/settings/open_response.ts +5 -0
- package/i18n/sv-SE/components/settings/open_response_collate.ts +6 -0
- package/i18n/sv-SE/shared/content_blocks.ts +2 -0
- package/i18n/sv-SE/shared/settings.ts +2 -0
- package/lib/helpers/GlossaryHelper.d.ts +9 -0
- package/lib/helpers/GlossaryHelper.js +118 -0
- package/lib/helpers/GlossaryTerm.d.ts +10 -0
- package/lib/helpers/GlossaryTerm.js +22 -0
- package/lib/helpers/MathHelper.d.ts +99 -0
- package/lib/helpers/MathHelper.js +194 -0
- package/lib/helpers/tinymce/plugin.d.ts +2 -0
- package/lib/helpers/tinymce/plugin.js +86 -0
- package/lib/i18n/en-US/components/content/blocks/image.d.ts +6 -0
- package/lib/i18n/en-US/components/content/blocks/image.js +7 -0
- package/lib/i18n/en-US/components/content/blocks/index.d.ts +75 -0
- package/lib/i18n/en-US/components/content/blocks/index.js +14 -0
- package/lib/i18n/en-US/components/content/blocks/tab.d.ts +5 -0
- package/lib/i18n/en-US/components/content/blocks/tab.js +6 -0
- package/lib/i18n/en-US/components/content/blocks/table.d.ts +5 -0
- package/lib/i18n/en-US/components/content/blocks/table.js +6 -0
- package/lib/i18n/en-US/components/content/blocks/user_upload.d.ts +13 -0
- package/lib/i18n/en-US/components/content/blocks/user_upload.js +14 -0
- package/lib/i18n/en-US/components/content/blocks/video.d.ts +48 -0
- package/lib/i18n/en-US/components/content/blocks/video.js +49 -0
- package/lib/i18n/en-US/components/content/index.d.ts +77 -0
- package/lib/i18n/en-US/components/content/index.js +6 -0
- package/lib/i18n/en-US/components/index.d.ts +140 -0
- package/lib/i18n/en-US/components/index.js +12 -0
- package/lib/i18n/en-US/components/navigation/image.d.ts +5 -0
- package/lib/i18n/en-US/components/navigation/image.js +6 -0
- package/lib/i18n/en-US/components/navigation/index.d.ts +10 -0
- package/lib/i18n/en-US/components/navigation/index.js +8 -0
- package/lib/i18n/en-US/components/navigation/user_upload.d.ts +4 -0
- package/lib/i18n/en-US/components/navigation/user_upload.js +5 -0
- package/lib/i18n/en-US/components/settings/clickable_icon.d.ts +6 -0
- package/lib/i18n/en-US/components/settings/clickable_icon.js +7 -0
- package/lib/i18n/en-US/components/settings/image.d.ts +2 -0
- package/lib/i18n/en-US/components/settings/image.js +3 -0
- package/lib/i18n/en-US/components/settings/index.d.ts +39 -0
- package/lib/i18n/en-US/components/settings/index.js +14 -0
- package/lib/i18n/en-US/components/settings/text_editor.d.ts +8 -0
- package/lib/i18n/en-US/components/settings/text_editor.js +9 -0
- package/lib/i18n/en-US/components/settings/user_upload.d.ts +12 -0
- package/lib/i18n/en-US/components/settings/user_upload.js +13 -0
- package/lib/i18n/en-US/components/settings/video.d.ts +13 -0
- package/lib/i18n/en-US/components/settings/video.js +14 -0
- package/lib/i18n/en-US/components/utils/index.d.ts +15 -0
- package/lib/i18n/en-US/components/utils/index.js +6 -0
- package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.d.ts +13 -0
- package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.js +14 -0
- package/lib/i18n/en-US/index.d.ts +197 -0
- package/lib/i18n/en-US/index.js +16 -0
- package/lib/i18n/en-US/modules/index.d.ts +2 -0
- package/lib/i18n/en-US/modules/index.js +6 -0
- package/lib/i18n/en-US/pages/glossary.d.ts +8 -0
- package/lib/i18n/en-US/pages/glossary.js +9 -0
- package/lib/i18n/en-US/pages/index.d.ts +13 -0
- package/lib/i18n/en-US/pages/index.js +8 -0
- package/lib/i18n/en-US/pages/user_upload.d.ts +4 -0
- package/lib/i18n/en-US/pages/user_upload.js +5 -0
- package/lib/i18n/en-US/shared/content_blocks.d.ts +20 -0
- package/lib/i18n/en-US/shared/content_blocks.js +21 -0
- package/lib/i18n/en-US/shared/index.d.ts +39 -0
- package/lib/i18n/en-US/shared/index.js +10 -0
- package/lib/i18n/en-US/shared/menu.d.ts +4 -0
- package/lib/i18n/en-US/shared/menu.js +5 -0
- package/lib/i18n/en-US/shared/settings.d.ts +15 -0
- package/lib/i18n/en-US/shared/settings.js +16 -0
- package/lib/i18n/en-US.d.ts +197 -0
- package/lib/i18n/en-US.js +15 -0
- package/lib/models/UserFileAsset.d.ts +5 -0
- package/lib/models/UserFileAsset.js +37 -0
- package/package.json +1 -1
- package/plugin.js +43 -0
- package/test/Components/Content/Blocks/OpenResponse.spec.js +31 -0
- package/test/Components/Content/Blocks/OpenResponseCollate.spec.js +36 -0
- package/test/Components/Settings/OpenResponseCollateSettings.spec.js +20 -0
- package/test/Components/Settings/OpenResponseSettings.spec.js +20 -0
- package/test/__mocks__/helpersMock.js +3 -0
- package/test/__mocks__/modelMock.js +4 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
+
<code_scheme name="Project" version="173">
|
|
3
|
+
<HTMLCodeStyleSettings>
|
|
4
|
+
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
|
5
|
+
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
|
6
|
+
</HTMLCodeStyleSettings>
|
|
7
|
+
<JSCodeStyleSettings version="0">
|
|
8
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
9
|
+
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
10
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
11
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
12
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
13
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
14
|
+
</JSCodeStyleSettings>
|
|
15
|
+
<TypeScriptCodeStyleSettings version="0">
|
|
16
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
17
|
+
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
18
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
19
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
20
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
21
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
22
|
+
</TypeScriptCodeStyleSettings>
|
|
23
|
+
<VueCodeStyleSettings>
|
|
24
|
+
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
|
25
|
+
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
|
26
|
+
</VueCodeStyleSettings>
|
|
27
|
+
<codeStyleSettings language="HTML">
|
|
28
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
29
|
+
<indentOptions>
|
|
30
|
+
<option name="INDENT_SIZE" value="2" />
|
|
31
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
32
|
+
<option name="TAB_SIZE" value="2" />
|
|
33
|
+
</indentOptions>
|
|
34
|
+
</codeStyleSettings>
|
|
35
|
+
<codeStyleSettings language="JavaScript">
|
|
36
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
37
|
+
<indentOptions>
|
|
38
|
+
<option name="INDENT_SIZE" value="2" />
|
|
39
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
40
|
+
<option name="TAB_SIZE" value="2" />
|
|
41
|
+
</indentOptions>
|
|
42
|
+
</codeStyleSettings>
|
|
43
|
+
<codeStyleSettings language="TypeScript">
|
|
44
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
45
|
+
<indentOptions>
|
|
46
|
+
<option name="INDENT_SIZE" value="2" />
|
|
47
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
48
|
+
<option name="TAB_SIZE" value="2" />
|
|
49
|
+
</indentOptions>
|
|
50
|
+
</codeStyleSettings>
|
|
51
|
+
<codeStyleSettings language="Vue">
|
|
52
|
+
<option name="SOFT_MARGINS" value="80" />
|
|
53
|
+
<indentOptions>
|
|
54
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
55
|
+
</indentOptions>
|
|
56
|
+
</codeStyleSettings>
|
|
57
|
+
</code_scheme>
|
|
58
|
+
</component>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/windward-ui-plugin-core.iml" filepath="$PROJECT_DIR$/.idea/windward-ui-plugin-core.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="PhpDockerContainerSettings">
|
|
4
|
+
<list>
|
|
5
|
+
<map>
|
|
6
|
+
<entry key="79d59a8f-c56c-4789-b96c-e55a326ab125">
|
|
7
|
+
<value>
|
|
8
|
+
<DockerContainerSettings>
|
|
9
|
+
<option name="version" value="1" />
|
|
10
|
+
<option name="volumeBindings">
|
|
11
|
+
<list>
|
|
12
|
+
<DockerVolumeBindingImpl>
|
|
13
|
+
<option name="containerPath" value="/opt/project" />
|
|
14
|
+
<option name="hostPath" value="$PROJECT_DIR$" />
|
|
15
|
+
</DockerVolumeBindingImpl>
|
|
16
|
+
</list>
|
|
17
|
+
</option>
|
|
18
|
+
</DockerContainerSettings>
|
|
19
|
+
</value>
|
|
20
|
+
</entry>
|
|
21
|
+
</map>
|
|
22
|
+
</list>
|
|
23
|
+
</component>
|
|
24
|
+
</project>
|
package/.idea/php.xml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="MessDetectorOptionsConfiguration">
|
|
4
|
+
<option name="transferred" value="true" />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="PHPCSFixerOptionsConfiguration">
|
|
7
|
+
<option name="transferred" value="true" />
|
|
8
|
+
</component>
|
|
9
|
+
<component name="PHPCodeSnifferOptionsConfiguration">
|
|
10
|
+
<option name="highlightLevel" value="WARNING" />
|
|
11
|
+
<option name="transferred" value="true" />
|
|
12
|
+
</component>
|
|
13
|
+
<component name="PhpStanOptionsConfiguration">
|
|
14
|
+
<option name="transferred" value="true" />
|
|
15
|
+
</component>
|
|
16
|
+
<component name="PsalmOptionsConfiguration">
|
|
17
|
+
<option name="transferred" value="true" />
|
|
18
|
+
</component>
|
|
19
|
+
</project>
|
package/.idea/vcs.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$" />
|
|
5
|
+
<orderEntry type="inheritedJdk" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<
|
|
4
|
-
<v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
></v-
|
|
9
|
-
|
|
3
|
+
<div v-if="!block.body" class="img-holder">
|
|
4
|
+
<v-skeleton-loader
|
|
5
|
+
height="300px"
|
|
6
|
+
:elevation="2"
|
|
7
|
+
type="image"
|
|
8
|
+
></v-skeleton-loader>
|
|
9
|
+
|
|
10
|
+
<div class="no-source-overlay">
|
|
11
|
+
<v-icon x-large>mdi-file-question</v-icon><br />
|
|
12
|
+
{{
|
|
13
|
+
$t(
|
|
14
|
+
'windward.core.components.content.blocks.image.no_image_url'
|
|
15
|
+
)
|
|
16
|
+
}}
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
10
19
|
<v-responsive :aspect-ratio="aspectRatio">
|
|
11
20
|
<v-img
|
|
12
21
|
v-if="block.body"
|
|
13
22
|
:alt="block.metadata.config.alt"
|
|
14
23
|
:aria-describedby="block.metadata.config.aria_described_by"
|
|
15
|
-
class="
|
|
24
|
+
:class="imageClass"
|
|
16
25
|
:src="block.body"
|
|
17
26
|
contain
|
|
18
27
|
>
|
|
@@ -48,10 +57,10 @@ export default {
|
|
|
48
57
|
},
|
|
49
58
|
data() {
|
|
50
59
|
return {
|
|
60
|
+
id: 'image_' + Crypto.id(),
|
|
51
61
|
aspectRatio: undefined,
|
|
52
62
|
}
|
|
53
63
|
},
|
|
54
|
-
extends: BaseContentBlock,
|
|
55
64
|
beforeMount() {
|
|
56
65
|
if (_.isEmpty(this.block.metadata.config)) {
|
|
57
66
|
this.block.metadata.config = {}
|
|
@@ -59,15 +68,13 @@ export default {
|
|
|
59
68
|
if (_.isEmpty(this.block.metadata.config.alt)) {
|
|
60
69
|
this.block.metadata.config.alt = ''
|
|
61
70
|
}
|
|
71
|
+
if (!_.isBoolean(this.block.metadata.config.hide_background)) {
|
|
72
|
+
this.block.metadata.config.hide_background = false
|
|
73
|
+
}
|
|
62
74
|
if (_.isEmpty(this.block.metadata.config.aria_describedby)) {
|
|
63
75
|
this.block.metadata.config.aria_describedby = ''
|
|
64
76
|
}
|
|
65
77
|
},
|
|
66
|
-
data() {
|
|
67
|
-
return {
|
|
68
|
-
id: 'image_' + Crypto.id(),
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
78
|
computed: {
|
|
72
79
|
describedById() {
|
|
73
80
|
// If there's a described by
|
|
@@ -80,6 +87,14 @@ export default {
|
|
|
80
87
|
describedByText() {
|
|
81
88
|
return _.get(this.block.metadata, 'config.aria_describedby', null)
|
|
82
89
|
},
|
|
90
|
+
imageClass() {
|
|
91
|
+
let imageClass = ''
|
|
92
|
+
// If NOT hide background, inclide the extra class
|
|
93
|
+
if (!_.get(this.block.metadata, 'config.hide_background', false)) {
|
|
94
|
+
imageClass += ' img-white'
|
|
95
|
+
}
|
|
96
|
+
return 'img-display' + imageClass
|
|
97
|
+
},
|
|
83
98
|
},
|
|
84
99
|
watch: {
|
|
85
100
|
value(newValue) {
|
|
@@ -108,6 +123,13 @@ export default {
|
|
|
108
123
|
.img-holder {
|
|
109
124
|
max-height: 300px;
|
|
110
125
|
}
|
|
126
|
+
.img-white {
|
|
127
|
+
background: #fff;
|
|
128
|
+
}
|
|
129
|
+
.no-source-overlay {
|
|
130
|
+
text-align: center;
|
|
131
|
+
margin-top: -175px;
|
|
132
|
+
}
|
|
111
133
|
::v-deep .v-skeleton-loader.v-skeleton-loader--is-loading {
|
|
112
134
|
.v-skeleton-loader__image {
|
|
113
135
|
height: 100%;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="stateLoaded">
|
|
4
|
+
<div v-if="block.body && !submitted">
|
|
5
|
+
<TextViewer v-model="block.body" :height="200"></TextViewer>
|
|
6
|
+
<TextEditor
|
|
7
|
+
v-model="response"
|
|
8
|
+
:height="200"
|
|
9
|
+
menubar=""
|
|
10
|
+
></TextEditor>
|
|
11
|
+
<p class="pa-3 text-center blue-grey lighten-5">
|
|
12
|
+
<v-btn
|
|
13
|
+
color="primary"
|
|
14
|
+
:disabled="!canSubmit"
|
|
15
|
+
@click="onSubmit"
|
|
16
|
+
>
|
|
17
|
+
{{ $t('shared.forms.submit') }}
|
|
18
|
+
</v-btn>
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div v-else-if="block.body && submitted">
|
|
23
|
+
<TextViewer v-model="block.body" :height="200"></TextViewer>
|
|
24
|
+
<p>
|
|
25
|
+
{{
|
|
26
|
+
$t(
|
|
27
|
+
'windward.core.components.content.blocks.open_response.your_response'
|
|
28
|
+
)
|
|
29
|
+
}}
|
|
30
|
+
</p>
|
|
31
|
+
<v-alert color="light-blue lighten-4">
|
|
32
|
+
<TextViewer v-model="response" :height="200"></TextViewer>
|
|
33
|
+
</v-alert>
|
|
34
|
+
<div v-if="block.metadata.config.sample_response">
|
|
35
|
+
<p>
|
|
36
|
+
{{
|
|
37
|
+
$t(
|
|
38
|
+
'windward.core.components.content.blocks.open_response.sample_response'
|
|
39
|
+
)
|
|
40
|
+
}}
|
|
41
|
+
</p>
|
|
42
|
+
<v-alert color="light-blue lighten-4">
|
|
43
|
+
<TextViewer
|
|
44
|
+
v-model="block.metadata.config.sample_response"
|
|
45
|
+
:height="200"
|
|
46
|
+
></TextViewer>
|
|
47
|
+
</v-alert>
|
|
48
|
+
</div>
|
|
49
|
+
<p class="pa-3 text-center blue-grey lighten-5">
|
|
50
|
+
<v-btn color="primary" @click="submitted = false">{{
|
|
51
|
+
$t('shared.forms.edit')
|
|
52
|
+
}}</v-btn>
|
|
53
|
+
</p>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<v-alert v-else type="warning">
|
|
57
|
+
{{
|
|
58
|
+
$t(
|
|
59
|
+
'windward.core.components.content.blocks.open_response.initial_setup'
|
|
60
|
+
)
|
|
61
|
+
}}
|
|
62
|
+
</v-alert>
|
|
63
|
+
</div>
|
|
64
|
+
<div v-if="!stateLoaded">
|
|
65
|
+
<v-progress-circular
|
|
66
|
+
indeterminate
|
|
67
|
+
:size="64"
|
|
68
|
+
:width="4"
|
|
69
|
+
color="white"
|
|
70
|
+
>
|
|
71
|
+
</v-progress-circular>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<script>
|
|
77
|
+
import _ from 'lodash'
|
|
78
|
+
import { mapGetters } from 'vuex'
|
|
79
|
+
import TextViewer from '~/components/Text/TextViewer.vue'
|
|
80
|
+
import TextEditor from '~/components/Text/TextEditor.vue'
|
|
81
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
82
|
+
import UserContentBlockState from '~/models/UserContentBlockState'
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
name: 'ContentBlockOpenResponse',
|
|
86
|
+
extends: BaseContentBlock,
|
|
87
|
+
components: {
|
|
88
|
+
TextViewer,
|
|
89
|
+
TextEditor,
|
|
90
|
+
},
|
|
91
|
+
data() {
|
|
92
|
+
return {
|
|
93
|
+
stateLoaded: false,
|
|
94
|
+
response: '',
|
|
95
|
+
submitted: false,
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
computed: {
|
|
99
|
+
...mapGetters({
|
|
100
|
+
enrollment: 'enrollment/get',
|
|
101
|
+
}),
|
|
102
|
+
canSubmit() {
|
|
103
|
+
// Make sure the response is not empty and not equal to the starting text
|
|
104
|
+
return (
|
|
105
|
+
this.response &&
|
|
106
|
+
this.response !== this.block.metadata.config.starting_text
|
|
107
|
+
)
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
beforeMount() {
|
|
111
|
+
if (_.isEmpty(this.block.body)) {
|
|
112
|
+
this.block.body = ''
|
|
113
|
+
}
|
|
114
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
115
|
+
this.block.metadata.config = {}
|
|
116
|
+
}
|
|
117
|
+
if (_.isEmpty(this.block.metadata.config.sample_response)) {
|
|
118
|
+
this.block.metadata.config.sample_response = ''
|
|
119
|
+
}
|
|
120
|
+
if (_.isEmpty(this.block.metadata.config.starting_text)) {
|
|
121
|
+
this.block.metadata.config.starting_text = ''
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
watch: {},
|
|
125
|
+
mounted() {},
|
|
126
|
+
methods: {
|
|
127
|
+
async onAfterSetContentBlockState() {
|
|
128
|
+
// Check to see if we have a state already for this block with the same block_id
|
|
129
|
+
// States are loaded via the ContentBlock.id but in this particular case we want to
|
|
130
|
+
// maintain the state ACROSS different ContentBlock.ids but with the same linked Block.id
|
|
131
|
+
const userState = await UserContentBlockState.where({
|
|
132
|
+
'metadata->block->tag': 'plugin-core-open-response',
|
|
133
|
+
course_user_id: this.enrollment.id,
|
|
134
|
+
})
|
|
135
|
+
.where('metadata->block->block_id', this.block.block_id)
|
|
136
|
+
.first()
|
|
137
|
+
|
|
138
|
+
// Apply the "True" state
|
|
139
|
+
if (!_.isEmpty(userState)) {
|
|
140
|
+
this.response = _.get(userState, 'metadata.response', '')
|
|
141
|
+
this.submitted = _.get(userState, 'metadata.submitted', false)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// If after the state is applied the response is still empty then apply the default response
|
|
145
|
+
if (this.response === '') {
|
|
146
|
+
this.response = this.block.metadata.config.starting_text
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.stateLoaded = true
|
|
150
|
+
},
|
|
151
|
+
onSubmit() {
|
|
152
|
+
this.submitted = true
|
|
153
|
+
|
|
154
|
+
// Force the state to save on submit and not wait
|
|
155
|
+
this.$Tracking.flushState()
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
</script>
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="block.metadata.config.linked.length">
|
|
4
|
+
<v-btn color="primary" block @click="onCollate">
|
|
5
|
+
<v-icon class="mr-3">mdi-file-word</v-icon>
|
|
6
|
+
{{
|
|
7
|
+
$t(
|
|
8
|
+
'windward.core.components.content.blocks.open_response_collate.download_document'
|
|
9
|
+
)
|
|
10
|
+
}}
|
|
11
|
+
</v-btn>
|
|
12
|
+
</div>
|
|
13
|
+
<v-alert v-else type="warning">
|
|
14
|
+
{{
|
|
15
|
+
$t(
|
|
16
|
+
'windward.core.components.content.blocks.open_response_collate.initial_setup'
|
|
17
|
+
)
|
|
18
|
+
}}
|
|
19
|
+
</v-alert>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
import _ from 'lodash'
|
|
25
|
+
import { mapGetters } from 'vuex'
|
|
26
|
+
import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
|
|
27
|
+
import UserContentBlockState from '~/models/UserContentBlockState'
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
name: 'ContentBlockOpenResponseCollate',
|
|
31
|
+
extends: BaseContentBlock,
|
|
32
|
+
components: {},
|
|
33
|
+
data() {
|
|
34
|
+
return {
|
|
35
|
+
saveState: false, // Override the base block to disable state saving
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
beforeMount() {
|
|
39
|
+
if (_.isEmpty(this.block.body)) {
|
|
40
|
+
this.block.body = ''
|
|
41
|
+
}
|
|
42
|
+
if (_.isEmpty(this.block.metadata.config)) {
|
|
43
|
+
this.block.metadata.config = {}
|
|
44
|
+
}
|
|
45
|
+
if (_.isEmpty(this.block.metadata.config.linked)) {
|
|
46
|
+
this.block.metadata.config.linked = []
|
|
47
|
+
}
|
|
48
|
+
if (_.isEmpty(this.block.metadata.config.filename)) {
|
|
49
|
+
this.block.metadata.config.filename = ''
|
|
50
|
+
}
|
|
51
|
+
// _.isEmpty(true) returns false. use isBoolean to check if this prop exists
|
|
52
|
+
if (!_.isBoolean(this.block.metadata.config.include_prompts)) {
|
|
53
|
+
this.block.metadata.config.include_prompts = false
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
computed: {
|
|
57
|
+
...mapGetters({
|
|
58
|
+
organization: 'organization/get',
|
|
59
|
+
course: 'course/get',
|
|
60
|
+
enrollment: 'enrollment/get',
|
|
61
|
+
content: 'content/get',
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
watch: {},
|
|
65
|
+
mounted() {},
|
|
66
|
+
methods: {
|
|
67
|
+
async onCollate() {
|
|
68
|
+
try {
|
|
69
|
+
let userState = await UserContentBlockState.where({
|
|
70
|
+
'metadata->block->tag': 'plugin-core-open-response',
|
|
71
|
+
course_user_id: this.enrollment.id,
|
|
72
|
+
})
|
|
73
|
+
.whereIn(
|
|
74
|
+
'metadata->block->block_id',
|
|
75
|
+
this.block.metadata.config.linked
|
|
76
|
+
)
|
|
77
|
+
.get()
|
|
78
|
+
let collated = ''
|
|
79
|
+
const sortedStates = []
|
|
80
|
+
|
|
81
|
+
// Sorted the states based on the linked order
|
|
82
|
+
this.block.metadata.config.linked.forEach((linkedId) => {
|
|
83
|
+
const found = userState.find((state) => {
|
|
84
|
+
return state.metadata.block.block_id === linkedId
|
|
85
|
+
})
|
|
86
|
+
if (found) {
|
|
87
|
+
sortedStates.push(found)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
sortedStates.forEach((state) => {
|
|
92
|
+
// Prepend the prompt from the state if include prompts is enabled
|
|
93
|
+
if (this.block.metadata.config.include_prompts) {
|
|
94
|
+
collated +=
|
|
95
|
+
'<strong>' +
|
|
96
|
+
state.metadata.block.body +
|
|
97
|
+
'</strong><hr />'
|
|
98
|
+
}
|
|
99
|
+
if (!_.isEmpty(state.metadata.response)) {
|
|
100
|
+
collated += '\n' + state.metadata.response
|
|
101
|
+
} else {
|
|
102
|
+
collated +=
|
|
103
|
+
'\n<p>' +
|
|
104
|
+
this.$t(
|
|
105
|
+
'windward.core.components.content.blocks.open_response_collate.no_response'
|
|
106
|
+
) +
|
|
107
|
+
'</p>'
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
let filename = this.block.metadata.config.filename
|
|
111
|
+
if (_.isEmpty(this.block.metadata.config.filename)) {
|
|
112
|
+
// Default filename is the users name + the current page
|
|
113
|
+
filename =
|
|
114
|
+
this.$auth.user.last_name +
|
|
115
|
+
'_' +
|
|
116
|
+
this.$auth.user.first_name +
|
|
117
|
+
'_' +
|
|
118
|
+
_.get(this.content, 'content.name_prefix') +
|
|
119
|
+
_.get(this.content, 'content.name')
|
|
120
|
+
|
|
121
|
+
// Change spaces to underscores and remove special characters
|
|
122
|
+
filename = filename.replaceAll(/\s+/gi, '_')
|
|
123
|
+
filename = filename.replaceAll(/[^a-z0-9\-\_]/gi, '')
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.generateDocument(collated, filename)
|
|
127
|
+
} catch (e) {
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.error(e)
|
|
130
|
+
this.$dialog.error(
|
|
131
|
+
this.$t(
|
|
132
|
+
'windward.core.components.content.blocks.open_response_collate.generate_error'
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
generateDocument(htmlBody, filename = '') {
|
|
138
|
+
// Specify file name. If one isn't supplied then a default name of `exported_document_YYYY-MM-DD.doc` is used
|
|
139
|
+
filename = filename
|
|
140
|
+
? filename + '.doc'
|
|
141
|
+
: 'exported_document_' +
|
|
142
|
+
new Date().toISOString().split('T')[0] +
|
|
143
|
+
'.doc'
|
|
144
|
+
|
|
145
|
+
var preHtml =
|
|
146
|
+
"<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'>" +
|
|
147
|
+
"<head><meta charset='utf-8'><title>" +
|
|
148
|
+
filename +
|
|
149
|
+
'</title></head>' +
|
|
150
|
+
'<body>'
|
|
151
|
+
var postHtml = '</body></html>'
|
|
152
|
+
var html = preHtml + htmlBody + postHtml
|
|
153
|
+
|
|
154
|
+
var blob = new Blob(['\ufeff', html], {
|
|
155
|
+
type: 'application/msword',
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Specify link url
|
|
159
|
+
var url =
|
|
160
|
+
'data:application/vnd.ms-word;charset=utf-8,' +
|
|
161
|
+
encodeURIComponent(html)
|
|
162
|
+
|
|
163
|
+
// Create download link element
|
|
164
|
+
var downloadLink = document.createElement('a')
|
|
165
|
+
|
|
166
|
+
document.body.appendChild(downloadLink)
|
|
167
|
+
|
|
168
|
+
if (navigator.msSaveOrOpenBlob) {
|
|
169
|
+
navigator.msSaveOrOpenBlob(blob, filename)
|
|
170
|
+
} else {
|
|
171
|
+
// Create a link to the file
|
|
172
|
+
downloadLink.href = url
|
|
173
|
+
|
|
174
|
+
// Setting the file name
|
|
175
|
+
downloadLink.download = filename
|
|
176
|
+
|
|
177
|
+
//triggering the function
|
|
178
|
+
downloadLink.click()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
document.body.removeChild(downloadLink)
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
}
|
|
185
|
+
</script>
|
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
</template>
|
|
18
18
|
</ContentBlockAsset>
|
|
19
19
|
|
|
20
|
+
<v-switch
|
|
21
|
+
v-model="block.metadata.config.hide_background"
|
|
22
|
+
:label="
|
|
23
|
+
$t('windward.core.components.settings.image.hide_background')
|
|
24
|
+
"
|
|
25
|
+
></v-switch>
|
|
26
|
+
|
|
20
27
|
<v-form>
|
|
21
28
|
<v-text-field
|
|
22
29
|
v-model="block.metadata.config.alt"
|
|
@@ -69,6 +76,9 @@ export default {
|
|
|
69
76
|
if (_.isEmpty(this.block.metadata.config.alt)) {
|
|
70
77
|
this.block.metadata.config.alt = ''
|
|
71
78
|
}
|
|
79
|
+
if (!_.isBoolean(this.block.metadata.config.hide_background)) {
|
|
80
|
+
this.block.metadata.config.hide_background = false
|
|
81
|
+
}
|
|
72
82
|
if (_.isEmpty(this.block.metadata.config.aria_describedby)) {
|
|
73
83
|
this.block.metadata.config.aria_describedby = ''
|
|
74
84
|
}
|