glib-web 0.5.77

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 (204) hide show
  1. package/.eslintrc.js +37 -0
  2. package/LICENSE +201 -0
  3. package/README.md +33 -0
  4. package/action.js +167 -0
  5. package/actions/analytics/logEvent.js +26 -0
  6. package/actions/auth/creditCard.js +29 -0
  7. package/actions/auth/restart.js +5 -0
  8. package/actions/auth/saveCsrfToken.js +12 -0
  9. package/actions/cables/push.js +38 -0
  10. package/actions/dialogs/alert.js +15 -0
  11. package/actions/dialogs/close.js +7 -0
  12. package/actions/dialogs/notification.js +14 -0
  13. package/actions/dialogs/oauth.js +6 -0
  14. package/actions/dialogs/open.js +7 -0
  15. package/actions/dialogs/options.js +5 -0
  16. package/actions/dialogs/show.js +5 -0
  17. package/actions/forms/submit.js +15 -0
  18. package/actions/http/delete.js +7 -0
  19. package/actions/http/patch.js +7 -0
  20. package/actions/http/post.js +7 -0
  21. package/actions/http/put.js +7 -0
  22. package/actions/panels/scrollTo.js +18 -0
  23. package/actions/panels/scrollToBottom.js +11 -0
  24. package/actions/runMultiple.js +11 -0
  25. package/actions/sheets/select.js +5 -0
  26. package/actions/snackbars/alert.js +15 -0
  27. package/actions/snackbars/select.js +5 -0
  28. package/actions/timeouts/set.js +20 -0
  29. package/actions/windows/close.js +13 -0
  30. package/actions/windows/closeAll.js +16 -0
  31. package/actions/windows/closeWithReload.js +18 -0
  32. package/actions/windows/open.js +5 -0
  33. package/actions/windows/openWeb.js +5 -0
  34. package/actions/windows/refreshState.js +5 -0
  35. package/actions/windows/reload.js +24 -0
  36. package/actions/ws/push.js +35 -0
  37. package/app.vue +180 -0
  38. package/components/_button.vue +101 -0
  39. package/components/_dropdownMenu.vue +76 -0
  40. package/components/_icon.vue +50 -0
  41. package/components/_message.vue +25 -0
  42. package/components/avatar.vue +16 -0
  43. package/components/banners/alert.vue +49 -0
  44. package/components/banners/select.vue +82 -0
  45. package/components/button.vue +13 -0
  46. package/components/calendar.vue +105 -0
  47. package/components/charts/column.vue +26 -0
  48. package/components/charts/line.vue +61 -0
  49. package/components/chip.vue +24 -0
  50. package/components/component.vue +222 -0
  51. package/components/datetime.vue +54 -0
  52. package/components/fab.vue +33 -0
  53. package/components/fields/_patternText.vue +61 -0
  54. package/components/fields/_select.vue +86 -0
  55. package/components/fields/autocomplete.vue +73 -0
  56. package/components/fields/check.vue +104 -0
  57. package/components/fields/checkGroup.vue +51 -0
  58. package/components/fields/country/countries.js +251 -0
  59. package/components/fields/country/field.vue +81 -0
  60. package/components/fields/country/regions.js +12 -0
  61. package/components/fields/creditCard.vue +105 -0
  62. package/components/fields/date.vue +24 -0
  63. package/components/fields/datetime.vue +49 -0
  64. package/components/fields/dynamicGroup.vue +106 -0
  65. package/components/fields/dynamicSelect.vue +173 -0
  66. package/components/fields/file.vue +166 -0
  67. package/components/fields/googlePlace.vue +158 -0
  68. package/components/fields/hidden.vue +18 -0
  69. package/components/fields/location.vue +223 -0
  70. package/components/fields/newRichText.vue +191 -0
  71. package/components/fields/phone/countries.js +315 -0
  72. package/components/fields/phone/field.vue +348 -0
  73. package/components/fields/phone/sprite.css +1071 -0
  74. package/components/fields/radio.vue +64 -0
  75. package/components/fields/radioGroup.vue +93 -0
  76. package/components/fields/rating.vue +26 -0
  77. package/components/fields/richText.vue +172 -0
  78. package/components/fields/select.vue +17 -0
  79. package/components/fields/stripe/stripeFields.vue +93 -0
  80. package/components/fields/stripe/stripeIndividualFields.vue +207 -0
  81. package/components/fields/stripeExternalAccount.vue +135 -0
  82. package/components/fields/stripeToken.vue +59 -0
  83. package/components/fields/submit.vue +23 -0
  84. package/components/fields/text.vue +144 -0
  85. package/components/fields/textarea.vue +59 -0
  86. package/components/fields/timeZone.vue +22 -0
  87. package/components/fields/timer.vue +83 -0
  88. package/components/h1.vue +28 -0
  89. package/components/h2.vue +20 -0
  90. package/components/h3.vue +22 -0
  91. package/components/h4.vue +20 -0
  92. package/components/h5.vue +20 -0
  93. package/components/h6.vue +20 -0
  94. package/components/hr.vue +13 -0
  95. package/components/html.vue +13 -0
  96. package/components/icon.vue +25 -0
  97. package/components/image.vue +87 -0
  98. package/components/label.vue +62 -0
  99. package/components/map.vue +206 -0
  100. package/components/markdown.vue +52 -0
  101. package/components/mixins/events.js +178 -0
  102. package/components/mixins/generic.js +58 -0
  103. package/components/mixins/list/autoload.js +144 -0
  104. package/components/mixins/longClick.js +56 -0
  105. package/components/mixins/scrolling.js +35 -0
  106. package/components/mixins/styles.js +221 -0
  107. package/components/mixins/table/autoload.js +131 -0
  108. package/components/mixins/table/export.js +52 -0
  109. package/components/mixins/table/import.js +106 -0
  110. package/components/mixins/text.js +20 -0
  111. package/components/mixins/ws/actionCable.js +48 -0
  112. package/components/mixins/ws/phoenixSocket.js +117 -0
  113. package/components/p.vue +36 -0
  114. package/components/panels/carousel.vue +55 -0
  115. package/components/panels/column.vue +117 -0
  116. package/components/panels/custom.vue +52 -0
  117. package/components/panels/flow.vue +81 -0
  118. package/components/panels/form.vue +126 -0
  119. package/components/panels/horizontal.vue +73 -0
  120. package/components/panels/list.vue +241 -0
  121. package/components/panels/responsive.vue +88 -0
  122. package/components/panels/scroll.vue +68 -0
  123. package/components/panels/split.vue +52 -0
  124. package/components/panels/table.vue +234 -0
  125. package/components/panels/ul.vue +34 -0
  126. package/components/panels/vertical.vue +71 -0
  127. package/components/panels/web.vue +11 -0
  128. package/components/spacer.vue +11 -0
  129. package/components/switch.vue +42 -0
  130. package/components/tabBar.vue +44 -0
  131. package/extensions/array.js +20 -0
  132. package/extensions/string.js +21 -0
  133. package/index.js +195 -0
  134. package/keys.js +12 -0
  135. package/nav/appbar.vue +117 -0
  136. package/nav/content.vue +40 -0
  137. package/nav/dialog.vue +127 -0
  138. package/nav/drawer.vue +88 -0
  139. package/nav/drawerButton.vue +28 -0
  140. package/nav/drawerLabel.vue +21 -0
  141. package/nav/sheet.vue +57 -0
  142. package/nav/snackbar.vue +72 -0
  143. package/package.json +42 -0
  144. package/settings.json.example +21 -0
  145. package/static/plugins/alignment/alignment.js +76 -0
  146. package/static/plugins/alignment/alignment.min.js +1 -0
  147. package/static/plugins/beyondgrammar/beyondgrammar.js +46 -0
  148. package/static/plugins/beyondgrammar/beyondgrammar.min.js +1 -0
  149. package/static/plugins/blockcode/blockcode.js +110 -0
  150. package/static/plugins/blockcode/blockcode.min.js +1 -0
  151. package/static/plugins/clips/clips.js +44 -0
  152. package/static/plugins/clips/clips.min.js +1 -0
  153. package/static/plugins/counter/counter.js +60 -0
  154. package/static/plugins/counter/counter.min.js +1 -0
  155. package/static/plugins/definedlinks/definedlinks.js +64 -0
  156. package/static/plugins/definedlinks/definedlinks.min.js +1 -0
  157. package/static/plugins/handle/handle.js +173 -0
  158. package/static/plugins/handle/handle.min.js +1 -0
  159. package/static/plugins/icons/icons.js +72 -0
  160. package/static/plugins/icons/icons.min.js +1 -0
  161. package/static/plugins/imageposition/imageposition.js +85 -0
  162. package/static/plugins/imageposition/imageposition.min.js +1 -0
  163. package/static/plugins/inlineformat/inlineformat.js +85 -0
  164. package/static/plugins/inlineformat/inlineformat.min.js +1 -0
  165. package/static/plugins/removeformat/removeformat.js +28 -0
  166. package/static/plugins/removeformat/removeformat.min.js +1 -0
  167. package/static/plugins/selector/selector.js +96 -0
  168. package/static/plugins/selector/selector.min.js +1 -0
  169. package/static/plugins/specialchars/specialchars.js +63 -0
  170. package/static/plugins/specialchars/specialchars.min.js +1 -0
  171. package/static/plugins/textdirection/textdirection.js +55 -0
  172. package/static/plugins/textdirection/textdirection.min.js +1 -0
  173. package/static/plugins/textexpander/textexpander.js +46 -0
  174. package/static/plugins/textexpander/textexpander.min.js +1 -0
  175. package/static/plugins/underline/underline.js +27 -0
  176. package/static/plugins/underline/underline.min.js +1 -0
  177. package/static/redactorx.css +1344 -0
  178. package/static/redactorx.js +14254 -0
  179. package/static/redactorx.min.css +1 -0
  180. package/static/redactorx.min.js +1 -0
  181. package/static/redactorx.usm.min.js +2 -0
  182. package/styles/test.sass +3 -0
  183. package/styles/test.scss +5 -0
  184. package/templates/_menu.vue +38 -0
  185. package/templates/comment.vue +202 -0
  186. package/templates/featured.vue +32 -0
  187. package/templates/thumbnail.vue +138 -0
  188. package/templates/unsupported.vue +12 -0
  189. package/utils/app.js +14 -0
  190. package/utils/dom.js +13 -0
  191. package/utils/form.js +34 -0
  192. package/utils/format.js +14 -0
  193. package/utils/hash.js +29 -0
  194. package/utils/helper.js +44 -0
  195. package/utils/history.js +70 -0
  196. package/utils/http.js +209 -0
  197. package/utils/launch.js +135 -0
  198. package/utils/private/ws.js +22 -0
  199. package/utils/public.js +23 -0
  200. package/utils/settings.js +48 -0
  201. package/utils/storage.js +9 -0
  202. package/utils/type.js +69 -0
  203. package/utils/uploader.js +121 -0
  204. package/utils/url.js +132 -0
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <v-form
3
+ ref="form"
4
+ :style="parentStyles"
5
+ :action="url"
6
+ :method="spec.method"
7
+ :data-local="spec.local"
8
+ @submit="onSubmit"
9
+ >
10
+ <template v-for="(value, key, index) in params">
11
+ <input
12
+ :key="`hidden_${index}`"
13
+ type="hidden"
14
+ :name="key"
15
+ :value="value"
16
+ />
17
+ </template>
18
+
19
+ <panels-responsive :spec="modifiedSpec" />
20
+ </v-form>
21
+ </template>
22
+
23
+ <script>
24
+ // import ActionsFormsSubmit from "../../actions/forms/submit";
25
+
26
+ export default {
27
+ props: {
28
+ spec: { type: Object, required: true }
29
+ },
30
+ data: () => ({
31
+ url: null,
32
+ params: null,
33
+ parentStyles: {},
34
+ formElement: null,
35
+ submitButtons: [],
36
+ modifiedSpec: {}
37
+ }),
38
+ watch: {
39
+ $isBusy: function(val, oldVal) {
40
+ for (const button of this.submitButtons) {
41
+ button._isBusy = val;
42
+ }
43
+ }
44
+ },
45
+ methods: {
46
+ $ready: function() {
47
+ this.$onEvent("forms/addSubmit", e => {
48
+ this.submitButtons.push(e.data);
49
+ });
50
+
51
+ this.$onEvent("forms/setBusy", e => {
52
+ if (e.data.value) {
53
+ Utils.http.startIndicator(this);
54
+ } else {
55
+ Utils.http.stopIndicator(this);
56
+ }
57
+ });
58
+
59
+ this.formElement = this.$refs.form.$el;
60
+ this.parentStyles = this.genericStyles({ width: this.spec.width });
61
+
62
+ const { url: url, params: params } = Utils.url.extractFormActionData(
63
+ this.spec.url,
64
+ this.spec.local
65
+ );
66
+ this.url = url;
67
+ this.params = params;
68
+
69
+ let firstAutoFocus = false;
70
+ this.modifiedSpec = this.spec;
71
+ this.modifiedSpec.childViews.map(childView => {
72
+ if (
73
+ childView.view.startsWith("fields/") &&
74
+ childView.view !== "fields/hidden-v1" &&
75
+ !firstAutoFocus
76
+ ) {
77
+ childView.autoFocus = true;
78
+ firstAutoFocus = true;
79
+ }
80
+
81
+ return childView;
82
+ });
83
+ },
84
+ onSubmit(event) {
85
+ event.preventDefault();
86
+ event.stopPropagation();
87
+
88
+ this.submit();
89
+ },
90
+ submit() {
91
+ if (this.$refs.form.validate()) {
92
+ // Remove focus from current input field to avoid double submit if the user presses ENTER again.
93
+ document.activeElement.blur();
94
+
95
+ Utils.type.ifObject(
96
+ this.spec.onSubmit,
97
+ onSubmit => {
98
+ const formData = Utils.url.toMap(new FormData(this.formElement));
99
+ const params = {
100
+ [this.spec.paramNameForFormData || "formData"]: formData
101
+ };
102
+ const data = Object.assign({}, onSubmit, params);
103
+ GLib.action.execute(data, null, this);
104
+ },
105
+ () => {
106
+ GLib.form.submitData(this.formElement, this);
107
+ }
108
+ );
109
+ } else {
110
+ Utils.launch.alert("Make sure all fields are valid");
111
+ }
112
+ },
113
+ action_clear() {
114
+ this.formElement.reset();
115
+ }
116
+ }
117
+ };
118
+ </script>
119
+
120
+ <style scoped>
121
+ /* .panels-form {
122
+ display: flex;
123
+ flex-direction: column;
124
+ align-items: flex-start;
125
+ } */
126
+ </style>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <div :class="cssClasses" :style="cssStyles">
3
+ <template v-for="(item, index) in spec.childViews">
4
+ <ui-component :key="index" :spec="item" />
5
+ </template>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ export default {
11
+ props: {
12
+ spec: { type: Object, required: true }
13
+ },
14
+ computed: {
15
+ cssClasses: function() {
16
+ const classes = this.$classes().concat("layouts-horizontal");
17
+ switch (this.spec.distribution) {
18
+ case "fillEqually":
19
+ classes.push("layouts-horizontal--fill-equally");
20
+ break;
21
+ case "spaceEqually":
22
+ classes.push("layouts-horizontal--space-equally");
23
+ break;
24
+ }
25
+ return classes;
26
+ },
27
+ cssStyles: function() {
28
+ const styles = this.genericStyles();
29
+ switch (this.spec.align) {
30
+ case "middle":
31
+ styles["align-items"] = "center";
32
+ break;
33
+ case "bottom":
34
+ styles["align-items"] = "flex-end";
35
+ break;
36
+ default:
37
+ styles["align-items"] = "flex-start";
38
+ }
39
+ return styles;
40
+ }
41
+ },
42
+ methods: {
43
+ $displayValue() {
44
+ return "flex";
45
+ }
46
+ }
47
+ };
48
+ </script>
49
+
50
+ <style scoped>
51
+ .layouts-horizontal {
52
+ display: flex;
53
+ /* overflow: hidden; */
54
+ }
55
+
56
+ /* From https://stackoverflow.com/questions/13483331/make-buttons-same-width-without-specifying-exact-size */
57
+ .layouts-horizontal--space-equally {
58
+ justify-content: space-around;
59
+ }
60
+ </style>
61
+
62
+ <style>
63
+ .layouts-horizontal--fill-equally > * {
64
+ flex: initial;
65
+ width: 100%;
66
+ }
67
+ .layouts-horizontal--space-equally > * {
68
+ flex: initial;
69
+ }
70
+ /* .layouts-horizontal > div {
71
+ display: inline-block;
72
+ } */
73
+ </style>
@@ -0,0 +1,241 @@
1
+ <template>
2
+ <v-list
3
+ :two-line="twoLine"
4
+ :three-line="threeLine"
5
+ class="py-0"
6
+ :style="genericStyles()"
7
+ >
8
+ <div ref="topAnchor"></div>
9
+
10
+ <template v-for="(section, sectionIndex) in sections">
11
+ <div :key="`section${sectionIndex}`">
12
+ <panels-responsive v-if="section.header" :spec="section.header" />
13
+
14
+ <draggable
15
+ v-model="section.rows"
16
+ ghost-class="ghost"
17
+ group="a"
18
+ handle=".handle"
19
+ :data-index="sectionIndex"
20
+ @end="onDragEnd"
21
+ >
22
+ <div
23
+ v-for="(row, rowIndex) in section.rows"
24
+ :key="`${sectionIndex}_${rowIndex}`"
25
+ :class="row.styleClasses"
26
+ >
27
+ <v-divider v-if="rowIndex == 0" />
28
+
29
+ <component :is="template(row)" :spec="row" :index="rowIndex" />
30
+ <v-divider
31
+ v-if="
32
+ rowIndex != section.rows.length - 1 ||
33
+ sectionIndex != sections.length - 1
34
+ "
35
+ />
36
+ </div>
37
+ </draggable>
38
+
39
+ <panels-responsive v-if="section.footer" :spec="section.footer" />
40
+ </div>
41
+ </template>
42
+
43
+ <div ref="bottomAnchor" class="py-3 px-4" :style="bottomAnchorStyles">
44
+ Loading...
45
+ </div>
46
+ </v-list>
47
+ </template>
48
+
49
+ <script>
50
+ import draggable from "vuedraggable";
51
+ import autoloadMixin from "../mixins/list/autoload.js";
52
+ import ThumbnailTemplate from "../../templates/thumbnail";
53
+ import FeaturedTemplate from "../../templates/featured";
54
+ import CommentTemplate from "../../templates/comment";
55
+ import actionCableMixin from "../mixins/ws/actionCable.js";
56
+
57
+ export default {
58
+ components: {
59
+ draggable,
60
+ "template-thumbnail": ThumbnailTemplate,
61
+ "template-featured": FeaturedTemplate,
62
+ "template-commentOutgoing": CommentTemplate,
63
+ "template-commentIncoming": CommentTemplate
64
+ },
65
+ mixins: [autoloadMixin, actionCableMixin],
66
+ props: {
67
+ spec: { type: Object, required: true }
68
+ },
69
+ data: function() {
70
+ return {
71
+ sections: []
72
+ };
73
+ },
74
+ computed: {
75
+ twoLine() {
76
+ for (const section of this.sections) {
77
+ const rows = section.rows || [];
78
+ for (const row of rows) {
79
+ if (row.subtitle) {
80
+ return true;
81
+ }
82
+ }
83
+ }
84
+ return false;
85
+ },
86
+ threeLine() {
87
+ for (const section of this.sections) {
88
+ const rows = section.rows || [];
89
+ for (const row of rows) {
90
+ if (row.subsubtitle) {
91
+ return true;
92
+ }
93
+ }
94
+ }
95
+ return false;
96
+ }
97
+ },
98
+ methods: {
99
+ $ready() {
100
+ this.sections = this.spec.sections || [];
101
+ this.autoloadAll(this.spec.nextPage);
102
+ this.enableInfiniteScrollIfApplicable();
103
+ this.$wsSubscribeEvents(this.spec.phoenixSocket);
104
+ this.$wsInitActionCable(this.spec.actionCable);
105
+
106
+ for (const section of this.sections) {
107
+ section.rows = section.rows || [];
108
+ }
109
+ },
110
+ action_loadNext(spec) {
111
+ console.log("TODO: load new comments and append to this list", spec);
112
+ // TODO
113
+ // - Load next rows/items from the Rails server
114
+ // - You can pass some parameters (e.g. currentItemId) for pagination
115
+ // - For example, if currentItemId is 56, the server will know that it needs to
116
+ // return items that are newer than 56
117
+ // - You may use other ways for pagination as well
118
+ // - Append the rows to this list
119
+ },
120
+ action_append(spec) {
121
+ for (const [index, appendedSection] of spec.sections.entries()) {
122
+ const section = this.sections[index] || {};
123
+
124
+ if (!section.rows) {
125
+ this.$set(section, "rows", []);
126
+ }
127
+
128
+ Utils.type.ifArray(appendedSection.rows, rows => {
129
+ for (const row of rows) {
130
+ section.rows.push(row);
131
+ }
132
+ });
133
+ }
134
+ },
135
+ action_update(spec) {
136
+ const updatedRows = {};
137
+
138
+ Utils.type.ifArray(spec.rows, rows => {
139
+ for (const row of rows) {
140
+ updatedRows[row.id] = row;
141
+ }
142
+ });
143
+
144
+ for (const section of this.sections) {
145
+ section.rows = section.rows.map(row => {
146
+ const updatedRow = updatedRows[row.id];
147
+ if (updatedRow) {
148
+ return updatedRow;
149
+ } else {
150
+ return row;
151
+ }
152
+ });
153
+ }
154
+ },
155
+ action_delete(spec) {
156
+ const deletedRows = {};
157
+ Utils.type.ifArray(spec.rows, rows => {
158
+ for (const row of rows) {
159
+ deletedRows[row.id] = row;
160
+ }
161
+ });
162
+
163
+ for (const section of this.sections) {
164
+ section.rows = section.rows.filter(row => {
165
+ // return !rows.includes(row.id);
166
+ return !deletedRows[row.id];
167
+ });
168
+ }
169
+ },
170
+ $tearDown() {
171
+ this.cancelAutoloadRequest();
172
+ },
173
+ template(row) {
174
+ const name = `template-${row.template.replace("/", "-")}`;
175
+ const strict = true;
176
+ if (strict) {
177
+ return name;
178
+ } else {
179
+ if (this.$options.components[name]) {
180
+ return name;
181
+ }
182
+ console.warn(`Invalid template: ${row.template}`);
183
+ return null;
184
+ }
185
+ },
186
+ serializedSpec(row) {
187
+ return JSON.stringify(row);
188
+ },
189
+ onDragEnd(event) {
190
+ const targetSectionedRowIndex = event.newIndex;
191
+ if (event.from == event.to && event.oldIndex == targetSectionedRowIndex) {
192
+ console.log("Reordering canceled");
193
+ return;
194
+ }
195
+
196
+ const targetSectionIndex = this.getSectionIndex(event.to);
197
+ const targetSection = this.getSection(targetSectionIndex);
198
+ // The dragged row is now on the new index
199
+ const draggedRow = targetSection.rows[targetSectionedRowIndex];
200
+
201
+ const targetAbsoluteIndex =
202
+ this.previousSectionsRowCount(event.to) + targetSectionedRowIndex;
203
+
204
+ const mergedSpec = Object.assign(draggedRow.onReorder, {
205
+ [draggedRow.paramNameForFormData || "formData"]: {
206
+ [draggedRow.paramNameForNewIndex]: targetAbsoluteIndex, // Deprecated
207
+ [draggedRow.paramNameForNewAbsoluteIndex ||
208
+ "newAbsoluteIndex"]: targetAbsoluteIndex,
209
+ [draggedRow.paramNameForNewSectionIndex ||
210
+ "newSectionIndex"]: targetSectionIndex,
211
+ [draggedRow.paramNameForNewSectionedRowIndex ||
212
+ "newSectionedRowIndex"]: targetSectionedRowIndex
213
+ }
214
+ });
215
+
216
+ GLib.action.execute(mergedSpec, null, this);
217
+ },
218
+ getSectionIndex(element) {
219
+ return element.dataset.index;
220
+ },
221
+ getSection(sectionIndex) {
222
+ return this.sections[sectionIndex];
223
+ },
224
+ previousSectionsRowCount(element) {
225
+ const sectionIndex = this.getSectionIndex(element);
226
+ let count = 0;
227
+ for (let i = 0; i < sectionIndex; i++) {
228
+ count += this.getSection(i).rows.length;
229
+ }
230
+ return count;
231
+ }
232
+ }
233
+ };
234
+ </script>
235
+
236
+ <style lang="scss" scoped>
237
+ .ghost {
238
+ opacity: 0.5;
239
+ background: #dddddd;
240
+ }
241
+ </style>
@@ -0,0 +1,88 @@
1
+ <template>
2
+ <div
3
+ :class="cssClasses"
4
+ :style="$styles()"
5
+ :href="$href()"
6
+ @click="$onClick()"
7
+ >
8
+ <v-row no-gutters class="full-height">
9
+ <template v-for="(item, index) in spec.childViews">
10
+ <ui-component
11
+ v-if="isColumn(item)"
12
+ :key="viewKey(item, index)"
13
+ :spec="item"
14
+ />
15
+ <div
16
+ v-else
17
+ :key="viewKey(item, index)"
18
+ class="full-width"
19
+ :style="innerStyles"
20
+ >
21
+ <ui-component :spec="item" />
22
+ </div>
23
+ </template>
24
+ </v-row>
25
+ </div>
26
+ </template>
27
+
28
+ <script>
29
+ import Vue from "vue";
30
+
31
+ export default {
32
+ props: {
33
+ spec: { type: Object, required: true }
34
+ },
35
+ data() {
36
+ return {
37
+ innerStyles: {}
38
+ };
39
+ },
40
+ computed: {
41
+ cssClasses() {
42
+ // This panel will be nameless when used in predefined layout (e.g. page.body, list.header, etc.)
43
+ this.spec.view = this.spec.view || "panels/responsive";
44
+ return this.$classes();
45
+ }
46
+ },
47
+ methods: {
48
+ $ready() {
49
+ let align = null;
50
+ switch (this.spec.align) {
51
+ case "center":
52
+ align = "center";
53
+ break;
54
+ case "right":
55
+ align = "flex-end";
56
+ break;
57
+ default:
58
+ align = "flex-start";
59
+ }
60
+ Vue.set(this.innerStyles, "align-items", align);
61
+ },
62
+ isColumn(item) {
63
+ return item.view == "panels/column-v1";
64
+ },
65
+ viewKey(item, index) {
66
+ // Use view name for key to avoid component reuse issue
67
+ return `view${index}_${item.view}`;
68
+ }
69
+ }
70
+ };
71
+ </script>
72
+
73
+ <style scoped>
74
+ .row {
75
+ margin-left: 0;
76
+ margin-right: 0;
77
+ }
78
+ .full-width {
79
+ width: 100%;
80
+ flex: 0 0 100%;
81
+ display: flex;
82
+ flex-direction: column;
83
+ }
84
+ /* Needed to ensure that split's sub panels have the same height */
85
+ .full-height {
86
+ height: 100%;
87
+ }
88
+ </style>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <div :class="cssClasses" :style="cssStyles">
3
+ <!-- <template v-for="(item, index) in spec.childViews">
4
+ <ui-component :key="`${index}_${item.view}`" :spec="item" />
5
+ </template> -->
6
+ <panels-responsive :spec="spec" />
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ // import Hash from "../../utils/hash";
12
+
13
+ export default {
14
+ props: {
15
+ spec: { type: Object, required: true }
16
+ },
17
+ computed: {
18
+ cssClasses() {
19
+ const classes = this.$classes().concat("layouts-scroll");
20
+ return classes;
21
+ },
22
+ cssStyles() {
23
+ // // Let the styles be handled by the child panel.
24
+ // const outerSpec = {};
25
+ // outerSpec["padding"] = this.spec["outerPadding"];
26
+ // console.log("outerSpec", outerSpec);
27
+ // const styles = this.$styles(outerSpec);
28
+ //
29
+ // const styles = this.genericStyles();
30
+ // styles.remove("padding-top");
31
+ // styles.remove("padding-bottom");
32
+ // styles.remove("padding-left");
33
+ // styles.remove("padding-right");
34
+ //
35
+ // const styles = this.$styles({
36
+ // width: this.spec.width,
37
+ // height: this.spec.height
38
+ // });
39
+ //
40
+ // console.log("styles", styles);
41
+
42
+ // Let the specified styles be handled by the child panel.
43
+ const styles = this.$styles({
44
+ width: "matchParent"
45
+ });
46
+ return styles;
47
+ }
48
+ }
49
+ };
50
+ </script>
51
+
52
+ <style lang="scss" scoped>
53
+ .layouts-scroll {
54
+ overflow: auto;
55
+ display: flex;
56
+ flex-direction: column;
57
+
58
+ &::-webkit-scrollbar {
59
+ width: 5px;
60
+ height: 8px;
61
+ background-color: #eee;
62
+ }
63
+
64
+ &::-webkit-scrollbar-thumb {
65
+ background: #aaa;
66
+ }
67
+ }
68
+ </style>
@@ -0,0 +1,52 @@
1
+ <template v-if="content">
2
+ <div :class="classes()" :style="genericStyles()">
3
+ <div v-if="spec.left" class="layouts-split__side">
4
+ <panels-responsive :spec="spec.left" />
5
+ </div>
6
+
7
+ <div class="layouts-split__expand">
8
+ <panels-responsive v-if="spec.center" :spec="spec.center" />
9
+ </div>
10
+
11
+ <!-- <ui-component :spec="spec.centerView" v-if="spec.centerView" class="panels-split__expand"/>
12
+ <div class="panels-split__expand" v-else></div> -->
13
+
14
+ <div v-if="spec.right" class="layouts-split__side layouts-split__right">
15
+ <panels-responsive :spec="spec.right" />
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script>
21
+ export default {
22
+ props: {
23
+ spec: { type: Object, required: true }
24
+ },
25
+ methods: {
26
+ classes: function() {
27
+ return this.$classes().concat("layouts-split");
28
+ }
29
+ }
30
+ };
31
+ </script>
32
+
33
+ <style scoped>
34
+ .layouts-split {
35
+ display: flex;
36
+ }
37
+
38
+ .layouts-split__expand {
39
+ flex: 1 auto;
40
+ line-height: 1;
41
+ }
42
+
43
+ .layouts-split__side {
44
+ /* Make the side panels take full height */
45
+ display: flex;
46
+ }
47
+
48
+ .layouts-split__right {
49
+ /* Prevent unnecessary squashing, i.e. text broken into multiple lines */
50
+ flex-shrink: 0;
51
+ }
52
+ </style>