glib-web 0.6.2 → 0.6.9

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 (55) hide show
  1. package/action.js +7 -4
  2. package/actions/analytics/logEvent.js +1 -1
  3. package/actions/auth/creditCard.js +4 -4
  4. package/actions/auth/saveCsrfToken.js +4 -4
  5. package/actions/cables/push.js +0 -12
  6. package/actions/commands/copy.js +12 -0
  7. package/actions/dialogs/alert.js +2 -2
  8. package/actions/dialogs/close.js +2 -4
  9. package/actions/dialogs/notification.js +2 -2
  10. package/actions/dialogs/open.js +2 -4
  11. package/actions/dialogs/show.js +3 -2
  12. package/actions/forms/submit.js +2 -12
  13. package/actions/http/delete.js +1 -1
  14. package/actions/http/patch.js +1 -1
  15. package/actions/http/post.js +1 -1
  16. package/actions/http/put.js +1 -1
  17. package/actions/runMultiple.js +2 -2
  18. package/actions/timeouts/set.js +2 -2
  19. package/actions/windows/close.js +2 -2
  20. package/actions/windows/closeAll.js +2 -2
  21. package/actions/windows/closeWithReload.js +1 -1
  22. package/actions/windows/open.js +1 -1
  23. package/actions/windows/reload.js +1 -1
  24. package/actions/ws/push.js +1 -1
  25. package/app.vue +5 -3
  26. package/components/button.vue +9 -2
  27. package/components/calendar.vue +1 -1
  28. package/components/component.vue +4 -0
  29. package/components/fields/googlePlace.vue +80 -52
  30. package/components/fields/radioGroup.vue +1 -0
  31. package/components/markdown.vue +7 -0
  32. package/components/mixins/dataset.js +10 -0
  33. package/components/mixins/events.js +4 -5
  34. package/components/mixins/generic.js +6 -0
  35. package/components/mixins/list/autoload.js +2 -3
  36. package/components/mixins/table/autoload.js +2 -2
  37. package/components/mixins/tour.js +75 -0
  38. package/components/mixins/ws/actionCable.js +1 -1
  39. package/components/multimedia/video.vue +87 -0
  40. package/components/panels/form.vue +13 -3
  41. package/components/panels/list.vue +1 -1
  42. package/components/switch.vue +2 -2
  43. package/index.js +3 -0
  44. package/nav/appbar.vue +1 -1
  45. package/nav/dialog.vue +2 -2
  46. package/nav/drawer.vue +38 -8
  47. package/nav/sheet.vue +1 -2
  48. package/nav/snackbar.vue +1 -2
  49. package/package.json +3 -2
  50. package/utils/form.js +1 -5
  51. package/utils/http.js +2 -2
  52. package/utils/launch.js +25 -18
  53. package/utils/mime_type.js +78 -0
  54. package/utils/private/ws.js +1 -1
  55. package/utils/uploader.js +9 -36
package/action.js CHANGED
@@ -45,6 +45,8 @@ import ActionsCreditCard from "./actions/auth/creditCard";
45
45
 
46
46
  import ActionsAnalyticsLogEvent from "./actions/analytics/logEvent";
47
47
 
