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
@@ -0,0 +1,10 @@
1
+ export default {
2
+ mounted() {
3
+ if (this.spec && this.spec.dataset) {
4
+ const data = this.spec.dataset;
5
+ for (const key in this.spec.dataset) {
6
+ this.$el.dataset[key] = data[key];
7
+ }
8
+ }
9
+ }
10
+ };
@@ -69,8 +69,7 @@ export default {
69
69
  if (!e.metaKey && !e.ctrlKey && e.button === 0) {
70
70
  e.preventDefault();
71
71
  e.stopPropagation();
72
- // Action.execute(properties.onClick, target || event.target, this);
73
- Action.execute(properties.onClick, null, this);
72
+ Action.execute(properties.onClick, this);
74
73
  }
75
74
  },
76
75
  $rel: function(spec) {
@@ -88,7 +87,7 @@ export default {
88
87
  // return this.spec.onLongPress ? this.$onLongPress : null;
89
88
  // },
90
89
  $onLongPress() {
91
- GLib.action.execute(this.spec.onLongPress, null, this);
90
+ GLib.action.execute(this.spec.onLongPress, this);
92
91
  },
93
92
  $addViewportChangeListeners: function(handler) {
94
93
  window.addEventListener("load", handler);
@@ -163,12 +162,12 @@ export default {
163
162
  this.$el.addEventListener(name, handler);
164
163
  },
165
164
  $onTyping({ duration = 2000 }) {
166
- GLib.action.execute(this.spec.onTypeStart, null, this);
165
+ GLib.action.execute(this.spec.onTypeStart, this);
167
166
  clearTimeout(this.timer);
168
167
 
169
168
  this.timer = setTimeout(() => {
170
169
  this._typingTimer = null;
171
- GLib.action.execute(this.spec.onTypeEnd, null, this);
170
+ GLib.action.execute(this.spec.onTypeEnd, this);
172
171
  }, duration);
173
172
  }
174
173
  // $onZero() {
@@ -23,6 +23,12 @@ export default {
23
23
  });
24
24
  return augmentedRules;
25
25
  },
26
+ // This can be overridden by the component to ensure that dialogs are shown within the component,
27
+ // which is necessary for operations requiring certain hierarchy, e.g. submitting a form from a
28
+ // child dialog.
29
+ $dialogContainer() {
30
+ return document.body;
31
+ },
26
32
  $wsSubscribeEvents(spec) {
27
33
  if (!Utils.type.isObject(spec)) {
28
34
  return;
@@ -64,7 +64,6 @@ export default {
64
64
  (el, visible) => {
65
65
  if (visible) {
66
66
  this._handleTopScroll(onScrollToTop);
67
- // GLib.action.execute(onScrollToTop, null, this);
68
67
  }
69
68
  }
70
69
  );
@@ -72,7 +71,7 @@ export default {
72
71
  this.$addViewportChangeListeners(this.topScrollHandler);
73
72
  },
74
73
  _handleTopScroll(onScrollToTop) {
75
- GLib.action.execute(onScrollToTop, null, this);
74
+ GLib.action.execute(onScrollToTop, this);
76
75
  },
77
76
  _registerBottomScroll(onScrollToBottom) {
78
77
  this.bottomScrollHandler = this.$onVisibilityChange(
@@ -108,7 +107,7 @@ export default {
108
107
  );
109
108
  }
110
109
 
111
- GLib.action.execute(onScrollToBottom, null, this);
110
+ GLib.action.execute(onScrollToBottom, this);
112
111
  },
113
112
  autoloadAll(nextPage) {
114
113
  const vm = this;
@@ -56,7 +56,7 @@ export default {
56
56
  // this.topScrollHandler();
57
57
  },
58
58
  _handleTopScroll(onScrollToTop) {
59
- GLib.action.execute(onScrollToTop, null, this);
59
+ GLib.action.execute(onScrollToTop, this);
60
60
  },
61
61
  _registerBottomScroll(onScrollToBottom) {
62
62
  this.bottomScrollHandler = this.$onVisibilityChange(
@@ -95,7 +95,7 @@ export default {
95
95
  );
96
96
  }
97
97
 
98
- GLib.action.execute(onScrollToBottom, null, this);
98
+ GLib.action.execute(onScrollToBottom, this);
99
99
  },
100
100
  autoloadAll(nextPage) {
101
101
  const vm = this;
@@ -0,0 +1,75 @@
1
+ import Driver from "driver.js";
2
+ import "driver.js/dist/driver.min.css";
3
+
4
+ class TourHelper {
5
+ constructor() {
6
+ this.keys = [];
7
+ this.storage = window.localStorage;
8
+
9
+ this.driver = new Driver({
10
+ doneBtnText: "Done",
11
+ closeBtnText: "Skip tour",
12
+ nextBtnText: "Next tip",
13
+ prevBtnText: "Prev",
14
+ onHighlighted: element => {
15
+ console.log("onHighlighted", element);
16
+ // TODO
17
+ // this.keys.forEach(value => this.storage.removeItem(value));
18
+ // this.storage.setItem(element.node.dataset.key, 1);
19
+ }
20
+ });
21
+
22
+ this.elements = [];
23
+ }
24
+ }
25
+
26
+ const helper = new TourHelper();
27
+
28
+ export default {
29
+ methods: {
30
+ registerTour() {
31
+ if (this.spec.tour) {
32
+ helper.elements.push(this);
33
+ }
34
+ },
35
+ startTour() {
36
+ if (helper.elements && helper.elements.length > 0) {
37
+ helper.elements = Array.from(helper.elements).sort(
38
+ (a, b) => a.index - b.index
39
+ );
40
+ let stepDefinitions = helper.elements.map(element => {
41
+ const tourSpec = element.spec.tour;
42
+
43
+ return {
44
+ element: element.$el,
45
+ popover: {
46
+ title: tourSpec.title,
47
+ description: tourSpec.message,
48
+ position: tourSpec.position
49
+ }
50
+ };
51
+ });
52
+
53
+ // TODO
54
+ // this.keys = helper.elements.map(value => value.dataset.key);
55
+
56
+ helper.driver.defineSteps(stepDefinitions);
57
+
58
+ helper.driver.start(this.latestTourStep());
59
+ }
60
+ },
61
+ latestTourStep() {
62
+ let step = 0;
63
+
64
+ // TODO
65
+ // Array.from(this.elements).forEach(element => {
66
+ // if (this.storage.getItem(element.dataset.key)) {
67
+ // step = parseInt(element.dataset.index);
68
+ // }
69
+ // });
70
+ // return step;
71
+
72
+ return step;
73
+ }
74
+ }
75
+ };
@@ -34,7 +34,7 @@ export default {
34
34
  const action = data.action;
35
35
  const payload = { ...action, filterKey: ws.filterKey };
36
36
  if (ws.filterKey === data.filterKey) {
37
- GLib.action.execute(payload, null, component);
37
+ GLib.action.execute(payload, component);
38
38
  }
39
39
  }
40
40
  });
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <div :style="styles()" :class="$classes()">
3
+ <iframe
4
+ :width="width"
5
+ :height="height"
6
+ :src="videoUrl"
7
+ allowfullscreen
8
+ ></iframe>
9
+ </div>
10
+ </template>
11
+
12
+ <script>
13
+ const urlRegex = /^(?:(?:https?:)?\/\/)?(?:www\.)?(?:m\.)?(?:youtu(?:be)?\.com\/(?:v\/|embed\/|watch(?:\/|\?v=))|youtu\.be\/)((?:\w|-){11})(?:\S+)?$/;
14
+
15
+ export default {
16
+ props: {
17
+ spec: { type: Object, required: true }
18
+ },
19
+ data() {
20
+ return {
21
+ videoUrl: "",
22
+ width: null,
23
+ height: null,
24
+ paddingBottom: null
25
+ };
26
+ },
27
+ methods: {
28
+ $ready() {
29
+ this.width = this.$length(this.spec.width);
30
+ this.height = this.$length(this.spec.height);
31
+
32
+ if (this.height == null) {
33
+ // Let the container calculates the height
34
+ this.height = "100%";
35
+
36
+ if (this.width == "100%") {
37
+ // 16:9 aspect ratio
38
+ // See https://stackoverflow.com/questions/35814653/automatic-height-when-embedding-a-youtube-video
39
+ this.paddingBottom = "56.25%";
40
+ } else {
41
+ Utils.type.ifNumber(this.spec.width, val => {
42
+ const height = (val * 9) / 16;
43
+ this.paddingBottom = `${height}px`;
44
+ });
45
+ }
46
+ }
47
+
48
+ const url = this.spec.url;
49
+ if (this.isYoutube(url)) {
50
+ this.videoUrl = this.embededYoutubeUrl(this.extractYoutubeId(url));
51
+ } else {
52
+ this.videoUrl = url;
53
+ }
54
+ },
55
+ styles() {
56
+ const styles = this.$styles();
57
+
58
+ // See https://stackoverflow.com/questions/35814653/automatic-height-when-embedding-a-youtube-video
59
+ styles["position"] = "relative";
60
+ styles["padding-bottom"] = this.paddingBottom;
61
+
62
+ return styles;
63
+ },
64
+ isYoutube(url) {
65
+ return !!String(url).match(urlRegex);
66
+ },
67
+ extractYoutubeId(url) {
68
+ let match = urlRegex.exec(url);
69
+ return match ? match[1] : false;
70
+ },
71
+ embededYoutubeUrl(youtubeId) {
72
+ return "https://www.youtube.com/embed/:youtubeId".replace(
73
+ ":youtubeId",
74
+ youtubeId
75
+ );
76
+ }
77
+ }
78
+ };
79
+ </script>
80
+
81
+ <style lang="scss" scoped>
82
+ iframe {
83
+ position: absolute;
84
+ top: 0;
85
+ left: 0;
86
+ }
87
+ </style>
@@ -60,6 +60,10 @@ export default {
60
60
  this.submit();
61
61
  });
62
62
 
63
+ this.$onEvent("forms/directSubmit", e => {
64
+ this.directSubmit();
65
+ });
66
+
63
67
  this.formElement = this.$refs.form.$el;
64
68
  this.parentStyles = this.genericStyles({ width: this.spec.width });
65
69
 
@@ -104,18 +108,24 @@ export default {
104
108
  [this.spec.paramNameForFormData || "formData"]: formData
105
109
  };
106
110
  const data = Object.assign({}, onSubmit, params);
107
- GLib.action.execute(data, null, this);
111
+ GLib.action.execute(data, this);
108
112
  },
109
113
  () => {
110
- GLib.form.submitData(this.formElement, this);
114
+ this.directSubmit();
111
115
  }
112
116
  );
