@concretecms/bedrock 1.3.7 → 1.4.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 (105) hide show
  1. package/.eslintrc.yml +2 -0
  2. package/assets/account/js/frontend/components/AvatarCropper.vue +159 -0
  3. package/assets/account/js/frontend.js +1 -1
  4. package/assets/account/scss/frontend/_frontend.scss +2 -0
  5. package/assets/account/scss/frontend/avatar/_avatar-cropper.scss +82 -0
  6. package/assets/account/scss/frontend/avatar/_avatar.scss +6 -0
  7. package/assets/bedrock/scss/_frontend.scss +0 -1
  8. package/assets/calendar/js/backend/duration.js +13 -13
  9. package/assets/calendar/js/vendor/fullcalendar.js +1 -0
  10. package/assets/cms/components/Announcement/Action/ExternalLinkAction.vue +25 -0
  11. package/assets/cms/components/Announcement/Action/GuideAction.vue +36 -0
  12. package/assets/cms/components/Announcement/Action/VideoAction.vue +31 -0
  13. package/assets/cms/components/Announcement/Broadcast.vue +63 -0
  14. package/assets/cms/components/Announcement/Button/ExternalLinkButton.vue +26 -0
  15. package/assets/cms/components/Announcement/Header/Header.vue +33 -0
  16. package/assets/cms/components/Announcement/Item/Item.vue +50 -0
  17. package/assets/cms/components/Announcement/Modal/Modal.vue +77 -0
  18. package/assets/cms/components/Announcement/Slide/CollectSiteInformationSlide.vue +61 -0
  19. package/assets/cms/components/Announcement/Slide/FeatureSlide.vue +81 -0
  20. package/assets/cms/components/Announcement/Slide/WelcomeSlide.vue +87 -0
  21. package/assets/cms/components/Help/Modal.vue +48 -0
  22. package/assets/cms/components/Image/ThumbnailEditor.vue +117 -0
  23. package/assets/cms/components/RunningProcessList.vue +6 -1
  24. package/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue +27 -7
  25. package/assets/cms/components/file-manager/Chooser/FileManager.vue +0 -1
  26. package/assets/cms/components/file-manager/Chooser/FolderBookmark.vue +0 -1
  27. package/assets/cms/components/file-manager/Chooser.vue +1 -1
  28. package/assets/cms/components/form/ConcreteAjaxSelect.vue +173 -0
  29. package/assets/cms/components/form/ConcreteExpressEntrySelect.vue +74 -0
  30. package/assets/cms/components/form/ConcreteFileDirectoryInput.vue +28 -26
  31. package/assets/cms/components/form/ConcreteFileInput.vue +17 -5
  32. package/assets/cms/components/form/ConcreteGroupInput.vue +134 -0
  33. package/assets/cms/components/form/ConcreteLocaleSelect.vue +58 -0
  34. package/assets/cms/components/form/ConcreteOptionSelect.vue +92 -0
  35. package/assets/cms/components/form/ConcretePageSelect.vue +67 -0
  36. package/assets/cms/components/form/ConcreteSelect.vue +75 -0
  37. package/assets/cms/components/form/ConcreteThemeColorInput.vue +19 -14
  38. package/assets/cms/components/form/ConcreteUserInput.vue +24 -4
  39. package/assets/cms/components/form/ConcreteUserSelect.vue +126 -0
  40. package/assets/cms/components/form/IconSelector.vue +14 -5
  41. package/assets/cms/components/form/PasswordInput.vue +141 -24
  42. package/assets/cms/components/groups/Chooser.vue +6 -5
  43. package/assets/cms/components/index.js +24 -0
  44. package/assets/cms/components/toolbar/ConcreteToolbarSiteList.vue +62 -0
  45. package/assets/cms/components/user/Chooser/Search.vue +5 -0
  46. package/assets/cms/components/user/Chooser/Users.vue +6 -2
  47. package/assets/cms/components/user/Chooser.vue +9 -3
  48. package/assets/cms/js/ajax-request/base.js +13 -4
  49. package/assets/cms/js/alert.js +2 -1
  50. package/assets/cms/js/base.js +3 -10
  51. package/assets/cms/js/edit-mode/area.js +0 -35
  52. package/assets/cms/js/edit-mode/block.js +27 -0
  53. package/assets/cms/js/edit-mode/containerblock.js +33 -3
  54. package/assets/cms/js/edit-mode/editmode.js +12 -0
  55. package/assets/cms/js/edit-mode/layout.js +56 -0
  56. package/assets/cms/js/edit-mode/style-customizer/style-customizer.js +0 -1
  57. package/assets/cms/js/file-manager/uploader.js +30 -206
  58. package/assets/cms/js/help/help.js +11 -8
  59. package/assets/cms/js/in-context-menu.js +5 -0
  60. package/assets/cms/js/jquery-vue.js +22 -0
  61. package/assets/cms/js/legacy-dialog.js +74 -65
  62. package/assets/cms/js/modal.js +73 -0
  63. package/assets/cms/js/panels.js +8 -0
  64. package/assets/cms/js/search/base.js +0 -18
  65. package/assets/cms/js/search/field-selector.js +6 -14
  66. package/assets/cms/js/select-combo-box.js +2 -0
  67. package/assets/cms/js/sitemap/sitemap-selector.js +2 -2
  68. package/assets/cms/js/sitemap/sitemap.js +15 -20
  69. package/assets/cms/js/toolbar.js +25 -2
  70. package/assets/cms/js/tree.js +7 -7
  71. package/assets/cms/js/users/group-manager.js +55 -0
  72. package/assets/cms/js/users/user-manager.js +2 -1
  73. package/assets/cms/js/users.js +1 -0
  74. package/assets/cms/js/vue/Manager.js +6 -3
  75. package/assets/cms/scss/_base.scss +2 -8
  76. package/assets/cms/scss/_cards.scss +7 -0
  77. package/assets/cms/scss/_file-manager.scss +1 -0
  78. package/assets/cms/scss/_file-uploader.scss +13 -3
  79. package/assets/cms/scss/_help.scss +11 -2
  80. package/assets/cms/scss/_item-selector.scss +10 -0
  81. package/assets/cms/scss/_layouts.scss +16 -0
  82. package/assets/cms/scss/_page-areas.scss +524 -245
  83. package/assets/cms/scss/_popover.scss +5 -0
  84. package/assets/cms/scss/_select-combo-box.scss +18 -0
  85. package/assets/cms/scss/_toolbar.scss +5 -14
  86. package/assets/cms/scss/_transitions.scss +13 -0
  87. package/assets/cms/scss/_variables.scss +18 -7
  88. package/assets/cms/scss/bootstrap/_reboot-tags.scss +17 -32
  89. package/assets/cms/scss/bootstrap/_reboot.scss +17 -7
  90. package/assets/cms/scss/bootstrap/_root-modified.scss +41 -20
  91. package/assets/cms/scss/file-manager/_thumbnail-image-editor.scss +45 -0
  92. package/assets/cms/scss/panels/_help.scss +0 -10
  93. package/assets/staging/scss/frontend/_frontend.scss +12 -0
  94. package/assets/staging/scss/frontend.scss +4 -0
  95. package/package.json +9 -9
  96. package/assets/account/js/frontend/components/Avatar/Avatar.js +0 -270
  97. package/assets/account/js/frontend/components/Avatar/Avatar.scss +0 -17
  98. package/assets/account/js/frontend/components/Avatar/Avatar.vue +0 -18
  99. package/assets/account/js/frontend/components/Avatar/Cropper.js +0 -202
  100. package/assets/account/js/frontend/components/Avatar/Cropper.scss +0 -136
  101. package/assets/account/js/frontend/components/Avatar/Cropper.vue +0 -40
  102. package/assets/bedrock/scss/_theme-grid.scss +0 -7
  103. package/assets/cms/js/edit-mode/style-customizer/inline-toolbar.js +0 -279
  104. package/assets/cms/js/modifiable-ajax-bootstrap-select.js +0 -78
  105. package/assets/cms/js/modifiable-bootstrap-select.js +0 -112
