glib-web 4.30.0 → 4.31.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.
@@ -1,16 +1,12 @@
1
1
  import { nextTick } from "vue";
2
+ import { forEachTargets } from "../util";
2
3
 
3
4
  export default class {
4
5
  execute(properties, component) {
5
- const target = GLib.component.findById(properties.targetId);
6
-
7
- if (!target) {
8
- console.warn("Component ID not found", properties.targetId);
9
- return;
10
- }
11
-
12
- target.action_resetValue();
13
-
6
+ forEachTargets(
7
+ properties,
8
+ (component) => component.action_resetValue()
9
+ );
14
10
  nextTick(() => {
15
11
  GLib.action.execute(properties["onReset"], component);
16
12
  });
@@ -1,16 +1,16 @@
1
1
  import jsonLogic from 'json-logic-js';
2
- import { fieldModels } from "../../components/composable/conditional";
2
+ import { getAllFormData } from "../../components/composable/form";
3
3
 
4
4
  export default class {
5
5
  execute(spec, component) {
6
- let condition = spec.condition
6
+ let condition = spec.condition;
7
7
 
8
- const dynamicGroupEntry = component.$closest("fields/internalDynamicGroupEntry");
9
- if (dynamicGroupEntry) {
10
- condition = dynamicGroupEntry.$populateIndexes(condition);
11
- }
8
+ // const dynamicGroupEntry = component.$closest("fields/internalDynamicGroupEntry");
9
+ // if (dynamicGroupEntry) {
10
+ // condition = dynamicGroupEntry.$populateIndexes(condition);
11
+ // }
12
12
 
13
- const result = jsonLogic.apply(condition, Object.assign({}, fieldModels, spec.variables));
13
+ const result = jsonLogic.apply(condition, Object.assign({}, getAllFormData(), spec.variables));
14
14
  if (result) {
15
15
  this.executeWithPassthroughParams(spec.onTrue, spec, component);
16
16
  } else {
@@ -0,0 +1,25 @@
1
+ import { isPresent } from "../utils/type";
2
+
3
+ // TODO: use this on other actions
4
+ export function forEachTargets(spec, cb) {
5
+ if (spec.targetId) {
6
+ const comp = getTarget(spec.targetId);
7
+ cb(comp);
8
+ return;
9
+ }
10
+
11
+ const components = spec.targetIds.map((id) => getTarget(id)).filter((comp) => comp);
12
+
13
+ components.forEach((comp) => cb(comp));
14
+ }
15
+
16
+ function getTarget(id) {
17
+ const target = GLib.component.findById(id);
18
+
19
+ if (!target) {
20
+ console.warn("Component ID not found", id);
21
+ return;
22
+ }
23
+
24
+ return target;
25
+ }
package/app.vue CHANGED
@@ -391,6 +391,19 @@ body,
391
391
  }
392
392
 
393
393
  /******/
394
+
395
+ // override textarea style
396
+ .fields-textarea .v-input--disabled {
397
+ pointer-events: unset;
398
+
399
+ .v-field--disabled {
400
+ pointer-events: unset;
401
+ }
402
+ }
403
+
404
+ .fields-textarea .v-input--readonly {
405
+ pointer-events: unset;
406
+ }
394
407
  </style>
395
408
 
396
409
  <style scoped>
@@ -38,6 +38,12 @@ const getFormData = (el, ignoredFields = new Set()) => {
38
38
  return obj;
39
39
  };
40
40
 
41
+ function getAllFormData() {
42
+ return Array.from(document.querySelectorAll('form')).reduce((prev, curr) => {
43
+ return Object.assign({}, prev, getFormData(curr));
44
+ }, {});
45
+ }
46
+
41
47
  function useGlibForm({ formRef }) {
42
48
  const initFormData = ref({});
43
49
  const currentFormData = ref({});
@@ -112,4 +118,4 @@ function useGlibInput({ props, cacheValue = true }) {
112
118
 
113
119
  }
114
120
 
115
- export { setBusy, triggerOnChange, triggerOnInput, useGlibForm, useGlibInput, getFormData };
121
+ export { setBusy, triggerOnChange, triggerOnInput, useGlibForm, useGlibInput, getFormData, getAllFormData };
@@ -2,8 +2,8 @@
2
2
  <div :style="$styles()" :class="$classes()" v-if="loadIf">
3
3
  <button-date v-if="spec.template" :type="type" :spec="spec" @datePicked="handleDatePicked"></button-date>
4
4
  <!-- See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date for why we need to use `pattern` -->
5
- <v-text-field v-else :color="gcolor" v-model="fieldModel" :name="fieldName" :label="spec.label" :hint="spec.hint"
6
- :type="type" :readonly="spec.readOnly" :disabled="inputDisabled" :min="sanitizeValue(spec.min)"
5
+ <v-text-field v-else ref="field" :color="gcolor" v-model="fieldModel" :name="fieldName" :label="spec.label"
6
+ :hint="spec.hint" :type="type" :readonly="spec.readOnly" :disabled="inputDisabled" :min="sanitizeValue(spec.min)"
7
7
  :max="sanitizeValue(spec.max)" :pattern="pattern" :rules="$validation()" :style="$styles()"
8
8
  :density="$classes().includes('compact') ? 'compact' : 'default'" :clearable="spec.clearable" @change="onChange"
9
9
  :variant="variant" validate-on="blur" persistent-placeholder />
@@ -43,6 +43,9 @@ export default {
43
43
  this.fieldModel = value;
44
44
  this.$executeOnChange();
45
45
  },
46
+ action_focus() {
47
+ this.$refs.field.focus();
48
+ },
46
49
  $registryEnabled() {
47
50
  return false;
48
51
  }
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div :style="styles()" :class="$classes()" v-if="loadIf">
3
- <v-textarea :color="gcolor" v-model="fieldModel" :label="spec.label" :name="fieldName" :hint="spec.hint"
3
+ <v-textarea ref="field" :color="gcolor" v-model="fieldModel" :label="spec.label" :name="fieldName" :hint="spec.hint"
4
4
  :placeholder="spec.placeholder" :maxlength="spec.maxLength || 255" :readonly="spec.readOnly" :height="height"
5
5
  :rules="$validation()" counter :outlined="$classes().includes('outlined')" :disabled="inputDisabled"
6
6
  :no-resize="$classes().includes('no-resize')" validate-on="blur" :variant="variant" :density="density"
@@ -41,8 +41,11 @@ export default {
41
41
  },
42
42
  onChange: eventFiltering.debounce(function () {
43
43
  this.$executeOnChange();
44
- }, 300)
45
- }
44
+ }, 300),
45
+ action_focus() {
46
+ this.$refs.field.focus();
47
+ },
48
+ },
46
49
  };
