glib-web 3.0.3 → 3.0.5

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 (42) hide show
  1. package/action.js +15 -29
  2. package/actions/analytics/logEvent.js +2 -2
  3. package/actions/auth/saveCsrfToken.js +0 -6
  4. package/actions/cables/push.js +3 -1
  5. package/actions/components/update.js +0 -1
  6. package/actions/http/get.js +28 -16
  7. package/actions/panels/scrollTo.js +32 -7
  8. package/actions/panels/scrollToBottom.js +1 -1
  9. package/actions/windows/closeWithReload.js +1 -1
  10. package/actions/ws/push.js +2 -2
  11. package/app.vue +8 -9
  12. package/components/_chip.vue +29 -12
  13. package/components/_responsive.vue +15 -12
  14. package/components/component.vue +10 -2
  15. package/components/datetime.vue +0 -2
  16. package/components/fields/check.vue +31 -23
  17. package/components/fields/hidden.vue +7 -2
  18. package/components/fields/newRichText.vue +1 -1
  19. package/components/fields/submit.vue +5 -2
  20. package/components/fields/text.vue +22 -23
  21. package/components/fields/timer.vue +1 -2
  22. package/components/label.vue +8 -4
  23. package/components/mixins/events.js +14 -19
  24. package/components/mixins/generic.js +2 -2
  25. package/components/mixins/styles.js +1 -1
  26. package/components/mixins/ws/actionCable.js +2 -2
  27. package/components/mixins/ws/phoenixSocket.js +6 -7
  28. package/components/panels/horizontal.vue +8 -8
  29. package/components/panels/list.vue +22 -3
  30. package/components/panels/responsive.vue +2 -11
  31. package/components/panels/scroll.vue +0 -3
  32. package/components/panels/table.vue +0 -3
  33. package/components/switch.vue +5 -4
  34. package/nav/dialog.vue +18 -8
  35. package/package.json +1 -1
  36. package/utils/history.js +1 -1
  37. package/utils/http.js +56 -10
  38. package/utils/private/ws.js +2 -2
  39. package/utils/public.js +0 -6
  40. package/utils/settings.js +10 -2
  41. package/actions/commands/enqueue.js +0 -17
  42. package/utils/queue.js +0 -102
@@ -1,12 +1,11 @@
1
1
  <template>
2
2
  <div :style="$styles()" :class="classes()">
3
- <v-text-field v-model="fieldModel" :label="spec.label" :name="fieldName" :placeholder="spec.placeholder"
4
- :maxlength="spec.maxLength || 255" :disabled="spec.readOnly" :type="config.type" :rules="rules"
5
- :prepend-inner-icon="leftIconName" :append-inner-icon="config.appendIcon" :prefix="spec.leftText"
6
- :suffix="spec.rightText" :min="spec.min" :max="spec.max" :autofocus="spec.autoFocus || false" validate-on="blur"
7
- @click:appendInner="onRightIconClick" @input="onChange" :variant="variant" persistent-placeholder />
3
+ <v-text-field :label="spec.label" :name="fieldName" :placeholder="spec.placeholder" :maxlength="spec.maxLength || 255"
4
+ :disabled="spec.readOnly" :type="config.type" :rules="rules" :prepend-inner-icon="leftIconName"
5
+ :append-inner-icon="config.appendIcon" :prefix="spec.leftText" :suffix="spec.rightText" :min="spec.min"
6
+ :max="spec.max" :autofocus="spec.autoFocus || false" validate-on="blur" @click:appendInner="onRightIconClick"
7
+ @input="onChange" :variant="variant" persistent-placeholder />
8
8
  <input v-if="spec.readOnly" type="hidden" :name="fieldName" />
9
-
10
9
  </div>
11
10
  </template>
12
11
 