48
+ import ActionCommandsCopy from "./actions/commands/copy";
49
+
48
50
  const actions = {
49
51
  runMultiple: ActionsRunMultiple,
50
52
 
@@ -89,11 +91,12 @@ const actions = {
89
91
  "auth/restart": ActionsAuthRestart,
90
92
  "auth/creditCard": ActionsCreditCard,
91
93
 
92
- "analytics/logEvent": ActionsAnalyticsLogEvent
94
+ "analytics/logEvent": ActionsAnalyticsLogEvent,
95
+ "commands/copy": ActionCommandsCopy
93
96
  };
94
97
 
95
98
  export default class Action {
96
- static execute(spec, target, component, params = {}) {
99
+ static execute(spec, component, params = {}) {
97
100
  if (!TypeUtils.isObject(spec)) {
98
101
  return;
99
102
  }
@@ -141,7 +144,7 @@ export default class Action {
141
144
  if (!logDisabled) {
142
145
  console.log(`Executing "${actionName}"`);
143
146
  }
144
- action.execute(spec, null, component, params);
147
+ action.execute(spec, component, params);
145
148
  } catch (e) {
146
149
  console.log(
147
150
  "Failed executing command",
@@ -159,7 +162,7 @@ export default class Action {
159
162
  }
160
163
 
161
164
  window.vueApp.temp.analytics = response.analytics;
162
- GLib.action.execute(response.onResponse, null, component);
165
+ GLib.action.execute(response.onResponse, component);
163
166
  window.vueApp.temp.analytics = null;
164
167
  }
165
168
  }
@@ -3,7 +3,7 @@ export default class {
3
3
  return true;
4
4
  }
5
5
 
6
- execute(properties, target, component) {
6
+ execute(properties, component) {
7
7
  if (Utils.settings.isDev) {
8
8
  return;
9
9
  }
@@ -9,9 +9,9 @@ export default class {
9
9
  Utils.http.stopIndicator(component);
10
10
 
11
11
  if (result.error) {
12
- GLib.action.execute(properties.onFailure, {}, component);
12
+ GLib.action.execute(properties.onFailure, component);
13
13
  } else {
14
- GLib.action.execute(properties.onSuccess, {}, component);
14
+ GLib.action.execute(properties.onSuccess, component);
15
15
  }
16
16
  });
17
17
  } else {
@@ -19,9 +19,9 @@ export default class {
19
19
  Utils.http.stopIndicator(component);
20
20
 
21
21
  if (result.error) {
22
- GLib.action.execute(properties.onFailure, {}, component);
22
+ GLib.action.execute(properties.onFailure, component);
23
23
  } else {
24
- GLib.action.execute(properties.onSuccess, {}, component);
24
+ GLib.action.execute(properties.onSuccess, component);
25
25
  }
26
26
  });
27
27
  }
@@ -2,11 +2,11 @@
2
2
  // import Keys from '../../keys'
3
3
 
4
4
  export default class {
5
- execute(properties, target, component) {
5
+ execute(properties, component) {
6
6
  // console.log(properties['token'])
7
7
  // Storage.setLocal(Keys.Db.csrfToken, properties['token'])
8
-
9
- Utils.dom.setCsrf(properties['token'])
10
- Action.execute(properties['onSave'], target, component)
8
+
9
+ Utils.dom.setCsrf(properties["token"]);
10
+ Action.execute(properties["onSave"], component);
11
11
  }
12
12
  }
@@ -1,17 +1,5 @@
1
1
  export default class {
2
2
  execute(properties) {
3
- // const spec = Object.assign({}, properties, {
4
- // buttons: [
5
- // {
6
- // text: "OK",
7
- // onClick: properties.onClose
8
- // }
9
- // ]
10
- // });
11
- // Launch.dialog(spec);
12
-
13
- // const ws = window.vueApp.actionCable;
14
-
15
3
  Utils.type.ifString(properties.channel, channelName => {
16
4
  const ws = window.vueApp.actionCable;
17
5
  const channel = ws.channels[channelName];
@@ -0,0 +1,12 @@
1
+ export default class {
2
+ execute(properties) {
3
+ let spec = Object.assign({}, properties, {
4
+ message: "Copied",
5
+ styleClasses: ["success"]
6
+ });
7
+ navigator.clipboard.writeText(properties.text).then(
8
+ () => Utils.launch.snackbar.open(spec),
9
+ reason => console.error("Could not copy text: " + reason)
10
+ );
11
+ }
12
+ }
@@ -1,7 +1,7 @@
1
1
  import Launch from "../../utils/launch";
2
2
 
3
3
  export default class {
4
- execute(properties) {
4
+ execute(properties, component) {
5
5
  const spec = Object.assign({}, properties, {
6
6
  buttons: [
7
7
  {
@@ -10,6 +10,6 @@ export default class {
10
10
  }
11
11
  ]
12
12
  });
13
- Launch.dialog(spec);
13
+ Utils.launch.dialog.open(spec, component);
14
14
  }
15
15
  }
@@ -1,7 +1,5 @@
1
- import Launch from '../../utils/launch'
2
-
3
1
  export default class {
4
- execute(properties, target, component) {
5
- Launch.closeDialog(properties, target, component)
2
+ execute(spec, component) {
3
+ Utils.launch.dialog.close(spec, component);
6
4
  }
7
5
  }
@@ -1,12 +1,12 @@
1
1
  import Push from "push.js";
2
2
 
3
3
  export default class {
4
- execute(properties, target, component) {
4
+ execute(properties, component) {
5
5
  Push.create(properties.title, {
6
6
  body: properties.message,
7
7
  onClick() {
8
8
  const onClick = properties.onClick;
9
- GLib.action.execute(onClick, null, component);
9
+ GLib.action.execute(onClick, component);
10
10
  this.close();
11
11
  }
12
12
  });
@@ -1,7 +1,5 @@
1
- import Launch from "../../utils/launch";
2
-
3
1
  export default class {
4
- execute(properties) {
5
- Launch.dialog(properties);
2
+ execute(spec, component) {
3
+ Utils.launch.dialog.open(spec, component);
6
4
  }
7
5
  }
@@ -1,5 +1,6 @@
1
1
  export default class {
2
- execute(properties) {
3
- Utils.launch.dialog(properties);
2
+ execute(spec, component) {
3
+ console.log("P1", spec);
4
+ Utils.launch.dialog.open(spec, component);
4
5
  }
5
6
  }
@@ -1,15 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, component) {
3
- const form = component.$closest("panels-form");
4
- if (form != null) {
5
- form.submit();
6
- }
7
-
8
- // const vm = this;
9
- // // Allows time for things to get finalized. For example, select.vue needs time to insert values
10
- // // into hidden fields before they get submitted.
11
- // setTimeout(() => {
12
- // vm.submit(target, component);
13
- // }, 10);
2
+ execute(properties, component) {
3
+ component.$dispatchEvent("forms/directSubmit");
14
4
  }
15
5
  }
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, controller) {
2
+ execute(properties, controller) {
3
3
  GLib.http.execute(properties, "DELETE", controller, response =>
4
4
  GLib.action.handleResponse(response, controller)
5
5
  );
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, controller) {
2
+ execute(properties, controller) {
3
3
  GLib.http.execute(properties, "PATCH", controller, response =>
4
4
  GLib.action.handleResponse(response, controller)
5
5
  );
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, controller) {
2
+ execute(properties, controller) {
3
3
  GLib.http.execute(properties, "POST", controller, response =>
4
4
  GLib.action.handleResponse(response, controller)
5
5
  );
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, controller) {
2
+ execute(properties, controller) {
3
3
  GLib.http.execute(properties, "PUT", controller, response =>
4
4
  GLib.action.handleResponse(response, controller)
5
5
  );
@@ -3,9 +3,9 @@ export default class {
3
3
  return true;
4
4
  }
5
5
 
6
- execute(properties, target, component) {
6
+ execute(properties, component) {
7
7
  for (const action of properties.childActions) {
8
- GLib.action.execute(action, null, component);
8
+ GLib.action.execute(action, component);
9
9
  }
10
10
  }
11
11
  }
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, component) {
2
+ execute(properties, component) {
3
3
  component.$data._isBusy = true;
4
4
 
5
5
  if (properties.repeat) {
@@ -15,6 +15,6 @@ export default class {
15
15
 
16
16
  onTimeout(properties, component) {
17
17
  component.$data._isBusy = false;
18
- GLib.action.execute(properties.onTimeout, null, component);
18
+ GLib.action.execute(properties.onTimeout, component);
19
19
  }
20
20
  }
@@ -1,12 +1,12 @@
1
1
  export default class {
2
- execute(properties, target, component) {
2
+ execute(properties, component) {
3
3
  Utils.history.back();
4
4
 
5
5
  Utils.type.ifObject(properties["onClose"], it => {
6
6
  // Allow time for history.back() to complete, which is important for actions that need
7
7
  // to use window.location.href such as windows/reload
8
8
  setTimeout(function() {
9
- GLib.action.execute(it, null, component);
9
+ GLib.action.execute(it, component);
10
10
  }, 100);
11
11
  });
12
12
  }
@@ -1,7 +1,7 @@
1
1
  import Type from "../../utils/type";
2
2
 
3
3
  export default class {
4
- execute(properties, target, component) {
4
+ execute(properties, component) {
5
5
  // TODO
6
6
  // window.history.deleteAll()
7
7
 
@@ -9,7 +9,7 @@ export default class {
9
9
  // Allow time for history.back() to complete, which is important for actions that need
10
10
  // to use window.location.href such as windows/reload
11
11
  setTimeout(function() {
12
- GLib.action.execute(it, null, component);
12
+ GLib.action.execute(it, component);
13
13
  }, 100);
14
14
  });
15
15
  }
@@ -1,7 +1,7 @@
1
1
  import Hash from "../../utils/hash";
2
2
 
3
3
  export default class {
4
- execute(properties, target, component) {
4
+ execute(properties, component) {
5
5
  const fallbackUrl = new Hash(properties).remove("fallbackUrl");
6
6
  const data = Object.assign({}, properties);
7
7
  if (!Utils.history.back()) {
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, component) {
2
+ execute(properties, component) {
3
3
  Utils.http.load(properties, null, component);
4
4
  }
5
5
  }
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, component) {
2
+ execute(properties, component) {
3
3
  if (Utils.settings.reactive) {
4
4
  // const currentUrl = window.location.href;
5
5
  // const data = {
@@ -1,5 +1,5 @@
1
1
  export default class {
2
- execute(properties, target, component, params) {
2
+ execute(properties, component, params) {
3
3
  Utils.type.ifString(properties.topic, topicName => {
4
4
  const ws = window.vueApp.webSocket;
5
5
  const channel = ws.channels[topicName];
package/app.vue CHANGED
@@ -42,13 +42,14 @@ import Utils from "./utils/helper";
42
42
  import ContentLayout from "./nav/content";
43
43
  import phoenixSocketMixin from "./components/mixins/ws/phoenixSocket.js";
44
44
  import actionCableMixin from "./components/mixins/ws/actionCable.js";
45
+ import tourMixin from "./components/mixins/tour";
45
46
 
46
47
  export default {
47
48
  components: {
48
49
  "nav-appbar": NavAppBar,
49
50
  "layouts-content": ContentLayout
50
51
  },
51
- mixins: [phoenixSocketMixin, actionCableMixin],
52
+ mixins: [phoenixSocketMixin, actionCableMixin, tourMixin],
52
53
  props: {
53
54
  page: { type: Object, required: true }
54
55
  },
@@ -103,12 +104,13 @@ export default {
103
104
  if (Utils.history.isPoppedState(this.page)) {
104
105
  setTimeout(() => {
105
106
  // Wait until page is rendered
106
- GLib.action.execute(this.page.onRefocus, null, this);
107
+ GLib.action.execute(this.page.onRefocus, this);
107
108
  });
108
109
  } else {
109
110
  setTimeout(() => {
110
111
  // Wait until page is rendered
111
- GLib.action.execute(this.page.onLoad, null, this);
112
+ GLib.action.execute(this.page.onLoad, this);
113
+ this.startTour();
112
114
  });
113
115
  }
114
116
  }
@@ -21,11 +21,18 @@
21
21
  </template>
22
22
 
23
23
  <script>
24
- import TooltipMixins from "./mixins/tooltip";
24
+ import tooltipMixin from "./mixins/tooltip";
25
+ import tourMixin from "./mixins/tour";
26
+
25
27
  export default {
26
- mixins: [TooltipMixins],
28
+ mixins: [tooltipMixin, tourMixin],
27
29
  props: {
28
30
  spec: { type: Object, required: true }
31
+ },
32
+ methods: {
33
+ $ready() {
34
+ this.registerTour();
35
+ }
29
36
  }
30
37
  };
31
38
  </script>
@@ -98,7 +98,7 @@ export default {
98
98
  });
99
99
  },
100
100
  showEvent({ event, target }) {
101
- Action.execute(event.onClick, target, this);
101
+ Action.execute(event.onClick, this);
102
102
  }
103
103
  }
104
104
  };
@@ -105,6 +105,8 @@ import ResponsivePanel from "./panels/responsive";
105
105
  import UlPanel from "./panels/ul";
106
106
  import WebPanel from "./panels/web";
107
107
 
108
+ import MultimediaVideo from "./multimedia/video";
109
+
108
110
  import AlertBanner from "./banners/alert";
109
111
  import SelectBanner from "./banners/select";
110
112
 
@@ -185,6 +187,8 @@ export default {
185
187
  "panels-ul": UlPanel,
186
188
  "panels-web": WebPanel,
187
189
 
190
+ "multimedia-video": MultimediaVideo,
191
+
188
192
  "banners-alert": AlertBanner,
189
193
  "banners-select": SelectBanner,
190
194
 
@@ -1,13 +1,16 @@
1
-
2
1
  <!-- TODO: This probably can be merged with latLong-v1 or map-v1, i.e. add infoWindow support to latLong or map -->
3
2
 
4
3
  <template>
5
- <v-container fluid class='pa-0'>
4
+ <v-container fluid class="pa-0">
6
5
  <div class="v-input v-text-field theme--light">
7
6
  <div class="v-input__control">
8
7
  <div class="v-input__slot">
9
8
  <div class="v-text-field__slot">
10
- <label class="v-label theme--light v-label--active" style="left: 0px; right: auto; position: absolute;">Address</label>
9
+ <label
10
+ class="v-label theme--light v-label--active"
11
+ style="left: 0px; right: auto; position: absolute;"
12
+ >Address</label
13
+ >
11
14
  <!-- <gmap-place-input :default-place="placeName" :placeholder="Address" @place_changed="setPlace" /> -->
12
15
  <gmap-autocomplete
13
16
  :name="spec.name"
@@ -20,22 +23,39 @@
20
23
  </div>
21
24
 
22
25
  <gmap-map
26
+ ref="map"
23
27
  :center="{ lat: 25.105497, lng: 121.597366 }"
24
28
  :zoom="13"
25
29
  map-type-id="roadmap"
26
30
  style="width: 100%; height: 300px"
27
- @click='onMapClick'
28
- ref='map'
31
+ @click="onMapClick"
29
32
  >
30
- <gmap-info-window :options="infoOptions" :position="markerPos" :opened="infoWinOpen" @closeclick="closeInfoWindow">
31
- <div v-if='place !== null'>
33
+ <gmap-info-window
34
+ :options="infoOptions"
35
+ :position="markerPos"
36
+ :opened="infoWinOpen"
37
+ @closeclick="closeInfoWindow"
38
+ >
39
+ <div v-if="place !== null">
32
40
  <strong>{{ place.name }}</strong>
33
41
  <div>Place ID: {{ place.place_id }}</div>
34
42
  <div>Address: {{ place.formatted_address }}</div>
35
- <div>Longitude: {{ place.geometry.location.lng() }}, Latitude: {{place.geometry.location.lat() }}</div>
43
+ <div>
44
+ Longitude: {{ place.geometry.location.lng() }}, Latitude:
45
+ {{ place.geometry.location.lat() }}
46
+ </div>
36
47
  </div>
37
- <div v-if="spec.hasOwnProperty('infoWindow') && spec.infoWindow['actionButtons'].length > 0">
38
- <v-btn v-for="(buttonSpec, i) in spec.infoWindow.actionButtons" :key="i" @click='onActionButtonClick($event, buttonSpec)'>
48
+ <div
49
+ v-if="
50
+ spec.hasOwnProperty('infoWindow') &&
51
+ spec.infoWindow['actionButtons'].length > 0
52
+ "
53
+ >
54
+ <v-btn
55
+ v-for="(buttonSpec, i) in spec.infoWindow.actionButtons"
56
+ :key="i"
57
+ @click="onActionButtonClick($event, buttonSpec)"
58
+ >
39
59
  {{ buttonSpec.text }}
40
60
  </v-btn>
41
61
  </div>
@@ -47,7 +67,7 @@
47
67
  @click="openInfoWindow"
48
68
  />
49
69
  <template v-slot:visible>
50
- <div id="loading-container" class="d-none" ref="loading">
70
+ <div id="loading-container" ref="loading" class="d-none">
51
71
  <v-progress-circular indeterminate color="primary" />
52
72
  </div>
53
73
  </template>
@@ -56,10 +76,10 @@
56
76
  </template>
57
77
 
58
78
  <script>
59
- import Action from "../../action"
79
+ import Action from "../../action";
60
80
 
61
81
  export default {
62
- props: ['spec'],
82
+ props: ["spec"],
63
83
  data() {
64
84
  return {
65
85
  infoOptions: {
@@ -71,77 +91,85 @@ export default {
71
91
  markerPos: { lat: 0, lng: 0 },
72
92
  infoWinOpen: false,
73
93
  place: null
74
- }
94
+ };
75
95
  },
76
96
  computed: {
77
97
  placeName() {
78
- return (this.place == null ? '' : this.place.name)
98
+ return this.place == null ? "" : this.place.name;
79
99
  }
80
100
  },
81
101
  methods: {
82
102
  closeInfoWindow() {
83
- this.infoWinOpen = false
103
+ this.infoWinOpen = false;
84
104
  },
85
105
  openInfoWindow() {
86
- this.infoWinOpen = true
106
+ this.infoWinOpen = true;
87
107
  },
88
108
  toggleLoadingIndicator() {
89
- this.$refs.loading.classList.toggle('d-none')
90
- this.$refs.loading.classList.toggle('d-flex')
109
+ this.$refs.loading.classList.toggle("d-none");
110
+ this.$refs.loading.classList.toggle("d-flex");
91
111
  },
92
112
  onActionButtonClick(event, properties) {
93
- properties.onClick['formData'] = {
94
- 'place[google_place_id]': this.place.place_id,
95
- 'place[name]': this.place.name,
96
- 'place[address]': this.place.formatted_address,
97
- 'place[longitude]': this.place.geometry.location.lng(),
98
- 'place[latitude]': this.place.geometry.location.lat(),
99
- }
113
+ properties.onClick["formData"] = {
114
+ "place[google_place_id]": this.place.place_id,
115
+ "place[name]": this.place.name,
116
+ "place[address]": this.place.formatted_address,
117
+ "place[longitude]": this.place.geometry.location.lng(),
118
+ "place[latitude]": this.place.geometry.location.lat()
119
+ };
100
120
 
101
- Action.execute(properties.onClick, event.target, this)
121
+ Action.execute(properties.onClick, this);
102
122
  },
103
123
  onMapClick(e) {
104
- this.closeInfoWindow()
124
+ this.closeInfoWindow();
105
125
 
106
126
  if (e.placeId === undefined) {
107
- return
127
+ return;
108
128
  }
109
129
 
110
- e.stop()
111
- this.toggleLoadingIndicator()
130
+ e.stop();
131
+ this.toggleLoadingIndicator();
112
132
 
113
133
  const request = {
114
134
  placeId: e.placeId,
115
- fields: ['place_id', 'geometry', 'name', 'formatted_address']
116
- }
117
- var service = new google.maps.places.PlacesService(this.$refs.map.$mapObject)
135
+ fields: ["place_id", "geometry", "name", "formatted_address"]
136
+ };
137
+ var service = new google.maps.places.PlacesService(
138
+ this.$refs.map.$mapObject
139
+ );
118
140
  service.getDetails(request, place => {
119
- this.toggleLoadingIndicator()
120
- this.markerPos = place.geometry.location
121
- this.place = place
122
- this.openInfoWindow()
123
- })
141
+ this.toggleLoadingIndicator();
142
+ this.markerPos = place.geometry.location;
143
+ this.place = place;
144
+ this.openInfoWindow();
145
+ });
124
146
  },
125
147
  setLocationField(name, value) {
126
- let field = document.querySelector(`input[name="${name}"]`)
127
- field.closest('div.v-input').classList.add('v-input--is-label-active')
128
- field.closest('div.v-input').classList.add('v-input--is-dirty')
129
- field.previousSibling.classList.add('v-label--active')
130
- field.value = value
148
+ let field = document.querySelector(`input[name="${name}"]`);
149
+ field.closest("div.v-input").classList.add("v-input--is-label-active");
150
+ field.closest("div.v-input").classList.add("v-input--is-dirty");
151
+ field.previousSibling.classList.add("v-label--active");
152
+ field.value = value;
131
153
  },
132
154
  setPlace(place) {
133
- const { location } = place.geometry
134
- this.place = place
135
- this.markerPos = location
136
- this.$refs.map.$mapObject.setCenter(location)
155
+ const { location } = place.geometry;
156
+ this.place = place;
157
+ this.markerPos = location;
158
+ this.$refs.map.$mapObject.setCenter(location);
137
159
 
138
- if (this.spec.hasOwnProperty('locationFields')) {
139
- this.setLocationField(this.spec.locationFields.latitudeName, location.lat())
140
- this.setLocationField(this.spec.locationFields.longitudeName, location.lng())
160
+ if (this.spec.hasOwnProperty("locationFields")) {
161
+ this.setLocationField(
162
+ this.spec.locationFields.latitudeName,
163
+ location.lat()
164
+ );
165
+ this.setLocationField(
166
+ this.spec.locationFields.longitudeName,
167
+ location.lng()
168
+ );
141
169
  }
142
170
  }
143
171
  }
144
- }
172
+ };
145
173
  </script>
146
174
 
147
175
  <style scoped>
@@ -3,6 +3,7 @@
3
3
  v-model="fieldModel"
4
4
  :name="fieldName"
5
5
  :disabled="spec.readOnly"
6
+ :rules="$validation()"
6
7
  >
7
8
  <div v-for="(item, index) in spec.childViews" :key="index">
8
9
  <ui-component :spec="item" />
@@ -32,6 +32,13 @@ export default {
32
32
  this.youtubeId = this.extractYoutubeId(this.spec.text);
33
33
  console.log("Detected Youtube ID", this.youtubeId);
34
34
  }
35
+ // Set all links to be openWeb or open in a new tab by default
36
+ if (!this.spec.openWeb) {
37
+ let anchors = document.querySelectorAll('a');
38
+ for (let i = 0; i < anchors.length; i++) {
39
+ anchors[i].setAttribute('target', '_blank')
40
+ }
41
+ }
35
42
  },
36
43
  // From https://gist.github.com/takien/4077195
37
44
  extractYoutubeId(url) {