glib-web 2.2.1 → 2.3.0

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 (60) hide show
  1. package/LICENSE +0 -0
  2. package/action.js +24 -2
  3. package/actions/auth/restart.js +0 -0
  4. package/actions/commands/custom.js +10 -0
  5. package/actions/components/update.js +7 -4
  6. package/actions/dialogs/oauth.js +0 -0
  7. package/actions/dialogs/options.js +0 -0
  8. package/actions/windows/openWeb.js +0 -0
  9. package/app.vue +51 -29
  10. package/components/_button.vue +3 -1
  11. package/components/_chip.vue +20 -28
  12. package/components/_message.vue +0 -0
  13. package/components/_responsive.vue +14 -12
  14. package/components/_tooltip.vue +50 -0
  15. package/components/avatar.vue +3 -22
  16. package/components/button.vue +5 -31
  17. package/components/charts/column.vue +2 -2
  18. package/components/charts/line.vue +2 -2
  19. package/components/chip.vue +0 -19
  20. package/components/datetime.vue +0 -0
  21. package/components/fab.vue +0 -0
  22. package/components/fields/_select.vue +12 -6
  23. package/components/fields/country/countries.js +0 -0
  24. package/components/fields/country/field.vue +0 -0
  25. package/components/fields/country/regions.js +0 -0
  26. package/components/fields/datetime.vue +0 -0
  27. package/components/fields/dynamicSelect.vue +0 -0
  28. package/components/fields/radio.vue +24 -18
  29. package/components/fields/richText.vue +1 -1
  30. package/components/fields/select.vue +15 -1
  31. package/components/fields/timeZone.vue +0 -0
  32. package/components/hr.vue +0 -0
  33. package/components/html.vue +0 -0
  34. package/components/image.vue +6 -13
  35. package/components/mixins/longClick.js +0 -0
  36. package/components/mixins/scrolling.js +0 -0
  37. package/components/mixins/table/export.js +0 -0
  38. package/components/mixins/table/import.js +0 -0
  39. package/components/p.vue +0 -0
  40. package/components/panels/column.vue +14 -2
  41. package/components/panels/responsive.vue +8 -2
  42. package/components/panels/ul.vue +3 -0
  43. package/index.js +3 -0
  44. package/keys.js +0 -0
  45. package/nav/drawerButton.vue +0 -0
  46. package/package.json +1 -1
  47. package/plugins/updatableComponent.js +14 -5
  48. package/settings.json.example +0 -0
  49. package/styles/test.sass +0 -0
  50. package/styles/test.scss +0 -0
  51. package/templates/unsupported.vue +0 -0
  52. package/utils/app.js +1 -0
  53. package/utils/component.js +12 -0
  54. package/utils/dom.js +0 -0
  55. package/utils/public.js +4 -0
  56. package/utils/settings.js +0 -0
  57. package/utils/storage.js +0 -0
  58. package/utils/url.js +0 -0
  59. package/components/mixins/tooltip.js +0 -20
  60. package/nav/content.vue +0 -40
package/LICENSE CHANGED
File without changes
package/action.js CHANGED
@@ -49,6 +49,7 @@ import ActionsCreditCard from "./actions/auth/creditCard";
49
49
  import ActionsAnalyticsLogEvent from "./actions/analytics/logEvent";
50
50
 
51
51
  import ActionCommandsCopy from "./actions/commands/copy";
52
+ import ActionCommandsCustom from "./actions/commands/custom";
52
53
 
53
54
  import ActionToursStart from "./actions/tours/start";
54
55
 
@@ -102,11 +103,16 @@ const actions = {
102
103
  "auth/creditCard": ActionsCreditCard,
103
104
 
104
105
  "analytics/logEvent": ActionsAnalyticsLogEvent,
106
+
105
107
  "commands/copy": ActionCommandsCopy,
108
+ "commands/custom": ActionCommandsCustom,
109
+
106
110
  "tours/start": ActionToursStart,
107
111
  "components/update": ActionComponentsUpdate
108
112
  };
109
113
 