@@ -18,7 +17,7 @@ export default {
18
17
  mixins: [inputVariant],
19
18
  props: {
20
19
  spec: { type: Object, required: true },
21
- type: { type: String, required: true }
20
+ type: { type: String, required: true },
22
21
  },
23
22
  data() {
24
23
  return {
@@ -31,17 +30,17 @@ export default {
31
30
  prependIcon: "email",
32
31
  onRightIconClick: function () { },
33
32
  rules: [
34
- v =>
33
+ (v) =>
35
34
  !v ||
36
35
  /^\w+([.-\\+]?\w+)*@\w+([.-]?\w+)*(\.\w{2,5})+$/.test(v) ||
37
- "E-mail must be valid"
38
- ]
36
+ "E-mail must be valid",
37
+ ],
39
38
  },
40
39
  number: {
41
40
  type: "number",
42
41
  prependIcon: "looks_one",
43
42
  onRightIconClick: function () { },
44
- rules: [v => !v || /^\-?[.\d]*$/.test(v) || "Must be a number"]
43
+ rules: [(v) => !v || /^\-?[.\d]*$/.test(v) || "Must be a number"],
45
44
  },
46
45
  password: {
47
46
  type: "password",
@@ -50,7 +49,7 @@ export default {
50
49
  onRightIconClick: function (vm) {
51
50
  vm.togglePasswordVisibility();
52
51
  },
53
- rules: [v => !v || v.length >= 6 || "Password must be longer"]
52
+ rules: [(v) => !v || v.length >= 6 || "Password must be longer"],
54
53
  },
55
54
  url: {
56
55
  type: "url",
@@ -59,23 +58,23 @@ export default {
59
58
  rules: [
60
59
  // From https://gist.github.com/rodneyrehm/8013067
61
60
  // Make sure to support unicode chars, e.g. https://www.facebook.com/%E5%86%B0%E5%8F%8B%E4%BE%86%E7%9C%8B%E7%90%83-103474391161721/
62
- v =>
61
+ (v) =>
63
62
  !v ||
64
63
  /^(https?|ftp|torrent|image|irc):\/\/(-\.)?([^\s\/?\.#]+\.?)+(\/[^\s]*)?$/i.test(
65
64
  v
66
65
  ) ||
67
- "Must be a valid URL"
68
- ]
66
+ "Must be a valid URL",
67
+ ],
69
68
  },
70
69
  search: {
71
70
  type: "url",
72
71
  prependIcon: "search",
73
72
  onRightIconClick: function () { },
74
73
  rules: [
75
- v => !v || /^\w+:\/\/[.-\w]+$/.test(v) || "Must be a valid URL"
76
- ]
77
- }
78
- }
74
+ (v) => !v || /^\w+:\/\/[.-\w]+$/.test(v) || "Must be a valid URL",
75
+ ],
76
+ },
77
+ },
79
78
  };
80
79
  },
81
80
  computed: {
@@ -88,11 +87,11 @@ export default {
88
87
  const icon = this.spec.rightIcon || {};
89
88
  const materialIcon = icon.material || {};
90
89
  return materialIcon.name;
91
- }
90
+ },
92
91
  },
93
92
  methods: {
94
93
  $ready() {
95
- this.fieldModel = this.spec.value
94
+ this.fieldModel = this.spec.value;
96
95
  this.config = this.fields[this.type] || {};
97
96
  this.rules = this.$validation(this.config.rules);
98
97
 
@@ -120,8 +119,8 @@ export default {
120
119
  },
121
120
  onChange: eventFiltering.debounce(function () {
122
121
  this.$executeOnChange();
123
- }, 300)
124
- }
122
+ }, 300),
123
+ },
125
124
  };
126
125
  </script>
127
126
 
@@ -101,10 +101,9 @@ export default {
101
101
  }
102
102
  },
103
103
  $tearDown() {
104
- console.log("Cleaning up timer...");
105
104
  if (this.timer != null) {
106
105
  clearInterval(this.timer);
107
- console.log(`Timer stopped: ${this.timer}`);
106
+ console.debug(`Timer stopped: ${this.timer}`);
108
107
  this.timer == null;
109
108
  }
110
109
  },