113
117
  } else {
114
- Utils.launch.alert("Make sure all fields are valid");
118
+ Utils.launch.dialog.alert("Make sure all fields are valid");
115
119
  }
116
120
  },
121
+ directSubmit() {
122
+ GLib.form.submitData(this.formElement, this);
123
+ },
117
124
  action_clear() {
118
125
  this.formElement.reset();
126
+ },
127
+ $dialogContainer() {
128
+ return this.formElement;
119
129
  }
120
130
  }
121
131
  };
@@ -219,7 +219,7 @@ export default {
219
219
  }
220
220
  });
221
221
 
222
- GLib.action.execute(mergedSpec, null, this);
222
+ GLib.action.execute(mergedSpec, this);
223
223
  },
224
224
  getSectionIndex(element) {
225
225
  return element.dataset.index;
@@ -26,9 +26,9 @@ export default {
26
26
  },
27
27
  changed() {
28
28
  if (this.enabled) {
29
- GLib.action.execute(this.spec.onEnabled, {}, this);
29
+ GLib.action.execute(this.spec.onEnabled, this);
30
30
  } else {
31
- GLib.action.execute(this.spec.onDisabled, {}, this);
31
+ GLib.action.execute(this.spec.onDisabled, this);
32
32
  }
33
33
  }
34
34
  }