47
50
  </script>
48
51
 
@@ -3,6 +3,11 @@ import launch from "../../utils/launch";
3
3
  import { htmlElement } from "../helper";
4
4
 
5
5
  export default defineComponent({
6
+ data() {
7
+ return {
8
+ key: Math.random().toString(36).slice(2, 7)
9
+ };
10
+ },
6
11
  computed: {
7
12
  properties() {
8
13
  return {
@@ -13,6 +18,18 @@ export default defineComponent({
13
18
  }
14
19
  },
15
20
  methods: {
21
+ handleMouseEnter() {
22
+ const properties = {
23
+ body: { childViews: [this.properties] },
24
+ key: this.key,
25
+ placement: this.spec.tooltip.placement || 'top',
26
+ styleClass: 'views-tooltip'
27
+ };
28
+ launch.popover.open(properties, this);
29
+ },
30
+ handleMouseLeave() {
31
+ launch.popover.close({ key: this.key });
32
+ },
16
33
  $mounted() {
17
34
  const tooltip = this.spec.tooltip;
18
35
 
@@ -20,26 +37,22 @@ export default defineComponent({
20
37
 
21
38
  this.initTooltip();
22
39
  },
23
- initTooltip() {
24
- const key = Math.random().toString(36).slice(2, 7);
40
+ $tearDown() {
41
+ const el = htmlElement(this);
42
+
43
+ if (el) {
44
+ el.removeEventListener('mouseenter', this.handleMouseEnter);
45
+ el.removeEventListener('mouseleave', this.handleMouseLeave);
46
+ }
25
47
 
26
- const handleMouseEnter = () => {
27
- const properties = {
28
- body: { childViews: [this.properties] },
29
- key: key,
30
- placement: this.spec.tooltip.placement || 'top',
31
- styleClass: 'views-tooltip'
32
- };
33
- launch.popover.open(properties, this);
34
- };
35
- const handleMouseLeave = () => {
36
- launch.popover.close({ key: key });
37
- };
38
48
 
49
+ this.handleMouseLeave();
50
+ },
51
+ initTooltip() {
39
52
  const el = htmlElement(this);
40
53
 
41
- el.addEventListener('mouseenter', handleMouseEnter);
42
- el.addEventListener('mouseleave', handleMouseLeave);
54
+ el.addEventListener('mouseenter', this.handleMouseEnter);
55
+ el.addEventListener('mouseleave', this.handleMouseLeave);
43
56
  }
44
57
  }
45
58
  });
@@ -15,6 +15,7 @@
15
15
  <script>
16
16
  import { onMounted, provide, ref } from "vue";
17
17
  import { useGlibForm } from "../composable/form";
18
+ import eventFiltering from "../../utils/eventFiltering";
18
19
 
19
20
  export default {
20
21
  props: {
@@ -138,7 +139,7 @@ export default {
138
139
  this.formCtx = { form: this.$refs.form };
139
140
  if (onChange) this.$executeOnChange();
140
141
  };
141
- this.formElement.onchange = () => onChangeHandler();
142
+ this.formElement.onchange = eventFiltering.debounce(onChangeHandler, 300);
142
143
 
143
144
  this.formElement.oninput = (event) => this.glibForm.updateDirtyState(event);
144
145
  }
@@ -24,7 +24,16 @@ export default {
24
24
  },
25
25
  methods: {
26
26
  classes: function () {
27
- return this.$classes().concat("layouts-split");
27
+ // This class is provided by Vuetify: https://vuetifyjs.com/en/styles/flex/#flex-align.
28
+ const configs = {
29
+ 'top': 'align-start',
30
+ 'middle': 'align-center',
31
+ 'bottom': 'align-end'
32
+ };
33
+
34
+ const alignClass = configs[this.spec.align] || 'align-start';
35
+
36
+ return this.$classes().concat(["layouts-split", alignClass]);
28
37
  }
29
38
  }
30
39
  };
package/nav/dialog.vue CHANGED
@@ -36,9 +36,9 @@
36
36
  </v-btn>
37
37
  </v-card-actions>
38
38
  </v-card>
39
- <glib-component v-show="loading && spec.loaderViews" v-for="(loaderView, index) in spec.loaderViews" :key="index"
40
- :spec="loaderView"></glib-component>
41
-
39
+ <template v-if="loading && spec.loaderViews">
40
+ <glib-component v-for="(loaderView, index) in spec.loaderViews" :key="index" :spec="loaderView"></glib-component>
41
+ </template>
42
42
  </v-dialog>
43
43
  </template>
44
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "4.30.0",
3
+ "version": "4.31.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/store.js CHANGED
@@ -42,7 +42,6 @@ export const closeAllPopover = () => {
42
42
  popovers.value.forEach((popover) => popover.close());
43
43
  popovers.value = [];
44
44
  vueApp.sheet.show = false;
45
-
46
45
  };
47
46
 
48
47
  export const glibevent = reactive({
@@ -48,6 +48,10 @@ export default class LaunchDialog {
48
48
  Utils.type.ifObject(dialogs.value.last(), dialog => {
49
49
  dialog.reload(properties);
50
50
  });
51
+
52
+ nextTick(() => {
53
+ Action.execute(properties.onReload, component);
54
+ });
51
55
  }
52
56
 
53
57
  static close(properties, component) {