package/.eslintrc.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  extends:
3
3
  - plugin:vue/base
4
+ parserOptions:
5
+ ecmaVersion: 2020
4
6
  rules:
5
7
  indent:
6
8
  - error
@@ -0,0 +1,159 @@
1
+ <template>
2
+ <div class="ccm-account-avatar-cropper">
3
+ <div class="card">
4
+ <div class="card-header">{{ lang.header }}</div>
5
+ <div class="card-body">
6
+ <template v-if="image">
7
+ <cropper
8
+ ref="cropper"
9
+ :stencil-props="{
10
+ handlers: {},
11
+ resizable: false,
12
+ }"
13
+ :stencil-size="stencilSize"
14
+ :canvas="canvas"
15
+ image-restriction="stencil"
16
+ :src="image.src"
17
+ />
18
+ <div class="ccm-account-avatar-cropper-controls">
19
+ <a @click="zoomIn"><svg width="24px" height="24px" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff"><path d="M8 11h3m3 0h-3m0 0V8m0 3v3M17 17l4 4M3 11a8 8 0 1016 0 8 8 0 00-16 0z" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></a>
20
+ <a @click="zoomOut"><svg width="24px" height="24px" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg" color="#ffffff"><path d="M17 17l4 4M3 11a8 8 0 1016 0 8 8 0 00-16 0zM8 11h6" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></a>
21
+ </div>
22
+ <div class="ccm-account-avatar-cropper-save" v-if="image">
23
+ <button @click="image = null" class="btn btn-secondary float-start">{{ lang.reset }}</button>
24
+ <template v-if="saveInProgress">
25
+ <button class="btn btn-primary float-end" disabled>
26
+ <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
27
+ {{ lang.saveInProgress }}
28
+ </button>
29
+ </template>
30
+ <button @click="saveAvatar" class="btn btn-primary float-end" v-else>{{ lang.save }}</button>
31
+ </div>
32
+ </template>
33
+ <template v-else>
34
+ <div :class="{'ccm-account-avatar-cropper-drop': true, 'ccm-account-avatar-crop-drop-hover': isDragging}"
35
+ @dragover="dragover"
36
+ @dragleave="dragleave"
37
+ @drop="drop"
38
+ @click="$refs.file.click()">
39
+ <input type="file" ref="file" @change="onChange" accept="image/*">
40
+ </div>
41
+ <div class="ccm-account-avatar-cropper-focus">
42
+ <div class="ccm-account-avatar-cropper-icon">
43
+ <svg width="100%" height="100%" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M3 20.4V3.6a.6.6 0 01.6-.6h16.8a.6.6 0 01.6.6v16.8a.6.6 0 01-.6.6H3.6a.6.6 0 01-.6-.6z" stroke="#000000" stroke-width="1.5"></path><path d="M6 18h12M12 14V6m0 0l3.5 3.5M12 6L8.5 9.5" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
44
+ </div>
45
+ <div class="ccm-account-avatar-cropper-text">{{ lang.upload }}</div>
46
+ </div>
47
+ </template>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </template>
52
+ <script>
53
+ import { Cropper } from 'vue-advanced-cropper'
54
+ import 'vue-advanced-cropper/dist/style.css'
55
+ export default {
56
+ components: {
57
+ Cropper
58
+ },
59
+ props: {
60
+ width: {
61
+ type: Number,
62
+ required: true
63
+ },
64
+ height: {
65
+ type: Number,
66
+ required: true
67
+ },
68
+ accessToken: {
69
+ type: String,
70
+ required: true
71
+ },
72
+ lang: {
73
+ type: Object,
74
+ required: true
75
+ },
76
+ uploadUrl: {
77
+ type: String,
78
+ required: true
79
+ }
80
+ },
81
+ data: () => ({
82
+ isDragging: false,
83
+ image: null,
84
+ saveInProgress: false
85
+ }),
86
+ computed: {
87
+ stencilSize: function() {
88
+ const stencilSize = {}
89
+ stencilSize.width = this.width
90
+ stencilSize.height = this.height
91
+ return stencilSize
92
+ },
93
+ canvas: function() {
94
+ const canvas = {}
95
+ canvas.maxWidth = this.width
96
+ canvas.maxHeight = this.height
97
+ return canvas
98
+ }
99
+ },
100
+ methods: {
101
+ zoomIn() {
102
+ this.$refs.cropper.zoom(1.2)
103
+ },
104
+ zoomOut() {
105
+ this.$refs.cropper.zoom(0.8)
106
+ },
107
+ dragover(e) {
108
+ e.preventDefault()
109
+ this.isDragging = true
110
+ },
111
+ dragleave() {
112
+ this.isDragging = false
113
+ },
114
+ drop(e) {
115
+ e.preventDefault()
116
+ this.$refs.file.files = e.dataTransfer.files
117
+ this.onChange()
118
+ this.isDragging = false
119
+ },
120
+ onChange() {
121
+ var files = this.$refs.file.files
122
+ if (files && files[0]) {
123
+ if (this.image && this.image.src) {
124
+ URL.revokeObjectURL(this.image.src)
125
+ }
126
+ const blob = URL.createObjectURL(files[0])
127
+ const reader = new FileReader()
128
+ reader.onload = (e) => {
129
+ this.image = {
130
+ src: blob,
131
+ type: files[0].type
132
+ }
133
+ }
134
+ reader.readAsArrayBuffer(files[0])
135
+ }
136
+ },
137
+ saveAvatar() {
138
+ this.saveInProgress = true
139
+ const { canvas } = this.$refs.cropper.getResult()
140
+ if (canvas) {
141
+ const form = new FormData()
142
+ form.append('ccm_token', this.accessToken)
143
+ canvas.toBlob(blob => {
144
+ form.append('file', blob)
145
+ // You can use axios, superagent and other libraries instead here
146
+ fetch(this.uploadUrl, {
147
+ method: 'POST',
148
+ body: form
149
+ }).then(() => {
150
+ window.location.reload()
151
+ })
152
+ })
153
+ }
154
+ }
155
+ },
156
+ mounted() {
157
+ }
158
+ }
159
+ </script>
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-new */
2
2
 