114
+ const customActions = {};
115
+
110
116
  export default class Action {
111
117
  static execute(spec, component, params = {}) {
112
118
  if (!TypeUtils.isObject(spec)) {
@@ -148,17 +154,21 @@ export default class Action {
148
154
  }
149
155
 
150
156
  static executeGlobal(name, spec, component, params) {
157
+ this._executeInternal(name, spec, component, params, actions);
158
+ }
159
+
160
+ static _executeInternal(name, spec, component, params, registry) {
151
161
  const actionName = name.replace(/-v1$/, "");
152
162
 
153
163
  try {
154
- const action = new actions[actionName]();
164
+ const action = new registry[actionName]();
155
165
  const logDisabled = action.logDisabled && action.logDisabled();
156
166
  if (!logDisabled) {
157
167
  console.log(`Executing "${actionName}"`);
158
168
  }
159
169
  action.execute(spec, component, params);
160
170
  } catch (e) {
161
- console.log(
171
+ console.error(
162
172
  "Failed executing command",
163
173
  actionName,
164
174
  `Error: '${e.message}'`
@@ -178,6 +188,18 @@ export default class Action {
178
188
  GLib.action.execute(response.onResponse, component);
179
189
  window.vueApp.temp.analytics = null;
180
190
  }
191
+
192
+ static registerCustom(actionName, action) {
193
+ if (customActions[actionName]) {
194
+ console.error("Command already registered", actionName);
195
+ } else {
196
+ customActions[actionName] = action;
197
+ }
198
+ }
199
+
200
+ static executeCustom(name, spec, component, params) {
201
+ this._executeInternal(name, spec, component, params, customActions);
202
+ }
181
203
  }
182
204
 
183
205
  window.Action = Action;
File without changes
@@ -0,0 +1,10 @@
1
+ import Hash from "../../utils/hash";
2
+
3
+ export default class {
4
+ execute(spec, component) {
5
+ const properties = new Hash(spec.properties);
6
+ // `spec` might contain params that were coming from other actions (e.g. `formData`).
7
+ Object.assign(properties, spec);
8
+ GLib.action.executeCustom(spec.name, properties, component);
9
+ }
10
+ }
@@ -5,11 +5,14 @@ export default class {
5
5
  if (!spec.views.length > 1) {
6
6
  console.warn("Make sure views only have 1 child!");
7
7
  }
8
- const target = component.updatables[spec.targetId];
9
- if (!target) console.error("no component found :" + spec.targetId);
8
+ // const target = component.updatables[spec.targetId];
9
+ // if (!target) console.error("no component found :" + spec.targetId);
10
10
 
11
- Object.assign(target.spec, spec.views[0]);
12
- this.updateComponent(target);
11
+ const target = GLib.component.findById(spec.targetId);
12
+ if (target) {
13
+ Object.assign(target.spec, spec.views[0]);
14
+ this.updateComponent(target);
15
+ }
13
16
  }
14
17
 
15
18
  updateComponent(component) {
File without changes
File without changes
File without changes
package/app.vue CHANGED
@@ -1,7 +1,11 @@
1
1
  <template>
2
2
  <v-app :class="page.styleClasses">
3
- <component :is="containerComponent" :spec="formSpec">
4
- <nav-appbar :page="page" />
3
+ <component
4
+ :is="containerComponent"
5
+ :spec="formSpec"
6
+ :style="'height: 100%;'"
7
+ >
8
+ <nav-appbar ref="appBar" :page="page" />
5
9
 
6
10
  <v-progress-linear
7
11
  v-if="$root.vueApp.indicator"
@@ -11,29 +15,24 @@
11
15
  >
12
16
  </v-progress-linear>
13
17
 
14
- <div class="pages-header">
15
- <layouts-content
16
- :template="page.template"
17
- :spec="header"
18
- :full-height="false"
19
- />
20
- </div>
21
-
22
- <div id="page_body" class="pages-body body-wrapper">
23
- <layouts-content
24
- :template="page.template"
25
- :spec="body"
26
- :full-height="true"
27
- />
28
- </div>
29
-
30
- <div class="pages-footer">
31
- <layouts-content
32
- :template="page.template"
33
- :spec="footer"
34
- :full-height="false"
35
- />
36
- </div>
18
+ <v-main :style="`height: ${mainHeight}px;`">
19
+ <v-container
20
+ :fluid="page.template == 'fullWidth'"
21
+ :class="containerClasses"
22
+ >
23
+ <div class="pages-header">
24
+ <panels-responsive :spec="header" />
25
+ </div>
26
+
27
+ <div id="page_body" class="pages-body body-wrapper">
28
+ <panels-responsive :spec="body" />
29
+ </div>
30
+
31
+ <div class="pages-footer">
32
+ <panels-responsive :spec="footer" />
33
+ </div>
34
+ </v-container>
35
+ </v-main>
37
36
  </component>
38
37
  </v-app>
39
38
  </template>
@@ -41,7 +40,6 @@
41
40
  <script>
42
41
  import NavAppBar from "./nav/appbar";
43
42
  import Utils from "./utils/helper";
44
- import ContentLayout from "./nav/content";
45
43
  import phoenixSocketMixin from "./components/mixins/ws/phoenixSocket.js";
46
44
  import actionCableMixin from "./components/mixins/ws/actionCable.js";
47
45
  import FormPanel from "./components/panels/form";
@@ -49,7 +47,6 @@ import FormPanel from "./components/panels/form";
49
47
  export default {
50
48
  components: {
51
49
  "nav-appbar": NavAppBar,
52
- "layouts-content": ContentLayout,
53
50
  "panels-form": FormPanel
54
51
  },
55
52
  mixins: [phoenixSocketMixin, actionCableMixin],
@@ -58,7 +55,8 @@ export default {
58
55
  },
59
56
  data() {
60
57
  return {
61
- title: "..."
58
+ title: "...",
59
+ mainHeight: 0
62
60
  };
63
61
  },
64
62
  computed: {
@@ -77,6 +75,11 @@ export default {
77
75
  }
78
76
  return "div";
79
77
  },
78
+ containerClasses() {
79
+ const classes = ["hamburger"];
80
+ classes.push(this.page.containerStyleClasses || []);
81
+ return classes;
82
+ },
80
83
  // Use computed to ensure that the spec gets updated when the user navigates to another page.
81
84
  formSpec() {
82
85
  return this.page.fullPageForm;
@@ -96,6 +99,15 @@ export default {
96
99
  Utils.http.promptIfDirtyOnUnload();
97
100
  },
98
101
  methods: {
102
+ $mounted() {
103
+ window.addEventListener(
104
+ "resize",
105
+ event => {
106
+ this.updateMainHeight();
107
+ },
108
+ true
109
+ );
110
+ },
99
111
  $ready() {
100
112
  document.title = this.page.title;
101
113
 
@@ -125,6 +137,15 @@ export default {
125
137
  GLib.action.execute(this.page.onLoad, this);
126
138
  });
127
139
  }
140
+
141
+ // Use nextTick() to allow time for the appBar to complete initialization.
142
+ this.$nextTick(() => {
143
+ this.updateMainHeight();
144
+ });
145
+ },
146
+ updateMainHeight() {
147
+ console.debug("Setting body height");
148
+ this.mainHeight = window.innerHeight - this.$refs.appBar.$el.offsetHeight;
128
149
  }
129
150
  }
130
151
  };
@@ -178,11 +199,12 @@ body,
178
199
 
179
200
  <style scoped>
180
201
  /*** Header/footer support ***/
181
- .application--wrap {
202
+ .hamburger {
182
203
  display: flex;
183
204
  flex-direction: column;
184
205
  justify-content: space-between;
185
206
  height: 100%;
207
+ padding: 0;
186
208
  }
187
209
 
188
210
  .body-wrapper {
@@ -15,6 +15,7 @@
15
15
  :rounded="$classes().includes('rounded')"
16
16
  :depressed="$classes().includes('depressed')"
17
17
  @click="type == 'submit' ? null : $onClick()"
18
+ v-on="eventHandlers"
18
19
  >
19
20
  <span><common-icon :spec="spec.icon || {}"/></span>
20
21
  <div :class="hideTextOnXs && spec.icon ? 'd-none d-sm-flex' : null">
@@ -30,7 +31,8 @@ export default {
30
31
  spec: { type: Object, required: true },
31
32
  type: { type: String, default: "button" },
32
33
  disabled: { type: Boolean, required: true },
33
- hideTextOnXs: { type: Boolean }
34
+ hideTextOnXs: { type: Boolean },
35
+ eventHandlers: { type: Object, default: null }
34
36
  },
35
37
  data: function() {
36
38
  return {
@@ -1,37 +1,29 @@
1
1
  <template>
2
- <v-tooltip
3
- :disabled="!spec.tooltip"
4
- :top="tooltipPositionMatches('top')"
5
- :right="tooltipPositionMatches('right')"
6
- :bottom="tooltipPositionMatches('bottom')"
7
- :left="tooltipPositionMatches('left')"
8
- >
2
+ <common-tooltip :spec="spec">
9
3
  <template v-slot:activator="{ on }">
10
- <span v-on="on">
11
- <common-badge :spec="spec">
12
- <v-chip
13
- v-if="spec.onClick"
14
- :style="genericStyles()"
15
- :class="$classes()"
16
- :href="$href()"
17
- @click="$onClick()"
18
- >
19
- {{ spec.text }}
20
- </v-chip>
21
- <v-chip v-else :style="genericStyles()" :class="$classes()">
22
- {{ spec.text }}
23
- </v-chip>
24
- </common-badge>
25
- </span>
4
+ <common-badge :spec="spec">
5
+ <v-chip
6
+ v-if="spec.onClick"
7
+ :style="genericStyles()"
8
+ :class="$classes()"
9
+ :href="$href()"
10
+ @click="$onClick()"
11
+ v-on="on"
12
+ >
13
+ {{ spec.text }}
14
+ </v-chip>
15
+ <v-chip v-else :style="genericStyles()" :class="$classes()" v-on="on">
16
+ {{ spec.text }}
17
+ </v-chip>
18
+ </common-badge>
26
19
  </template>
27
- <span>{{ tooltip.text }}</span>
28
- </v-tooltip>
20
+ </common-tooltip>
29
21
  </template>
30
22
 
31
23
  <script>
32
- import TooltipMixins from "./mixins/tooltip";
24
+ // import TooltipMixins from "./mixins/tooltip";
33
25
  export default {
34
- mixins: [TooltipMixins],
26
+ // mixins: [TooltipMixins],
35
27
  props: {
36
28
  spec: { type: Object, required: true }
37
29
  },
@@ -50,7 +42,7 @@ export default {
50
42
 
51
43
  <style lang="scss" scoped>
52
44
  // Prevent hover effect if the chip is not clickable.
53
- span.theme--light.v-chip:hover:before {
45
+ .v-chip:not(.v-chip--clickable).theme--light:hover:before {
54
46
  opacity: 0;
55
47
  }
56
48
  </style>
File without changes
@@ -5,6 +5,7 @@
5
5
  :style="$styles()"
6
6
  :href="$href()"
7
7
  @click="$onClick()"
8
+ v-on="eventHandlers"
8
9
  >
9
10
  <v-row no-gutters class="full-height">
10
11
  <template v-for="(item, index) in spec.childViews">
@@ -31,13 +32,8 @@ import Vue from "vue";
31
32
 
32
33
  export default {
33
34
  props: {
34
- spec: {
35
- type: Object,
36
- required: true,
37
- default: function() {
38
- return {};
39
- }
40
- }
35
+ spec: { type: Object, required: true },
36
+ eventHandlers: { type: Object, default: null }
41
37
  },
42
38
  data() {
43
39
  return {
@@ -46,12 +42,18 @@ export default {
46
42
  },
47
43
  computed: {
48
44
  cssClasses() {
49
- // This panel will be nameless when used in predefined layout (e.g. page.body, list.header, etc.)
50
- this.spec.view = this.spec.view || "panels/responsive";
51
- return this.$classes();
45
+ // Provide a default name so the panel will not be nameless when used in predefined layouts (e.g. page.body, list.header, etc.)
46
+ return this.$classes(
47
+ Object.assign(
48
+ {
49
+ view: "panels/responsive"
50
+ },
51
+ this.spec
52
+ )
53
+ );
52
54
  },
53
55
  componentName() {
54
- return this.$href() ? "a" : "div";
56
+ return this.spec.onClick ? "a" : "div";
55
57
  }
56
58
  },
57
59
  methods: {
@@ -91,7 +93,7 @@ export default {
91
93
  display: flex;
92
94
  flex-direction: column;
93
95
  }
94
- /* Needed to ensure that split's sub panels have the same height */
96
+ // Needed to ensure that split's sub panels have the same height
95
97
  .full-height {
96
98
  height: 100%;
97
99
  }
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <v-tooltip
3
+ :disabled="tooltip.disabled"
4
+ :top="tooltipPositionMatches('top')"
5
+ :right="tooltipPositionMatches('right')"
6
+ :bottom="tooltipPositionMatches('bottom')"
7
+ :left="tooltipPositionMatches('left')"
8
+ >
9
+ <template v-slot:activator="{ on }">
10
+ <!-- Pass the slot props through to the caller using the same slot name (i.e. `activator`) -->
11
+ <slot name="activator" :on="on" />
12
+ </template>
13
+ <span> {{ tooltip.text }} </span>
14
+ </v-tooltip>
15
+ </template>
16
+
17
+ <script>
18
+ // import tooltipMixin from "./mixins/tooltip";
19
+
20
+ export default {
21
+ // mixins: [tooltipMixin],
22
+ props: {
23
+ spec: { type: Object, required: true }
24
+ },
25
+ data() {
26
+ return {
27
+ tooltip: {},
28
+ childSpec: Object.assign({}, this.spec, { id: undefined })
29
+ };
30
+ },
31
+ methods: {
32
+ $ready() {
33
+ this.tooltip = this.spec.tooltip || { disabled: true };
34
+ this.childSpec = Object.assign({}, this.spec, { id: undefined });
35
+ },
36
+ // $initAccessories() {
37
+ // this.tooltip = this.spec.tooltip || { disabled: true };
38
+ // },
39
+ tooltipPositionMatches(position) {
40
+ if (this.spec.tooltip && this.spec.tooltip.position) {
41
+ return position == this.spec.tooltip.position;
42
+ } else {
43
+ return position == "bottom";
44
+ }
45
+ }
46
+ }
47
+ };
48
+ </script>
49
+
50
+ <style lang="scss" scoped></style>
@@ -1,11 +1,5 @@
1
1
  <template>
2
- <v-tooltip
3
- :disabled="tooltip.disabled"
4
- :top="tooltipPositionMatches('top')"
5
- :right="tooltipPositionMatches('right')"
6
- :bottom="tooltipPositionMatches('bottom')"
7
- :left="tooltipPositionMatches('left')"
8
- >
2
+ <common-tooltip :spec="spec">
9
3
  <template v-slot:activator="{ on }">
10
4
  <common-badge :spec="spec">
11
5
  <v-avatar :size="spec.size">
@@ -14,31 +8,18 @@
14
8
  :style="$styles()"
15
9
  :src="spec.url || spec.base64Data"
16
10
  @click="$onClick()"
11
+ v-on="on"
17
12
  />
18
13
  </v-avatar>
19
14
  </common-badge>
20
15
  </template>
21
- <span>{{ tooltip.text }}</span>
22
- </v-tooltip>
16
+ </common-tooltip>
23
17
  </template>
24
18
 
25
19
  <script>
26
- import TooltipMixins from "./mixins/tooltip";
27
-
28
20
  export default {
29
- mixins: [TooltipMixins],
30
21
  props: {
31
22
  spec: { type: Object, required: true }
32
- },
33
- data() {
34
- return {
35
- styles: {}
36
- };
37
- },
38
- methods: {
39
- $ready() {
40
- this.$initAccessories();
41
- }
42
23
  }
43
24
  };
44
25
  </script>
@@ -1,41 +1,15 @@
1
1
  <template>
2
- <div>
3
- <v-tooltip
4
- :disabled="tooltip.disabled"
5
- :top="tooltipPositionMatches('top')"
6
- :right="tooltipPositionMatches('right')"
7
- :bottom="tooltipPositionMatches('bottom')"
8
- :left="tooltipPositionMatches('left')"
9
- >
10
- <template v-slot:activator="{ on }">
11
- <div v-on="on">
12
- <common-button :spec="childSpec" :disabled="$isBusy" />
13
- </div>
14
- </template>
15
- <span> {{ tooltip.text }} </span>
16
- </v-tooltip>
17
- </div>
2
+ <common-tooltip :spec="spec">
3
+ <template v-slot:activator="{ on }">
4
+ <common-button :spec="spec" :disabled="$isBusy" :event-handlers="on" />
5
+ </template>
6
+ </common-tooltip>
18
7
  </template>
19
8
 
20
9
  <script>
21
- import tooltipMixin from "./mixins/tooltip";
22
-
23
10
  export default {
24
- mixins: [tooltipMixin],
25
11
  props: {
26
12
  spec: { type: Object, required: true }
27
- },
28
- data() {
29
- return {
30
- tooltip: {},
31
- childSpec: Object.assign({}, this.spec, { id: undefined })
32
- };
33
- },
34
- methods: {
35
- $ready() {
36
- this.tooltip = this.spec.tooltip || { disabled: true };
37
- this.childSpec = Object.assign({}, this.spec, { id: undefined });
38
- }
39
13
  }
40
14
  };
41
15
  </script>
@@ -10,10 +10,10 @@
10
10
  // https://chartkick.com/vue
11
11
 
12
12
  import annotation from "../mixins/chart/annotation.js";
13
- import tooltip from "../mixins/chart/tooltip.js";
13
+ // import tooltip from "../mixins/chart/tooltip.js";
14
14
 
15
15
  export default {
16
- mixins: [annotation, tooltip],
16
+ mixins: [annotation],
17
17
  props: {
18
18
  spec: { type: Object, required: true }
19
19
  },
@@ -9,10 +9,10 @@
9
9
 
10
10
  <script>
11
11
  import annotation from "../mixins/chart/annotation.js";
12
- import tooltip from "../mixins/chart/tooltip.js";
12
+ // import tooltip from "../mixins/chart/tooltip.js";
13
13
 
14
14
  export default {
15
- mixins: [annotation, tooltip],
15
+ mixins: [annotation],
16
16
  props: {
17
17
  spec: { type: Object, required: true }
18
18
  },
@@ -3,28 +3,9 @@
3
3
  </template>
4
4
 
5
5
  <script>
6
- import TooltipMixins from "./mixins/tooltip";
7
6
  export default {
8
- mixins: [TooltipMixins],
9
7
  props: {
10
8
  spec: { type: Object, required: true }
11
- },
12
- data: function() {
13
- return {
14
- tooltip: {}
15
- };
16
- },
17
- methods: {
18
- $ready() {
19
- this.tooltip = this.spec.tooltip || {};
20
- }
21
9
  }
22
10
  };
23
11
  </script>
24
-
25
- <style lang="scss" scoped>
26
- // Prevent hover effect if the chip is not clickable.
27
- span.theme--light.v-chip:hover:before {
28
- opacity: 0;
29
- }
30
- </style>
File without changes
File without changes
@@ -60,12 +60,7 @@ export default {
60
60
  },
61
61
  methods: {
62
62
  $ready() {
63
- this.options = this.normalizedOptions();
64
- this.append = this.spec.append || {};
65
- this.rules = this.$validation();
66
- if (this.defaultValue) {
67
- this.fieldModel = this.defaultValue;
68
- }
63
+ this.updateData();
69
64
  },
70
65
  normalizedOptions() {
71
66
  return this.spec.options.map(i => {
@@ -88,6 +83,17 @@ export default {
88
83
  GLib.action.execute(onChange, this);
89
84
  });
90
85
  });
86
+ },
87
+ updateData() {
88
+ this.options = this.normalizedOptions();
89
+ this.append = this.spec.append || {};
90
+ this.rules = this.$validation();
91
+ if (this.defaultValue) {
92
+ this.fieldModel = this.defaultValue;
93
+ }
94
+ },
95
+ $registryEnabled() {
96
+ return false;
91
97
  }
92
98
  }
93
99
  };
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,13 +1,17 @@
1
1
  <template>
2
- <div :class="$classes()">
3
- <v-tooltip
2
+ <common-tooltip :spec="spec">
3
+ <template v-slot:activator="{ on }">
4
+ <!-- <common-button :spec="spec" :disabled="$isBusy" :event-handlers="on" /> -->
5
+
6
+ <div :class="$classes()">
7
+ <!-- <v-tooltip
4
8
  :disabled="tooltip.disabled"
5
9
  :top="tooltipPositionMatches('top')"
6
10
  :right="tooltipPositionMatches('right')"
7
11
  :bottom="tooltipPositionMatches('bottom')"
8
12
  :left="tooltipPositionMatches('left')"
9
13
  >
10
- <template v-slot:activator="{ on }">
14
+ <template v-slot:activator="{ on }"> -->
11
15
  <v-radio
12
16
  :label="spec.label"
13
17
  :value="spec.value.presence() || vuetifyEmptyString"
@@ -22,29 +26,31 @@
22
26
  <glib-component :spec="item" />
23
27
  </div>
24
28
  </div>
25
- </template>
29
+ <!-- </template>
26
30
  <span>{{ tooltip.text }}</span>
27
- </v-tooltip>
28
- </div>
31
+ </v-tooltip> -->
32
+ </div>
33
+ </template>
34
+ </common-tooltip>
29
35
  </template>
30
36
 
31
37
  <script>
32
- import TooltipMixins from "../mixins/tooltip";
38
+ // import TooltipMixins from "../mixins/tooltip";
33
39
 
34
40
  export default {
35
- mixins: [TooltipMixins],
41
+ // mixins: [TooltipMixins],
36
42
  props: {
37
43
  spec: { type: Object, required: true }
38
- },
39
- data() {
40
- return {
41
- tooltip: {}
42
- };
43
- },
44
- methods: {
45
- $ready() {
46
- this.tooltip = this.spec.tooltip || { disabled: true };
47
- }
48
44
  }
45
+ // data() {
46
+ // return {
47
+ // tooltip: {}
48
+ // };
49
+ // },
50
+ // methods: {
51
+ // $ready() {
52
+ // this.tooltip = this.spec.tooltip || { disabled: true };
53
+ // }
54
+ // }
49
55
  };
50
56
  </script>
@@ -56,7 +56,7 @@ export default {
56
56
  data: () => ({
57
57
  customToolbar: [
58
58
  ["bold", "italic", "strike"],
59
- [{ header: 1 }, { header: 2 }],
59
+ [{ header: 1 }, { header: 2 }, { header: 3 }],
60
60
  [{ list: "ordered" }, { list: "bullet" }],
61
61
  ["image", "link"]
62
62
  ],
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <fields-genericSelect :spec="spec" />
2
+ <fields-genericSelect ref="delegate" :spec="updatedSpec" />
3
3
  </template>
4
4
 
5
5
  <script>
@@ -12,6 +12,20 @@ export default {
12
12
  },
13
13
  props: {
14
14
  spec: { type: Object, required: true }
15
+ },
16
+ data() {
17
+ return {
18
+ updatedSpec: this.spec
19
+ };
20
+ },
21
+ methods: {
22
+ $ready() {
23
+ this.updatedSpec = this.spec;
24
+ },
25
+ action_merge(mergedSpec) {
26
+ Object.assign(this.updatedSpec, mergedSpec);
27
+ this.$refs.delegate.updateData();
28
+ }
15
29
  }
16
30
  };
17
31
  </script>
File without changes
package/components/hr.vue CHANGED
File without changes
File without changes
@@ -1,34 +1,27 @@
1
1
  <template>
2
- <v-tooltip
3
- :disabled="tooltip.disabled"
4
- :top="tooltipPositionMatches('top')"
5
- :right="tooltipPositionMatches('right')"
6
- :bottom="tooltipPositionMatches('bottom')"
7
- :left="tooltipPositionMatches('left')"
8
- >
2
+ <common-tooltip :spec="spec">
9
3
  <template v-slot:activator="{ on }">
10
4
  <common-badge :spec="spec">
11
5
  <!-- TODO: Add support for href and :rel="$rel()" -->
12
6
  <v-img
13
7
  :src="spec.url || spec.base64Data"
14
8
  :style="styles"
15
- v-on="on"
16
9
  @click="$onClick()"
10
+ v-on="on"
17
11
  >
18
12
  <!-- <v-progress-circular v-if="$isBusy" indeterminate /> -->
19
13
  </v-img>
20
14
  </common-badge>
21
15
  </template>
22
- <span>{{ tooltip.text }}</span>
23
- </v-tooltip>
16
+ </common-tooltip>
24
17
  </template>
25
18
 
26
19
  <script>
27
20
  import Vue from "vue";
28
- import TooltipMixins from "./mixins/tooltip";
21
+ // import TooltipMixins from "./mixins/tooltip";
29
22
 
30
23
  export default {
31
- mixins: [TooltipMixins],
24
+ // mixins: [TooltipMixins],
32
25
  props: {
33
26
  spec: { type: Object, required: true }
34
27
  },
@@ -39,7 +32,7 @@ export default {
39
32
  },
40
33
  methods: {
41
34
  $ready() {
42
- this.$initAccessories();
35
+ // this.$initAccessories();
43
36
 
44
37
  const styles = this.genericStyles(Object.assign({}, this.spec));
45
38
  this.styles = styles;
File without changes
File without changes
File without changes
File without changes
package/components/p.vue CHANGED
File without changes
@@ -5,13 +5,21 @@
5
5
  :md="md.cols"
6
6
  :sm="sm.cols"
7
7
  :style="cssStyles()"
8
+ :class="$classes()"
8
9
  :cols="xs.cols || 12"
10
+ :order-xl="xl.order"
11
+ :order-lg="lg.order"
12
+ :order-md="md.order"
13
+ :order-sm="sm.order"
14
+ :order="xs.order"
9
15
  >
10
- <panels-responsive :spec="spec" />
16
+ <panels-responsive :spec="innerSpec()" />
11
17
  </v-col>
12
18
  </template>
13
19
 
14
20
  <script>
21
+ import Hash from "../../utils/hash";
22
+
15
23
  export default {
16
24
  props: {
17
25
  spec: { type: Object, required: true }
@@ -33,8 +41,12 @@ export default {
33
41
  this.sm = this.spec.sm || this.sm;
34
42
  this.xs = this.spec.xs || this.xs;
35
43
  },
44
+ innerSpec() {
45
+ // Remove properties that are handled by the container (i.e. v-col).
46
+ return new Hash(this.spec).without("padding").without("styleClasses");
47
+ },
36
48
  cssStyles() {
37
- const styles = this.$styles();
49
+ const styles = Object.assign({}, this.$styles());
38
50
  switch (this.$vuetify.breakpoint.name) {
39
51
  case "xl":
40
52
  this.applyStyles(styles, this.xs);
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <div style="display: contents;">
3
- <common-responsive v-if="!hoverViewsSpec" :spec="spec" />
3
+ <!-- <common-responsive v-if="!hoverViewsSpec" :spec="spec" /> -->
4
4
  <v-menu
5
- v-else
5
+ v-if="hoverViewsSpec"
6
6
  :close-on-content-click="false"
7
7
  open-on-hover
8
8
  offset-x
@@ -18,6 +18,12 @@
18
18
  <common-responsive :spec="hoverViewsSpec" />
19
19
  </v-card>
20
20
  </v-menu>
21
+ <common-tooltip v-else :spec="spec">
22
+ <template v-slot:activator="{ on }">
23
+ <common-responsive :spec="spec" :event-handlers="on" />
24
+ <!-- <common-button :spec="spec" :disabled="$isBusy" :event-handlers="on" /> -->
25
+ </template>
26
+ </common-tooltip>
21
27
  </div>
22
28
  </template>
23
29
 
@@ -31,4 +31,7 @@ ul.breadcrumbs {
31
31
  content: "/\00a0";
32
32
  }
33
33
  }
34
+ li > * {
35
+ vertical-align: text-top;
36
+ }
34
37
  </style>
package/index.js CHANGED
@@ -50,6 +50,7 @@ import ResponsivePanel from "./components/panels/responsive";
50
50
  import Component from "./components/component";
51
51
  import CommonIcon from "./components/_icon";
52
52
  import CommonBadge from "./components/_badge";
53
+ import CommonTooltip from "./components/_tooltip";
53
54
  import CommonButton from "./components/_button";
54
55
  import CommonChip from "./components/_chip";
55
56
  import CommonMessage from "./components/_message";
@@ -61,6 +62,7 @@ Vue.component("panels-responsive", ResponsivePanel);
61
62
  Vue.component("common-button", CommonButton);
62
63
  Vue.component("common-icon", CommonIcon);
63
64
  Vue.component("common-badge", CommonBadge);
65
+ Vue.component("common-tooltip", CommonTooltip);
64
66
  Vue.component("common-chip", CommonChip);
65
67
  Vue.component("common-message", CommonMessage);
66
68
  Vue.component("common-dropdownMenu", CommonDropdownMenu);
@@ -174,6 +176,7 @@ document.addEventListener("DOMContentLoaded", () => {
174
176
  stateUpdatedAt: null,
175
177
  webSocket: { channels: {}, header: {} },
176
178
  actionCable: { channels: {} },
179
+ registeredComponents: [],
177
180
  temp: {}
178
181
  };
179
182
  new Vue({
package/keys.js CHANGED
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,13 +1,22 @@
1
1
  export default {
2
2
  install: (Vue, options) => {
3
- Vue.prototype.updatables = {};
3
+ // Vue.prototype.updatables = {};
4
+
4
5
  Vue.mixin({
5
6
  created: function() {
6
7
  let spec = this.spec;
7
- if (spec && spec.id) {
8
- Object.assign(this.updatables, {
9
- [spec.id]: this
10
- });
8
+ if (spec && spec.id && this.$registryEnabled()) {
9
+ GLib.component.register(spec.id, this);
10
+ // Object.assign(this.updatables, {
11
+ // [spec.id]: this
12
+ // });
13
+ // console.log("U", this.updatables);
14
+ }
15
+ },
16
+ methods: {
17
+ $registryEnabled() {
18
+ // Common classes such as `_select` need to return false so that it doesn't override its parent (e.g. `select`).
19
+ return true;
11
20
  }
12
21
  }
13
22
  });
File without changes
package/styles/test.sass CHANGED
File without changes
package/styles/test.scss CHANGED
File without changes
File without changes
package/utils/app.js CHANGED
@@ -1,3 +1,4 @@
1
+ // TODO: Move to component.js
1
2
  export default class {
2
3
  static componentName(jsonName) {
3
4
  const name = `${jsonName.replace("/", "-").replace(/-v1$/, "")}`;
@@ -0,0 +1,12 @@
1
+ export default class {
2
+ static findById(id) {
3
+ const component = window.vueApp.registeredComponents[id];
4
+ if (component) {
5
+ return component;
6
+ }
7
+ console.error("Component not found: " + id);
8
+ }
9
+ static register(id, component) {
10
+ window.vueApp.registeredComponents[id] = component;
11
+ }
12
+ }
package/utils/dom.js CHANGED
File without changes
package/utils/public.js CHANGED
@@ -3,6 +3,7 @@ import Url from "./url";
3
3
  import Http from "./http";
4
4
  import Type from "./type";
5
5
  import Form from "./form";
6
+ import Component from "./component";
6
7
 
7
8
  export default class {
8
9
  static get action() {
@@ -20,4 +21,7 @@ export default class {
20
21
  static get form() {
21
22
  return Form;
22
23
  }
24
+ static get component() {
25
+ return Component;
26
+ }
23
27
  }
package/utils/settings.js CHANGED
File without changes
package/utils/storage.js CHANGED
File without changes
package/utils/url.js CHANGED
File without changes
@@ -1,20 +0,0 @@
1
- // TODO: Make tooltip reusable component. See _badge.vue
2
- export default {
3
- data() {
4
- return {
5
- tooltip: {}
6
- };
7
- },
8
- methods: {
9
- $initAccessories() {
10
- this.tooltip = this.spec.tooltip || { disabled: true };
11
- },
12
- tooltipPositionMatches(position) {
13
- if (this.spec.tooltip && this.spec.tooltip.position) {
14
- return position == this.spec.tooltip.position;
15
- } else {
16
- return position == "bottom";
17
- }
18
- }
19
- }
20
- };
package/nav/content.vue DELETED
@@ -1,40 +0,0 @@
1
- <template>
2
- <v-main :style="outerStyle()">
3
- <panels-responsive v-if="template == 'fullWidth'" :spec="spec" />
4
- <v-col v-else cols="12" md="8" offset-md="2" :style="innerStyle()">
5
- <template v-if="spec">
6
- <panels-responsive v-if="template == 'flatCentered'" :spec="spec" />
7
- <v-card v-else :height="$length(spec.height)">
8
- <panels-responsive :spec="spec" />
9
- </v-card>
10
- </template>
11
- </v-col>
12
- </v-main>
13
- </template>
14
-
15
- <script>
16
- export default {
17
- props: {
18
- spec: { type: Object, required: true },
19
- template: { type: String, default: null },
20
- fullHeight: { type: Boolean, required: true }
21
- },
22
- methods: {
23
- outerStyle() {
24
- if (this.fullHeight) {
25
- return { height: "100%" };
26
- }
27
- return {};
28
- },
29
- innerStyle() {
30
- const style = { padding: "0" };
31
- if (this.fullHeight) {
32
- return Object.assign(style, { height: "100%" });
33
- }
34
- return style;
35
- }
36
- }
37
- };
38
- </script>
39
-
40
- <style scoped></style>