package/index.js CHANGED
@@ -78,6 +78,9 @@ Vue.mixin(stylesMixin);
78
78
  import scrollingMixin from "./components/mixins/scrolling.js";
79
79
  Vue.mixin(scrollingMixin);
80
80
 
81
+ import datasetMixins from "./components/mixins/dataset.js";
82
+ Vue.mixin(datasetMixins);
83
+
81
84
  import longClickDirective from "./components/mixins/longClick.js";
82
85
  window.longClickInstance = longClickDirective({ delay: 500, interval: 0 });
83
86
  Vue.directive("longclick", window.longClickInstance);
package/nav/appbar.vue CHANGED
@@ -108,7 +108,7 @@ export default {
108
108
  },
109
109
  viewSource: function() {
110
110
  const properties = { message: this.page };
111
- Launch.dialog(Object.assign({}, properties));
111
+ Utils.launch.dialog.open(Object.assign({}, properties));
112
112
  },
113
113
  avatarSpec(spec) {
114
114
  return {
package/nav/dialog.vue CHANGED
@@ -89,7 +89,7 @@ export default {
89
89
  this.title = this.spec.title;
90
90
  this.message = this.spec.message;
91
91
  this.body = this.spec.body;
92
- Action.execute(spec.onLoad, null, this);
92
+ Action.execute(spec.onLoad, this);
93
93
  }
94
94
 
95
95
  this.stack.push(this);
@@ -105,7 +105,7 @@ export default {
105
105
  click(spec, event) {
106
106
  const onClick = spec["onClick"];
107
107
  this.model = false;
108
- Action.execute(onClick, event.target, this);
108
+ Action.execute(onClick, this);
109
109
  }
110
110
  }
111
111
  };
package/nav/drawer.vue CHANGED
@@ -7,26 +7,41 @@
7
7
  app
8
8
  :class="cssClasses"
9
9
  :dark="cssClasses.includes('dark')"
10
- :expand-on-hover="expandOnHover()"
11
10
  :permanent="cssClasses.includes('permanent')"
12
11
  :style="style"
12
+ :expand-on-hover="expandOnHover()"
13
+ :mini-variant.sync="mini"
13
14
  @input="updateState"
14
15
  >
16
+ <template v-slot:prepend>
17
+ <v-list-item>
18
+ <v-list-item-icon>
19
+ <v-icon v-if="!mini">mdi-chevron-left</v-icon>
20
+ <v-icon v-if="mini">mdi-chevron-right</v-icon>
21
+ </v-list-item-icon>
22
+ </v-list-item>
23
+ </template>
24
+
15
25
  <template v-if="spec.header">
16
- <!-- <v-toolbar flat> -->
17
26
  <panels-responsive :spec="spec.header" />
18
- <!-- </v-toolbar> -->
19
- <v-divider></v-divider>
20
27
  </template>
21
28
 
22
29
  <v-list dense class="pt-0">
23
- <div v-for="(item, index) in spec.rows" :key="index">
30
+ <div v-for="(item, index) in spec.rows" :key="index" class="nav-item">
31
+ <div v-if="item.type == 'button'" class="indicator"></div>
24
32
  <v-divider v-if="item.type == 'divider'" />
25
33
  <nav-drawerLabel v-else-if="item.type == 'label'" :spec="item" />
26
34
  <nav-drawerButton v-else :spec="item" />
27
- <!-- <nav-drawerButton :spec="item" :state="state" v-else /> -->
28
35
  </div>
29
36
  </v-list>
37
+
38
+ <template v-if="spec.footer" v-slot:append>
39
+ <v-list-item>
40
+ <!-- Display the first line when the drawer is shrunk. Display the second line when the drawer is expanded -->
41
+ <div style="display: none">Show if expand</div>
42
+ <panels-responsive :spec="spec.footer" />
43
+ </v-list-item>
44
+ </template>
30
45
  </v-navigation-drawer>
31
46
  </template>
32
47
 
@@ -50,7 +65,8 @@ export default {
50
65
  return {
51
66
  // Using null as the starting value for its v-model will initialize the drawer as closed on mobile and as open on desktop.
52
67
  // See https://vuetifyjs.com/en/components/navigation-drawers
53
- state: null
68
+ state: null,
69
+ mini: true
54
70
  };
55
71
  },
56
72
  computed: {
@@ -102,4 +118,18 @@ export default {
102
118
  };
103
119
  </script>
104
120
 
105
- <style scoped></style>
121
+ <style scoped>
122
+ .nav-item {
123
+ position: relative;
124
+ }
125
+ .nav-item:hover .indicator {
126
+ display: flex;
127
+ position: absolute;
128
+ width: 3px;
129
+ height: 65%;
130
+ margin: 10px 0;
131
+ justify-content: center;
132
+ align-items: center;
133
+ background-color: white;
134
+ }
135
+ </style>
package/nav/sheet.vue CHANGED
@@ -49,8 +49,7 @@ export default {
49
49
  this.model = false;
50
50
 
51
51
  Utils.type.ifFunction(spec.onClickFunction, f => f());
52
- GLib.action.execute(spec.onClick, event.target, this);
53
- // this.$onClick(spec, event.target, this);
52
+ GLib.action.execute(spec.onClick, this);
54
53
  }
55
54
  }
56
55
  };