3
- import AvatarCropper from './frontend/components/Avatar/Cropper.vue'
3
+ import AvatarCropper from './frontend/components/AvatarCropper.vue'
4
4
 
5
5
  $(function() {
6
6
  window.Concrete.Vue.createContext('frontend', {
@@ -3,3 +3,5 @@
3
3
  @import 'bootstrap/scss/mixins';
4
4
 
5
5
  @import 'sidebar/navigation';
6
+ @import 'avatar/avatar';
7
+ @import 'avatar/avatar-cropper';
@@ -0,0 +1,82 @@
1
+ div.ccm-account-avatar-cropper {
2
+ .card-body {
3
+ align-items: center;
4
+ display: flex;
5
+ height: 400px;
6
+ padding: 0;
7
+ position: relative;
8
+ width: 100%;
9
+ }
10
+
11
+ div.ccm-account-avatar-cropper-drop {
12
+ cursor: pointer;
13
+ height: 100%;
14
+ position: absolute;
15
+ transition: all 0.1s linear;
16
+ width: 100%;
17
+ z-index: 100;
18
+
19
+ input[type=file] {
20
+ display: none;
21
+ }
22
+
23
+ &.ccm-account-avatar-crop-drop-hover,
24
+ &:hover {
25
+ background-color: rgba($primary, 0.1);
26
+ }
27
+ }
28
+
29
+ .ccm-account-avatar-cropper-focus {
30
+ margin-left: auto;
31
+ margin-right: auto;
32
+ }
33
+
34
+ .ccm-account-avatar-cropper-icon {
35
+ height: 120px;
36
+ margin-left: auto;
37
+ margin-right: auto;
38
+ width: 120px;
39
+ }
40
+
41
+ .ccm-account-avatar-cropper-text {
42
+ color: $secondary;
43
+ }
44
+
45
+ .ccm-account-avatar-cropper-controls {
46
+ left: 20px;
47
+ position: absolute;
48
+ top: 50%;
49
+ transform: translateY(-50%);
50
+
51
+ a {
52
+ align-items: center;
53
+ background-color: rgba(0, 0, 0, 0.8);
54
+ cursor: pointer;
55
+ display: flex;
56
+ height: 40px;
57
+ margin-bottom: 10px;
58
+ text-align: center;
59
+ width: 40px;
60
+
61
+ &:last-child {
62
+ margin-bottom: 0;
63
+ }
64
+
65
+ &:hover {
66
+ background-color: $primary;
67
+ }
68
+
69
+ svg {
70
+ margin-left: auto;
71
+ margin-right: auto;
72
+ }
73
+ }
74
+ }
75
+
76
+ .ccm-account-avatar-cropper-save {
77
+ bottom: 20px;
78
+ left: 20px;
79
+ position: absolute;
80
+ right: 20px;
81
+ }
82
+ }
@@ -0,0 +1,6 @@
1
+ div.ccm-page-account {
2
+ img.u-avatar {
3
+ height: auto;
4
+ max-width: 100%;
5
+ }
6
+ }
@@ -8,5 +8,4 @@
8
8
  @import 'theme-context-root';
9
9
  @import 'mixins';
10
10
  @import 'utilities';
11
- @import 'theme-grid';
12
11
  @import 'pagination';
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-new, no-unused-vars, camelcase, eqeqeq */
2
- /* global moment, _ */
2
+ /* global TomSelect, moment, _ */
3
3
 
4
4
  ;(function(global, $) {
5
5
  'use strict'
@@ -132,18 +132,16 @@
132
132
  setupTimes: function () {
133
133
  var my = this
134
134
  var $startTime = my.$element.find('select[data-select=start-time]')
135
- $startTime.selectpicker({
136
- liveSearch: true,
137
- liveSearchStyle: 'startsWith'
138
- })
139
- $startTime.on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
135
+ var $endTime = my.$element.find('select[data-select=end-time]')
136
+ var startTimeSelect = new TomSelect($startTime.get(0))
137
+ var endTimeSelect = new TomSelect($endTime.get(0))
138
+
139
+ $startTime.data('TomSelect', startTimeSelect)
140
+ $startTime.on('change', function () {
140
141
  my.calculateEndDate()
141
142
  })
142
143
 
143
- my.$element.find('select[data-select=end-time]').selectpicker({
144
- liveSearch: true,
145
- liveSearchStyle: 'startsWith'
146
- })
144
+ $endTime.data('TomSelect', endTimeSelect)
147
145
  },
148
146
 
149
147
  getSelectedEndDate: function () {
@@ -243,8 +241,10 @@
243
241
 
244
242
  my.$element.find('input[name=' + my.options.namespace + '_pdEndDate_pub_' + my.getSetID() + ']').datepicker('setDate', endDateFormatted)
245
243
 
246
- var $bsSelect = my.$element.find('select[name=' + my.options.namespace + '_pdEndDateSelectTime_' + my.getSetID() + ']')
247
- $bsSelect.selectpicker('val', endTime)
244
+ var $select = my.$element.find('select[name=' + my.options.namespace + '_pdEndDateSelectTime_' + my.getSetID() + ']')
245
+ $select.val(endTime)
246
+ // TomSelect specifically. Need to do this to update the value.
247
+ $select.data('TomSelect').sync()
248
248
  },
249
249
 
250
250
  setupDates: function () {
@@ -392,7 +392,7 @@
392
392
  my.$element.find('select[data-select=start-time]').parent().hide()
393
393
  my.$element.find('select[data-select=end-time]').parent().hide()
394
394
  } else {
395
- my.$element.find('div[data-column=date]').removeClass().addClass('col-sm-6')
395
+ my.$element.find('div[data-column=date]').removeClass().addClass('col-sm-5')
396
396
  my.$element.find('select[data-select=start-time]').parent().show()
397
397
  my.$element.find('select[data-select=end-time]').parent().show()
398
398
  }
@@ -1,3 +1,4 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import $ from 'jquery'
3
3
  import 'fullcalendar'
4
+ import 'fullcalendar/dist/locale-all.js'
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <div>
3
+ <a target="_blank" :href="url">
4
+ <i class="fas fa-external-link-alt"></i>
5
+ Learn More
6
+ </a>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ export default {
12
+ props: {
13
+ url: {
14
+ type: String,
15
+ required: true
16
+ }
17
+ },
18
+ data: () => ({
19
+ }),
20
+ methods: {
21
+ },
22
+ mounted() {
23
+ }
24
+ }
25
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div>
3
+ <a href="#" @click="launchGuide">
4
+ <i class="fas fa-cog"></i>
5
+ Run Guide
6
+ </a>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ /* global ConcreteHelpGuideManager bootstrap */
12
+ export default {
13
+ props: {
14
+ guide: {
15
+ type: String,
16
+ required: true
17
+ }
18
+ },
19
+ data: () => ({
20
+ }),
21
+ methods: {
22
+ launchGuide() {
23
+ var tour = ConcreteHelpGuideManager.getGuide(this.guide)
24
+ const announcementModal = $(this.$el).closest('.modal')
25
+ const modal = bootstrap.Modal.getOrCreateInstance(announcementModal.get(0))
26
+ if (modal) {
27
+ modal.hide()
28
+ }
29
+ tour.start()
30
+ }
31
+ },
32
+ mounted() {
33
+
34
+ }
35
+ }
36
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div>
3
+ <a :href="url" ref="link">
4
+ <i class="fas fa-play-circle"></i>
5
+ Watch Video
6
+ </a>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ export default {
12
+ props: {
13
+ url: {
14
+ type: String,
15
+ required: true
16
+ }
17
+ },
18
+ data: () => ({
19
+ }),
20
+ mounted() {
21
+ $(this.$refs.link).magnificPopup({
22
+ disableOn: 700,
23
+ type: 'iframe',
24
+ mainClass: 'mfp-fade',
25
+ removalDelay: 160,
26
+ preloader: false,
27
+ fixedContentPos: false
28
+ })
29
+ }
30
+ }
31
+ </script>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <div class="ccm-ui">
3
+ <div class="modal fade" data-bs-backdrop="static" role="dialog" tabindex="-1" id="concrete-announcement-modal">
4
+ <component
5
+ :key="announcementKey"
6
+ :is="announcementComponent"
7
+ :handle="announcementKey"
8
+ :slides="announcementComponentSlides"
9
+ :total-slides="announcementComponentSlides.length"
10
+ @advance-broadcast="advanceBroadcast"
11
+ ></component>
12
+ </div>
13
+ </div>
14
+ </template>
15
+ <script>
16
+ /* global bootstrap */
17
+ import ConcreteAnnouncementModal from './Modal/Modal'
18
+
19
+ export default {
20
+ components: {
21
+ ConcreteAnnouncementModal
22
+ },
23
+ props: {
24
+ broadcast: {
25
+ type: Object,
26
+ required: true
27
+ }
28
+ },
29
+ data: () => ({
30
+ currentAnnouncement: 0
31
+ }),
32
+ computed: {
33
+ announcementKey: function() {
34
+ return this.broadcast.announcements[this.currentAnnouncement].handle
35
+ },
36
+ announcementComponent: function() {
37
+ return this.broadcast.announcements[this.currentAnnouncement].component
38
+ },
39
+ announcementComponentSlides: function() {
40
+ return this.broadcast.announcements[this.currentAnnouncement].slides
41
+ }
42
+ },
43
+ methods: {
44
+ advanceBroadcast() {
45
+ if ((this.currentAnnouncement + 1) === this.broadcast.announcements.length) {
46
+ this.getModal().hide()
47
+ } else {
48
+ this.currentAnnouncement++
49
+ }
50
+ },
51
+ getModal() {
52
+ const modal = document.getElementById('concrete-announcement-modal')
53
+ return bootstrap.Modal.getOrCreateInstance(modal)
54
+ }
55
+ },
56
+ mounted() {
57
+ var modal = this.getModal()
58
+ if (modal) {
59
+ modal.show()
60
+ }
61
+ }
62
+ }
63
+ </script>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div>
3
+ <a target="_blank" class="btn btn-secondary" :href="url">{{ title }}</a>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ props: {
10
+ title: {
11
+ type: String,
12
+ required: true
13
+ },
14
+ url: {
15
+ type: String,
16
+ required: true
17
+ }
18
+ },
19
+ data: () => ({
20
+ }),
21
+ methods: {
22
+ },
23
+ mounted() {
24
+ }
25
+ }
26
+ </script>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="modal-header">
3
+ <div class="row w-100 align-items-center">
4
+ <div class="col-md-3 text-center">
5
+ <svg width="100" fill="white" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
6
+ viewBox="0 0 25 25" enable-background="new 0 0 25 25" xml:space="preserve">
7
+ <path d="M21.6,15.9c-2.1-2.5-5.4,2.8-7.1,3.9c-1.2,0.8-3,0.9-4.3,0.1c-1.8-1-1.2-3.5,0.6-4.1c1.7-0.5,4.6,1.2,5.6-0.5
8
+ c1.3-2.2-3.1-2.7-4.4-2.6c-2.4,0.1-4.6,0.9-6,2.6c-1.5,1.9-1.2,4.3,0.5,6c1.7,1.6,4.2,2.3,6.6,2.1c0.6-0.1,1.7-0.3,2.5-0.8
9
+ C17.1,21.8,22,16.4,21.6,15.9z M6.1,14C7,14.2,5.4,9.6,5.3,9C5.1,8.2,4.9,7.2,4.1,7C3.2,6.9,3,7.9,3.2,8.8C3.4,9.7,5.4,13.9,6.1,14z
10
+ M12.9,11.7c1.3,0.2,1.2-5.9,1.2-6.7c0-0.7,0.3-2.8-0.7-3c-1.4-0.3-1.5,1.5-1.5,2.5C11.9,5.4,11.6,11.5,12.9,11.7z M15.9,12.6
11
+ c1.4,0.6,2.4-5.6,2.6-6.4c0.2-0.8,0.2-2.5-1.2-2c-0.7,0.3-0.8,1.4-0.9,2C16.2,7.1,14.9,12.2,15.9,12.6z M9.3,12.1
12
+ c1.6,0.1,0.1-6.1,0-6.9C9.1,4.4,8.5,2.7,7.4,3.7C6.8,4.2,7.1,5.3,7.2,6C7.3,6.8,8.1,12,9.3,12.1z"/>
13
+ </svg>
14
+ </div>
15
+ <div class="col-md-9">
16
+ <h4 class="modal-title">{{title}}</h4>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script>
23
+ export default {
24
+ props: {
25
+ title: {
26
+ type: String,
27
+ required: true
28
+ }
29
+ },
30
+ data: () => ({
31
+ })
32
+ }
33
+ </script>
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <section class="row w-100 align-items-center">
3
+ <div class="col-md-3 text-center" v-if="showSidebar">
4
+ <span class="d-inline-block" style="max-width: 100px;" v-html="item.icon.element" v-if="item.icon"></span>
5
+ </div>
6
+ <div :class="{'col-md-9': showSidebar, 'col-md-12': !showSidebar}">
7
+ <h5>{{ item.title }}</h5>
8
+ <div class="text-muted">{{ item.description }}</div>
9
+ <div class="ccm-help-media">
10
+ <component :key="action.component" v-for="action in item.actions" :is="action.component"
11
+ v-bind="action.componentProps"
12
+ ></component>
13
+ </div>
14
+ </div>
15
+ </section>
16
+ </template>
17
+
18
+ <script>
19
+ import ConcreteAnnouncementVideoAction from '../Action/VideoAction'
20
+ import ConcreteAnnouncementGuideAction from '../Action/GuideAction'
21
+ import ConcreteAnnouncementExternalLinkAction from '../Action/ExternalLinkAction'
22
+
23
+ export default {
24
+ components: {
25
+ ConcreteAnnouncementVideoAction,
26
+ ConcreteAnnouncementGuideAction,
27
+ ConcreteAnnouncementExternalLinkAction
28
+ },
29
+ props: {
30
+ indentIfIconEmpty: {
31
+ type: Boolean,
32
+ required: false,
33
+ default: true
34
+ },
35
+ item: {
36
+ type: Object,
37
+ required: true
38
+ }
39
+ },
40
+ computed: {
41
+ showSidebar() {
42
+ return this.item.icon || this.indentIfIconEmpty
43
+ }
44
+ },
45
+ data: () => ({
46
+ }),
47
+ methods: {
48
+ }
49
+ }
50
+ </script>