@@ -24,10 +24,14 @@ export default {
24
24
 
25
25
  this.text = this.spec.text;
26
26
  },
27
- action_set(spec) {
28
- if (spec.user_id !== spec.filterKey) {
29
- this.text = spec.text;
30
- }
27
+ // action_set(spec) {
28
+ // if (spec.user_id !== spec.filterKey) {
29
+ // this.text = spec.text;
30
+ // }
31
+ // },
32
+ action_merge(mergedSpec) {
33
+ Object.assign(this.spec, mergedSpec);
34
+ this.$ready();
31
35
  }
32
36
  }
33
37
  };
@@ -165,26 +165,21 @@ export default {
165
165
  // this._linkFieldModels();
166
166
  this.$ready();
167
167
  },
168
- async $recursiveUpdate() {
169
- this.$update();
170
- this.$forceUpdate();
168
+ async $recursiveUpdate(stack) {
169
+ // const children = this.$children;
170
+ if (this.spec) {
171
+ // this.$update();
172
+ // this.$forceUpdate();
171
173
 
172
- // Execute on next tick to ensure that the child has received the updated spec.
173
- // $children is removed in vue 3
174
- // this.$nextTick(() => {
175
- // this.$children.find(child => {
176
- // child.$recursiveUpdate();
177
- // });
178
- // });
179
- },
180
- // _recursiveUpdate() {
181
- // this.$update();
182
- // this.$forceUpdate();
183
-
184
- // this.$children.find(child => {
185
- // child._recursiveUpdate();
186
- // });
187
- // },
174
+ // Execute on next tick to ensure that the child has received the updated spec.
175
+ // $children is removed in vue 3
176
+ // this.$nextTick(() => {
177
+ // this.$children.find(child => {
178
+ // child.$recursiveUpdate();
179
+ // });
180
+ // });
181
+ }
182
+ },
188
183
  $dispatchEvent(name, data) {
189
184
  const event = new Event(name, { bubbles: true });
190
185
 
@@ -57,7 +57,7 @@ export default {
57
57
  const channel = ws.channels[topicName];
58
58
 
59
59
  if (!channel) {
60
- console.log(`Topic not ready: '${topicName}'`);
60
+ console.debug(`Topic not ready: '${topicName}'`);
61
61
  setTimeout(() => {
62
62
  // Wait until $wsInitPhoenixSocket() has executed.
63
63
  this.$wsSubscribeEvents(spec);
@@ -66,7 +66,7 @@ export default {
66
66
  }
67
67
 
68
68
  for (const eventName of events) {
69
- console.log(`Registering event '${eventName}'`);
69
+ console.debug(`Registering event '${eventName}'`);
70
70
  channel.on(eventName, payload => {
71
71
  console.debug(`Received '${eventName}' event`, payload);
72
72
  Utils.ws.handleResponse(payload.onResponse, this);
@@ -60,7 +60,7 @@ export default {
60
60
  const topDialog = Utils.launch.dialog.topDialog();
61
61
  if (topDialog) {
62
62
  if (!topDialog.isFormDirty) {
63
- console.log("Dialog form is now dirty");
63
+ console.debug("Dialog form is now dirty");
64
64
  topDialog.isFormDirty = true;
65
65
  }
66
66
  } else {
@@ -20,13 +20,13 @@ export default {
20
20
  channel: channelName
21
21
  });
22
22
 
23
- console.log("Connecting to channel", subscription);
23
+ console.debug("Connecting to channel", subscription);
24
24
 
25
25
  consumer.subscriptions.create(subscription, {
26
26
  connected() {
27
27
  const ws = vueApp.actionCable;
28
28
  ws.channels[channelName] = this;
29
- console.log("Connected to channel", channelName);
29
+ console.debug("Connected to channel", channelName);
30
30
  },
31
31
 
32
32
  disconnected() { },
@@ -13,7 +13,6 @@ export default {
13
13
  Utils.type.ifObject(
14
14
  spec,
15
15
  ws => {
16
- console.log("Connecting socket...");
17
16
  Utils.launch.snackbar.indicator("Connecting...");
18
17
  Utils.http.startIndicator(this);
19
18
 
@@ -55,14 +54,14 @@ export default {
55
54
 
56
55
  this._wsSocket = socket;
57
56
  socket.onOpen(() => {
58
- console.log("Connected socket");
57
+ console.debug("Connected socket");
59
58
  this._wsJoinChannel(socket, spec);
60
59
  Utils.http.stopIndicator(this);
61
60
  });
62
61
  socket.onError(() => {
63
62
  // Start the indicator again because this can trigger even after successfully connected.
64
63
  Utils.http.startIndicator(this);
65
- console.log("Unable to connect socket");
64
+ console.debug("Unable to connect socket");
66
65
  });
67
66
  socket.connect();
68
67
  },
@@ -81,7 +80,7 @@ export default {
81
80
  const channel = socket.channel(topicName, {});
82
81
 
83
82
  for (const eventName of events) {
84
- console.log(`Registering event '${eventName}'`);
83
+ console.debug(`Registering event '${eventName}'`);
85
84
  channel.on(eventName, payload => {
86
85
  console.debug(`Received '${eventName}' event`, payload);
87
86
  Utils.ws.handleResponse(payload.onResponse, this);
@@ -91,11 +90,11 @@ export default {
91
90
  channel
92
91
  .join()
93
92
  .receive("ok", resp => {
94
- console.log(`Channel joined '${topicName}'`, resp);
93
+ console.debug(`Channel joined '${topicName}'`, resp);
95
94
  ws.channels[topicName] = channel;
96
95
  })
97
96
  .receive("error", resp => {
98
- console.log(`Unable to join channel '${topicName}'`, resp);
97
+ console.debug(`Unable to join channel '${topicName}'`, resp);
99
98
  Utils.launch.snackbar.error(
100
99
  "Unable to connect. Please try again.",
101
100
  this
@@ -104,7 +103,7 @@ export default {
104
103
  },
105
104
  _wsDisconnectSocket() {
106
105
  if (this._wsSocket) {
107
- console.log("Disconnecting socket");
106
+ console.debug("Disconnecting socket");
108
107
  // Sometimes this doesn't prevent errorneous socket from trying to reconnect. In this case,
109
108
  // the socket will keep attempting to connect.
110
109
  this._wsSocket.disconnect();
@@ -41,7 +41,7 @@ export default {
41
41
  data: function () {
42
42
  return {
43
43
  dragSupport: null,
44
- childViews: []
44
+ childViews: [],
45
45
  };
46
46
  },
47
47
  computed: {
@@ -82,7 +82,7 @@ export default {
82
82
  childStyles() {
83
83
  const styles = {
84
84
  width: "100%",
85
- height: "100%"
85
+ height: "100%",
86
86
  };
87
87
 
88
88
  switch (this.spec.align) {
@@ -100,7 +100,7 @@ export default {
100
100
  },
101
101
  componentName() {
102
102
  return this.spec.onClick ? "a" : "div";
103
- }
103
+ },
104
104
  },
105
105
  methods: {
106
106
  $ready() {
@@ -119,7 +119,7 @@ export default {
119
119
 
120
120
  const targetRowIndex = event.newIndex;
121
121
  if (event.from == event.to && event.oldIndex == targetRowIndex) {
122
- console.log("Reordering canceled");
122
+ console.debug("Reordering canceled");
123
123
  return;
124
124
  }
125
125
 
@@ -136,8 +136,8 @@ export default {
136
136
  [dragSpec.paramNameForNewAbsoluteIndex || "newIndex"]: targetRowIndex,
137
137
  [dragSpec.paramNameForItemId || "itemId"]: itemId,
138
138
  [dragSpec.paramNameForOldPanelId || "oldPanelId"]: oldPanelId,
139
- [dragSpec.paramNameForNewPanelId || "newPanelId"]: newPanelId
140
- }
139
+ [dragSpec.paramNameForNewPanelId || "newPanelId"]: newPanelId,
140
+ },
141
141
  });
142
142
 
143
143
  GLib.action.execute(mergedSpec, this);
@@ -145,8 +145,8 @@ export default {
145
145
  action_merge(mergedSpec) {
146
146
  Object.assign(this.spec, mergedSpec);
147
147
  this.$ready();
148
- }
149
- }
148
+ },
149
+ },
150
150
  };
151
151
  </script>
152
152
 
@@ -94,7 +94,6 @@ export default {
94
94
  return row;
95
95
  },
96
96
  action_loadNext(spec) {
97
- console.log("TODO: load new comments and append to this list", spec);
98
97
  // TODO
99
98
  // - Load next rows/items from the Rails server
100
99
  // - You can pass some parameters (e.g. currentItemId) for pagination
@@ -182,7 +181,7 @@ export default {
182
181
  const targetSectionedRowIndex = event.newIndex;
183
182
  // const sourceSectionedRowIndex = event.oldIndex;
184
183
  if (event.from == event.to && event.oldIndex == targetSectionedRowIndex) {
185
- console.log("Reordering canceled");
184
+ console.debug("Reordering canceled");
186
185
  return;
187
186
  }
188
187
 
@@ -190,7 +189,6 @@ export default {
190
189
  this.$recursiveUpdate();
191
190
 
192
191
  const targetSectionIndex = this.getSectionIndex(event.to);
193
- // const targetSection = this.getSection(targetSectionIndex);
194
192
 
195
193
  const targetAbsoluteIndex =
196
194
  this.previousSectionsRowCount(event.to) + targetSectionedRowIndex;
@@ -215,6 +213,27 @@ export default {
215
213
  });
216
214
 
217
215
  GLib.action.execute(mergedSpec, this);
216
+
217
+ this.hackLingeringHighlight();
218
+ },
219
+ hackLingeringHighlight() {
220
+ // After a row finished dragging, the row below it will automatically be
221
+ // "active&hover" for some reason, which will cause it to be incorrectly
222
+ // highlighted
223
+ // This seems to be a browser/library bug, so as a workaround, we temporarily
224
+ // apply the "disabled" class so the highlighting doesn't happen.
225
+ this.$el
226
+ .querySelectorAll(":active .row_container > .glib-clickable:hover")
227
+ .forEach(activeRow => {
228
+ activeRow.classList.add("disabled");
229
+ document.addEventListener(
230
+ "mousemove",
231
+ function () {
232
+ activeRow.classList.remove("disabled");
233
+ },
234
+ { once: true }
235
+ );
236
+ });
218
237
  },
219
238
  getSectionIndex(element) {
220
239
  return element.dataset.dragsectionindex;
@@ -10,18 +10,9 @@ export default {
10
10
  required: true,
11
11
  default: function () {
12
12
  return {};
13
- }
14
- }
13
+ },
14
+ },
15
15
  },
16
- data() {
17
- return {
18
- hoverViewsSpec: null
19
- };
20
- },
21
- methods: {
22
- $ready() {
23
- }
24
- }
25
16
  };
26
17
  </script>
27
18
 
@@ -23,7 +23,6 @@ export default {
23
23
  // // Let the styles be handled by the child panel.
24
24
  // const outerSpec = {};
25
25
  // outerSpec["padding"] = this.spec["outerPadding"];
26
- // console.log("outerSpec", outerSpec);
27
26
  // const styles = this.$styles(outerSpec);
28
27
  //
29
28
  // const styles = this.genericStyles();
@@ -36,8 +35,6 @@ export default {
36
35
  // width: this.spec.width,
37
36
  // height: this.spec.height
38
37
  // });
39
- //
40
- // console.log("styles", styles);
41
38
 
42
39
  // Let the specified styles be handled by the child panel.
43
40
  const styles = this.$styles({
@@ -99,9 +99,6 @@ export default {
99
99
  // const createdAt = row[5]
100
100
  // const activationState = row[14] ? 'active' : 'pending'
101
101
  // count += 1
102
- // if (email.includes("'")) {
103
- // console.log("INVALID NAME", name)
104
- // }
105
102
  // str += `{ name: "${name}".to_s, email: '${email}'.to_s, created_at: '${createdAt}', activation_state: '${activationState}'},\n`
106
103
  // }
107
104
  // }
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div :class="$classes()">
3
3
  <v-switch
4
+ color="primary"
4
5
  v-model="enabled"
5
6
  :label="spec.text"
6
7
  hide-details
@@ -13,11 +14,11 @@
13
14
  <script>
14
15
  export default {
15
16
  props: {
16
- spec: { type: Object, required: true }
17
+ spec: { type: Object, required: true },
17
18
  },
18
19
  data() {
19
20
  return {
20
- enabled: false
21
+ enabled: false,
21
22
  };
22
23
  },
23
24
  methods: {
@@ -30,8 +31,8 @@ export default {
30
31
  } else {
31
32
  GLib.action.execute(this.spec.onDisabled, this);
32
33
  }
33
- }
34
- }
34
+ },
35
+ },
35
36
  };
36
37
  </script>
37
38
 
package/nav/dialog.vue CHANGED
@@ -1,10 +1,19 @@
1
1
  <template>
2
- <v-dialog :width="spec.width || 600" v-model="model" :fullscreen="fullscreen" :persistent="true">
3
- <v-card>
4
- <v-card-title v-if="title || showClose" class="text-h5" primary-title>
5
- {{ title }}
6
- <v-btn v-if="showClose" icon="close" size="small" :flat="true" class="dialog-close" @click.native="close" />
7
- </v-card-title>
2
+ <v-dialog v-model="model" :width="spec.width || 600" :dark="false" :fullscreen="fullscreen" :sm-and-down="false"
3
+ :persistent="!spec.closeOnBlur">
4
+ <v-card :style="hamburgerStyles" class="hamburger">
5
+ <!-- <v-card-title v-if="title || showClose" class="text-h5" primary-title> -->
6
+ <div>
7
+ <panels-responsive v-if="header" :spec="header" />
8
+ <div v-if="title" class="dialogs-title theme--light v-subheader">
9
+ {{ title }}
10
+ </div>
11
+
12
+ <v-btn v-if="showClose" text icon class="dialog-close" @click="close">
13
+ <v-icon>close</v-icon>
14
+ </v-btn>
15
+ </div>
16
+ <!-- </v-card-title> -->
8
17
 
9
18
  <div class="dialogs-body">
10
19
  <component :is="containerComponent" :spec="formSpec">
@@ -108,7 +117,7 @@ export default {
108
117
  });
109
118
  },
110
119
  $tearDown() {
111
- console.log("Dialog destroyed");
120
+ console.debug("Dialog destroyed");
112
121
  this.stack.remove(this);
113
122
  },
114
123
  close() {
@@ -152,6 +161,8 @@ export default {
152
161
  this.body = response.body;
153
162
  this.footer = response.footer;
154
163
  this.showClose = this.spec.showClose || false;
164
+
165
+ Action.execute(response.onLoad, this);
155
166
  });
156
167
  });
157
168
  }
@@ -166,7 +177,6 @@ export default {
166
177
  this.model = true;
167
178
  },
168
179
  updateMainHeight() {
169
- console.debug("Setting body height");
170
180
  this.mainHeight = window.innerHeight - 140;
171
181
  }
172
182
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/utils/history.js CHANGED
@@ -81,7 +81,7 @@ export default class {
81
81
  window.history.back();
82
82
  return true;
83
83
  } else {
84
- console.log("Reached beginning of navigation stack");
84
+ console.debug("Reached beginning of navigation stack");
85
85
  return false;
86
86
  }
87
87
  }