package/nav/snackbar.vue CHANGED
@@ -62,8 +62,7 @@ export default {
62
62
  click: function(spec) {
63
63
  const onClick = spec["onClick"];
64
64
  this.show = false;
65
- // Action.execute(onClick, event.target, this);
66
- GLib.action.execute(onClick, null, this);
65
+ GLib.action.execute(onClick, this);
67
66
  }
68
67
  }
69
68
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "0.6.2",
3
+ "version": "0.6.9",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -28,7 +28,8 @@
28
28
  "vue2-editor": "^2.9.1",
29
29
  "vue2-google-maps": "^0.10.6",
30
30
  "vuedraggable": "^2.24.1",
31
- "vuetify": "2.3.9"
31
+ "vuetify": "2.3.9",
32
+ "driver.js": "^0.9.8"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@types/chart.js": "^2.9.34",
package/utils/form.js CHANGED
@@ -2,12 +2,8 @@ export default class {
2
2
  // Execution flows:
3
3
  // Button -> Button.onClick() -> Utils.http.execute() -- doesn't save autofill values
4
4
  // Button -> Button.onClick() -> form.submit() -- doesn't execute Form.onSubmit(), so cannot call Utils.http.execute() there
5
- // Submit -> Form.onSubmit() -> Utils.http.execute() -- save autofill values, but cannot have submit action nested in another action
6
- // TOTRY: Button -> Button.onClick() -> form.clickSubmit() -> submit.click() -> Form.onSubmit() -> Utils.http.execute()
5
+ // Submit -> Form.onSubmit() -> Utils.http.execute() -- save autofill values and auto-submit when ENTER is pressed
7
6
  static submitData(form, component) {
8
- // const form = target.closest("form");
9
- // const form = this.formElement;
10
-
11
7
  // Analogous to Rails' form_with's local
12
8
  if (form.dataset.local) {
13
9
  form.submit();
package/utils/http.js CHANGED
@@ -54,7 +54,7 @@ export default class {
54
54
  this.forceComponentUpdate(() => {
55
55
  Utils.history.resetScroll();
56
56
  window.vueApp.page = data;
57
- Action.execute(properties["onOpen"], target, component);
57
+ Action.execute(properties["onOpen"], component);
58
58
  });
59
59
  });
60
60
  } else {
@@ -109,7 +109,7 @@ export default class {
109
109
  const redirectUrl = Utils.url.htmlUrl(response.url);
110
110
  Utils.history.updatePage(redirectUrl);
111
111
 
112
- GLib.action.execute(properties["onReload"], null, component);
112
+ GLib.action.execute(properties["onReload"], component);
113
113
  });
114
114
  });
