glib-web 3.0.12 → 3.0.13

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.
package/LICENSE CHANGED
File without changes
File without changes
@@ -6,8 +6,7 @@ export default class {
6
6
 
7
7
  const target = GLib.component.findById(spec.targetId);
8
8
  if (target) {
9
- // force update
10
- Object.assign(target.spec, spec.views[0], { forceUpdate: true });
9
+ Object.assign(target.spec, spec.views[0]);
11
10
  }
12
11
  }
13
12
  }
File without changes
File without changes
package/app.vue CHANGED
@@ -229,10 +229,15 @@ body,
229
229
  font-size: 16px;
230
230
  padding: 8px 16px;
231
231
  width: 100%;
232
- }
232
+ text-decoration: none;
233
+
234
+ &:hover {
235
+ background-color: #f3f4f6;
236
+ }
233
237
 
234
- .popover-menu-item:hover {
235
- background-color: #f3f4f6;
238
+ &:visited {
239
+ color: inherit;
240
+ }
236
241
  }
237
242
 
238
243
  .v-input__details {
File without changes
@@ -56,12 +56,16 @@ export default {
56
56
  return item.view == "panels/column-v1";
57
57
  },
58
58
  viewKey(item, index) {
59
- // Use view name for key to avoid component reuse issue
60
- if (!item.forceUpdate) {
61
- return `view${index}_${item.view}_value${item.value}`
62
- } else {
63
- return `comp-${Date.now().toString()}`
64
- }
59
+ return index
60
+
61
+ // return `view${index}_${item.view}`;
62
+
63
+ // // Use view name for key to avoid component reuse issue
64
+ // if (!item.forceUpdate) {
65
+ // return `view${index}_${item.view}_value${item.value}`
66
+ // } else {
67
+ // return `comp-${Date.now().toString()}`
68
+ // }
65
69
  // return item
66
70
  },
67
71
  $registryEnabled() {
File without changes
File without changes
File without changes
File without changes
@@ -3,7 +3,6 @@
3
3
  type="hidden"
4
4
  :name="fieldName"
5
5
  :value="fieldModel"
6
- :data-observe="spec"
7
6
  />
8
7
  </template>
9
8
 
@@ -14,7 +13,7 @@ export default {
14
13
  },
15
14
  methods: {
16
15
  $ready() {
17
- this.fieldModel = this.spec.value;
16
+ // this.fieldModel = this.spec.value;
18
17
  },
19
18
  },
20
19
  };
@@ -2,6 +2,7 @@
2
2
  <div :style="$styles()" :class="$classes()">
3
3
  <v-text-field ref="field" v-model="fieldModel" :label="spec.label" :name="fieldName" :placeholder="spec.placeholder"
4
4
  :density="density"
5
+ :hint="spec.hint"
5
6
  :maxlength="spec.maxLength || 255" :disabled="spec.readOnly" :type="config.type" :rules="rules"
6
7
  :prepend-inner-icon="leftIconName" :append-inner-icon="config.appendIcon" :prefix="spec.leftText"
7
8
  :suffix="spec.rightText" :min="spec.min" :max="spec.max" :autofocus="spec.autoFocus || false" validate-on="blur"
@@ -23,8 +24,8 @@ export default {
23
24
  },
24
25
  data() {
25
26
  return {
26
- config: {},
27
- rules: [],
27
+ // config: {},
28
+ // rules: [],
28
29
  onRightIconClick: null,
29
30
  fields: {
30
31
  email: {
@@ -92,20 +93,38 @@ export default {
92
93
  },
93
94
  density() {
94
95
  return determineDensity(this.spec.styleClasses)
96
+ },
97
+ config() {
98
+ return this.fields[this.type] || {}
99
+ },
100
+ rules() {
101
+ return this.$validation(this.config.rules);
102
+ }
103
+ },
104
+ watch: {
105
+ spec: {
106
+ handler(spec) {
107
+ if (this.config.onRightIconClick) {
108
+ this.onRightIconClick = () => {
109
+ this.config.onRightIconClick(this);
110
+ };
111
+ }
112
+ },
113
+ immediate: true
95
114
  }
96
115
  },
97
116
  methods: {
98
- $ready() {
99
- this.fieldModel = this.spec.value;
100
- this.config = this.fields[this.type] || {};
101
- this.rules = this.$validation(this.config.rules);
117
+ // $ready() {
118
+ // this.fieldModel = this.spec.value;
119
+ // this.config = this.fields[this.type] || {};
120
+ // this.rules = this.$validation(this.config.rules);
102
121
 
103
- if (this.config.onRightIconClick) {
104
- this.onRightIconClick = () => {
105
- this.config.onRightIconClick(this);
106
- };
107
- }
108
- },
122
+ // if (this.config.onRightIconClick) {
123
+ // this.onRightIconClick = () => {
124
+ // this.config.onRightIconClick(this);
125
+ // };
126
+ // }
127
+ // },
109
128
  togglePasswordVisibility() {
110
129
  const passwordField = this.fields["password"];
111
130
  if (passwordField.appendIcon == "visibility") {
@@ -117,7 +136,8 @@ export default {
117
136
  }
118
137
  },
119
138
  classes() {
120
- return this.$classes().concat("g-text-field--hintless");
139
+ // return this.$classes().concat("g-text-field--hintless");
140
+ return this.$classes()
121
141
  },
122
142
  action_focus() {
123
143
  this.$refs.field.focus();
@@ -130,14 +150,14 @@ export default {
130
150
  </script>
131
151
 
132
152
  <style lang="scss">
133
- .g-text-field--hintless {
134
- .v-input__details {
135
- min-height: 0;
136
- margin-bottom: 0;
153
+ // .g-text-field--hintless {
154
+ // .v-input__details {
155
+ // min-height: 0;
156
+ // margin-bottom: 0;
137
157
 
138
- .v-messages {
139
- min-height: 0;
140
- }
141
- }
142
- }
158
+ // .v-messages {
159
+ // min-height: 0;
160
+ // }
161
+ // }
162
+ // }
143
163
  </style>
@@ -4,6 +4,7 @@
4
4
  :placeholder="spec.placeholder" :maxlength="spec.maxLength || 255" :disabled="spec.readOnly" :height="height"
5
5
  :rules="$validation()" counter :outlined="$classes().includes('outlined')"
6
6
  :no-resize="$classes().includes('no-resize')" validate-on="blur" :variant="variant"
7
+ :density="density"
7
8
  persistent-placeholder></v-textarea>
8
9
  <input v-if="spec.readOnly" type="hidden" :name="fieldName" :value="fieldModel" />
9
10
  </div>
@@ -12,6 +13,7 @@
12
13
  <script>
13
14
  import eventFiltering from "../../utils/eventFiltering";
14
15
  import inputVariant from "../mixins/inputVariant";
16
+ import { determineDensity } from "../../utils/constant";
15
17
 
16
18
  export default {
17
19
  mixins: [inputVariant],
@@ -24,6 +26,11 @@ export default {
24
26
  height: null,
25
27
  };
26
28
  },
29
+ computed: {
30
+ density() {
31
+ return determineDensity(this.spec.styleClasses)
32
+ }
33
+ },
27
34
  methods: {
28
35
  $ready() {
29
36
  this.fieldModel = this.spec.value;
package/components/hr.vue CHANGED
File without changes
File without changes
@@ -49,16 +49,6 @@ export default {
49
49
  // this._executeIfReady(true);
50
50
  this.$updated();
51
51
  },
52
- // _executeIfReady(updated) {
53
- // if (updated) {
54
- // if (!this._renderingTheSamePage()) {
55
- // this.$tearDown();
56
- // this._ready();
57
- // }
58
- // } else {
59
- // this._ready();
60
- // }
61
- // },
62
52
  // deactivated() {
63
53
  unmounted() {
64
54
  this.$tearDown();
@@ -132,9 +122,6 @@ export default {
132
122
 
133
123
  this.$data._events = [];
134
124
 
135
- // Has to be executed before $ready()
136
- this._linkFieldModels();
137
-
138
125
  this.$ready();
139
126
 
140
127
  // Make sure events are dispatched after $ready(). Dispatching them during $ready() causes errors.
@@ -165,9 +152,6 @@ export default {
165
152
  },
166
153
  // Override to provide customization
167
154
  $update() {
168
- // This causes user input getting removed which is not what we want in some situations.
169
- // // This is so that the field's value gets updated to the new `value` property.
170
- // this._linkFieldModels();
171
155
  this.$ready();
172
156
  },
173
157
  async $recursiveUpdate(stack) {
File without changes
File without changes
@@ -44,6 +44,18 @@ export default {
44
44
  Object.assign(this.$data._fieldModels, { [this.fieldName]: this.$internalizeValue(val) })
45
45
 
46
46
  this._checkDirtyState(val, oldVal);
47
+ },
48
+ spec: {
49
+ handler(spec, oldSpec) {
50
+ if (spec) {
51
+ let valueChanged = true
52
+ if (oldSpec && oldSpec.value === spec.value) {
53
+ valueChanged = false
54
+ }
55
+ this._linkFieldModels(valueChanged);
56
+ }
57
+ },
58
+ immediate: true
47
59
  }
48
60
  },
49
61
  methods: {
@@ -186,7 +198,7 @@ export default {
186
198
  $externalizeValue(val) {
187
199
  return val;
188
200
  },
189
- _linkFieldModels() {
201
+ _linkFieldModels(valueChanged) {
190
202
  const hasCondition = this.spec && this.spec.showIf;
191
203
  const name = GLib.component.vueName(this);
192
204
 
@@ -200,7 +212,11 @@ export default {
200
212
  // Has to be executed before $ready(). This executes regardless of whether a form is found because fields
201
213
  // may be used without a form.
202
214
  this.fieldName = this.spec.name;
203
- this.fieldModel = this._sanitizeValue(this.spec.value);
215
+
216
+ // Avoid user input getting removed when updating certain parts of the page.
217
+ if (valueChanged) {
218
+ this.fieldModel = this._sanitizeValue(this.spec.value);
219
+ }
204
220
  }
205
221
  },
206
222
  action_resetValue() {
File without changes
File without changes
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div :style="genericStyles()" :class="$classes()">
3
+ <!-- This comment is not relevant anymore after moving all initializations to `computed()` and `watch()`. -->
3
4
  <!--
4
5
  NOTE: To make sure that the custom component gets updated, in the custom component,
5
6
  make sure to use one of the `spec` attributes directly or through a computed method.
@@ -11,7 +12,10 @@
11
12
  This should not be needed if a component (custom or not) uses $styles() or other mixin
12
13
  methods because those methods use `spec` attributes, which will force $ready() to be called.
13
14
  -->
14
- <component ref="ccomp" :is="template" v-if="customData" :name="spec.template" :spec="customData" />
15
+ <!-- <component ref="ccomp" :is="template" v-if="customData" :name="spec.template" :spec="customData" /> -->
16
+
17
+ <component :is="template" :name="spec.template" :spec="contentSpec" />
18
+
15
19
  </div>
16
20
  </template>
17
21
 
@@ -32,12 +36,11 @@ export default {
32
36
  },
33
37
  data() {
34
38
  return {
35
- customData: null,
39
+ // customData: null,
36
40
  };
37
41
  },
38
42
  computed: {
39
43
  template() {
40
-
41
44
  const name = `template-${this.spec.template.replace("/", "-")}`;
42
45
  const strict = true;
43
46
  if (strict) {
@@ -49,15 +52,19 @@ export default {
49
52
  return "template-unsupported";
50
53
  }
51
54
  },
55
+ contentSpec() {
56
+ const onClick = this.spec.onClick ? { onClick: this.spec.onClick } : {};
57
+ return Object.assign(onClick, this.spec.data);
58
+ }
52
59
  },
53
60
  methods: {
54
61
  $ready() {
55
- const onClick = this.spec.onClick ? { onClick: this.spec.onClick } : {};
56
- this.customData = Object.assign(onClick, this.spec.data);
57
- // Fix an issue where the panel doesn't get updated
58
- if (this.$refs.ccomp) {
59
- this.$refs.ccomp.$forceUpdate();
60
- }
62
+ // const onClick = this.spec.onClick ? { onClick: this.spec.onClick } : {};
63
+ // this.customData = Object.assign(onClick, this.spec.data);
64
+ // // Fix an issue where the panel doesn't get updated
65
+ // if (this.$refs.ccomp) {
66
+ // this.$refs.ccomp.$forceUpdate();
67
+ // }
61
68
  },
62
69
  $registryEnabled() {
63
70
  return false;
package/keys.js CHANGED
File without changes
package/nav/dialog.vue CHANGED
@@ -121,6 +121,7 @@ export default {
121
121
  this.updateMainHeight();
122
122
  });
123
123
  },
124
+ // TODO: This doesn't get called anymore after Vue3 upgrade.
124
125
  $tearDown() {
125
126
  console.debug("Dialog destroyed");
126
127
  this.stack.remove(this);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "3.0.12",
3
+ "version": "3.0.13",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -4,13 +4,27 @@ export default {
4
4
  mounted: function () {
5
5
  let spec = this.spec;
6
6
  if (spec && spec.id && this.$registryEnabled()) {
7
- GLib.component.register(spec.id, this);
7
+ const id = spec.id
8
+ const existingComponent = GLib.component.findById(id)
9
+ // A component with the same ID in a different page shouldn't be considered a
10
+ // duplicate. See `utils/components#deregister` for more details.
11
+ if (existingComponent && existingComponent._mountedUrl == this._mountedUrl) {
12
+ console.warn(
13
+ "Duplicate component ID:",
14
+ id,
15
+ "Existing:",
16
+ GLib.component.vueName(existingComponent),
17
+ "New:",
18
+ GLib.component.vueName(this)
19
+ );
20
+ }
21
+ GLib.component.register(id, this);
8
22
  }
9
23
  },
10
24
  unmounted: function () {
11
25
  let spec = this.spec;
12
26
  if (spec && spec.id && this.$registryEnabled()) {
13
- GLib.component.deregister(spec.id);
27
+ GLib.component.deregister(spec.id, this);
14
28
  }
15
29
  },
16
30
  methods: {
File without changes
package/styles/test.sass CHANGED
File without changes
package/styles/test.scss CHANGED
File without changes
File without changes
@@ -12,22 +12,29 @@ export default class {
12
12
  }
13
13
 
14
14
  static register(id, component) {
15
- if (this._registry[id]) {
16
- console.warn(
17
- "Duplicate component ID:",
18
- id,
19
- "Existing:",
20
- this.vueName(this._registry[id]),
21
- "New:",
22
- this.vueName(component)
23
- );
24
- }
15
+ // if (this._registry[id]) {
16
+ // console.warn(
17
+ // "Duplicate component ID:",
18
+ // id,
19
+ // "Existing:",
20
+ // this.vueName(this._registry[id]),
21
+ // "New:",
22
+ // this.vueName(component)
23
+ // );
24
+ // }
25
25
 
26
26
  this._registry[id] = component;
27
27
  }
28
28
 
29
- static deregister(id) {
30
- delete this._registry[id];
29
+ static deregister(id, component) {
30
+ // As the user navigates to a new page, there may be a component with the same ID in the next page,
31
+ // that is not reused from the component in the previous page. When this happens, the new
32
+ // component will get registered before the old component gets deregistered, in which case we
33
+ // should skip the deregistering or else we'd accidentally deregister the new component.
34
+ if (this._registry[id] == component) {
35
+ console.debug("Deregistering component with ID", id)
36
+ delete this._registry[id];
37
+ }
31
38
  }
32
39
 
33
40
  static vueName(component) {
@@ -41,7 +48,6 @@ export default class {
41
48
  }
42
49
  }
43
50
 
44
-
45
51
  return component.name
46
52
  }
47
53
 
package/utils/dom.js CHANGED
File without changes
package/utils/launch.js CHANGED
@@ -40,11 +40,16 @@ class LaunchPopover {
40
40
  if (component) {
41
41
  const placeholder = document.createElement('div')
42
42
 
43
- // component.$el.parentElement.appendChild(placeholder)
44
-
45
- // Attach the popover to the document body to prevent clipping caused by the parent's `overflow` property.
46
- // See https://stackoverflow.com/questions/51393427/z-index-to-ignore-max-height-and-always-come-on-top
47
- document.body.appendChild(placeholder);
43
+ // const pageBody = Utils.launch.dialog.closestBody(component) || Utils.history._pageBody;
44
+ const dialogBody = Utils.launch.dialog.closestBody(component)
45
+ if (dialogBody) {
46
+ // Put the popover on the dialog so that clicking it doesn't close a non-persistent dialog.
47
+ dialogBody.appendChild(placeholder);
48
+ } else {
49
+ // Attach the popover to the document body to prevent clipping caused by the parent's `overflow` property.
50
+ // See https://stackoverflow.com/questions/51393427/z-index-to-ignore-max-height-and-always-come-on-top
51
+ document.body.appendChild(placeholder);
52
+ }
48
53
 
49
54
  instance.mount(placeholder);
50
55
 
package/utils/storage.js CHANGED
File without changes
package/utils/url.js CHANGED
File without changes