115
115
  }
package/utils/launch.js CHANGED
@@ -5,7 +5,21 @@ import Snackbar from "../nav/snackbar";
5
5
  import Vuetify from "vuetify";
6
6
 
7
7
  export default class {
8
- static dialog(properties, target) {
8
+ static get dialog() {
9
+ return LaunchDialog;
10
+ }
11
+
12
+ static get sheet() {
13
+ return LaunchSheet;
14
+ }
15
+
16
+ static get snackbar() {
17
+ return LaunchSnackbar;
18
+ }
19
+ }
20
+
21
+ class LaunchDialog {
22
+ static open(properties, component) {
9
23
  if (!this.stack) {
10
24
  this.stack = [];
11
25
  }
@@ -21,19 +35,20 @@ export default class {
21
35
  propsData: {
22
36
  spec: properties,
23
37
  stack: this.stack,
24
- target: target,
25
38
  vueApp: window.vueApp
26
39
  }
27
40
  });
28
41
  // instance.stack = this.stack;
29
42
 
30
- const placeholder = document.body.appendChild(
31
- document.createElement("div")
32
- );
33
- instance.$mount(placeholder);
43
+ if (component) {
44
+ const placeholder = component
45
+ .$dialogContainer()
46
+ .appendChild(document.createElement("div"));
47
+ instance.$mount(placeholder);
48
+ }
34
49
  }
35
50
 
36
- static closeDialog(properties, target, component) {
51
+ static close(properties, component) {
37
52
  if (!this.stack) {
38
53
  this.stack = [];
39
54
  }
@@ -43,19 +58,11 @@ export default class {
43
58
  });
44
59
 
45
60
  Utils.type.ifObject(properties["onClose"], it => {
46
- Action.execute(it, target, component);
61
+ Action.execute(it, component);
47
62
  });
48
63
  }
49
64
 
50
- static get sheet() {
51
- return LaunchSheet;
52
- }
53
-
54
- static get snackbar() {
55
- return LaunchSnackbar;
56
- }
57
-
58
- static alert(message, target) {
65
+ static alert(message) {
59
66
  const properties = {
60
67
  message: message
61
68
  };
@@ -67,7 +74,7 @@ export default class {
67
74
  }
68
75
  ]
69
76
  });
70
- this.dialog(spec, target);
77
+ this.dialog(spec);
71
78
  }
72
79
  }
73
80