glib-web 3.24.4 → 3.25.1

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/action.js CHANGED
@@ -29,6 +29,7 @@ import ActionsWindowsOpen from "./actions/windows/open";
29
29
  import ActionsWindowsOpenWeb from "./actions/windows/openWeb";
30
30
  import ActionsWindowsReload from "./actions/windows/reload";
31
31
  import ActionsWindowsCloseWithReload from "./actions/windows/closeWithReload";
32
+ import ActionsWindowsCloseWithOpen from "./actions/windows/closeWithOpen";
32
33
  import ActionsWindowsRefreshState from "./actions/windows/refreshState";
33
34
  import ActionsWindowsPrint from "./actions/windows/print";
34
35
 
@@ -45,6 +46,8 @@ import ActionsAuthSaveCsrfToken from "./actions/auth/saveCsrfToken";
45
46
  import ActionsAuthRestart from "./actions/auth/restart";
46
47
  import ActionsCreditCard from "./actions/auth/creditCard";
47
48
 
49
+ import ActionsCookiesSave from "./actions/cookies/save";
50
+
48
51
  import ActionsAnalyticsLogEvent from "./actions/analytics/logEvent";
49
52
 
50
53
  import ActionCommandsCopy from "./actions/commands/copy";
@@ -67,8 +70,11 @@ import ActionComponentsUpdate from "./actions/components/update";
67
70
  import ActionComponentsFind from "./actions/components/find";
68
71
  import ActionComponentsFindClosest from "./actions/components/findClosest";
69
72
  import ActionComponentsReplace from "./actions/components/replace";
73
+ import ActionComponentsReplaceChildren from "./actions/components/replaceChildren";
70
74
  import ActionComponentsSet from "./actions/components/set";
71
75
 
76
+ import ActionLogicsSet from "./actions/logics/set";
77
+
72
78
  import ActionListsAppend from "./actions/lists/append";
73
79
 
74
80
  import { dialogs, vueApp } from "./store";
@@ -103,6 +109,7 @@ const actions = {
103
109
  "windows/openWeb": ActionsWindowsOpenWeb,
104
110
  "windows/reload": ActionsWindowsReload,
105
111
  "windows/closeWithReload": ActionsWindowsCloseWithReload,
112
+ "windows/closeWithOpen": ActionsWindowsCloseWithOpen,
106
113
  "windows/refreshState": ActionsWindowsRefreshState,
107
114
  "windows/print": ActionsWindowsPrint,
108
115
 
@@ -119,6 +126,8 @@ const actions = {
119
126
  "auth/restart": ActionsAuthRestart,
120
127
  "auth/creditCard": ActionsCreditCard,
121
128
 
129
+ "cookies/save": ActionsCookiesSave,
130
+
122
131
  "analytics/logEvent": ActionsAnalyticsLogEvent,
123
132
 
124
133
  "commands/copy": ActionCommandsCopy,
@@ -140,8 +149,11 @@ const actions = {
140
149
  "components/find": ActionComponentsFind,
141
150
  "components/findClosest": ActionComponentsFindClosest,
142
151
  "components/replace": ActionComponentsReplace,
152
+ "components/replaceChildren": ActionComponentsReplaceChildren,
143
153
  "components/set": ActionComponentsSet,
144
154
 
155
+ "logics/set": ActionLogicsSet,
156
+
145
157
  "lists/append": ActionListsAppend
146
158
  };
147
159
 
@@ -1,4 +1,4 @@
1
- // Experimental
1
+ // Experimental. Can this be merged with `components_set` ?
2
2
  export default class {
3
3
  execute(spec, component) {
4
4
  const target = GLib.component.findById(spec.targetId) || component;
@@ -0,0 +1,15 @@
1
+ import { nextTick } from "vue";
2
+
3
+ // Experimental
4
+ export default class {
5
+ execute(spec, component) {
6
+ const target = GLib.component.findById(spec.targetId) || component;
7
+ if (target) {
8
+ Object.assign(target.spec.childViews, spec.childViews);
9
+ }
10
+
11
+ nextTick(() => {
12
+ Action.execute(spec.onReplace, target);
13
+ });
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ export default class {
2
+ execute(spec, component) {
3
+ const key = spec.key;
4
+ const value = spec.value;
5
+ if (Utils.type.isNotNull(key) && Utils.type.isNotNull(value)) {
6
+ document.cookie = `${key}=${value}`;
7
+ Action.execute(spec.onSave, component);
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,40 @@
1
+ import jsonLogic from 'json-logic-js';
2
+
3
+ const subscript = function(a, b) {
4
+ if (a) {
5
+ if (b) { // This is expected when the dependent field doesn't have a value
6
+ return a[b];
7
+ } else {
8
+ console.info('Null subscript')
9
+ }
10
+ } else {
11
+ console.error('Left hand operator not found')
12
+ }
13
+ };
14
+ jsonLogic.add_operation("[]", subscript);
15
+
16
+ // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing
17
+ const nullishCoalescing = function(a, b) {
18
+ return a ?? b;
19
+ }
20
+ jsonLogic.add_operation("??", nullishCoalescing);
21
+
22
+ export default class {
23
+ execute(spec, component) {
24
+ let targetComponent = component;
25
+
26
+ if (spec.targetId) {
27
+ targetComponent = GLib.component.findById(spec.targetId);
28
+ }
29
+
30
+ Utils.type.ifObject(spec.conditionalData, (properties) => {
31
+ const data = {}
32
+ for (const key in properties) {
33
+ data[key] = jsonLogic.apply(properties[key], spec.variables);
34
+ }
35
+ targetComponent.action_merge(data);
36
+ });
37
+
38
+ GLib.action.execute(spec.onSet, targetComponent);
39
+ }
40
+ }
@@ -1,4 +1,4 @@
1
- import { vueApp } from "../../store";
1
+ import { executeGlobalEvent, vueApp } from "../../store";
2
2
 
3
3
  export default class {
4
4
  execute(properties, component) {
@@ -0,0 +1,9 @@
1
+ export default class {
2
+ execute(properties, component) {
3
+ // TODO: Need to find out how to prevent onpopstate() from executing.
4
+ Utils.history.back()
5
+
6
+ // Open right away so there is no visible flicker.
7
+ Utils.http.load(properties, component, true);
8
+ }
9
+ }
package/app.vue CHANGED
@@ -14,7 +14,9 @@
14
14
  </div>
15
15
 
16
16
  <div id="page_body" class="pages-body body-wrapper">
17
- <panels-responsive :spec="body" />
17
+ <panels-responsive class="body-header" :spec="bodyHeader" />
18
+ <panels-responsive class="body-content" :spec="body" />
19
+ <panels-responsive class="body-footer" :spec="bodyFooter" />
18
20
  </div>
19
21
 
20
22
  <div class="pages-footer">
@@ -72,6 +74,9 @@ export default {
72
74
  footer() {
73
75
  return this.page.footer || {};
74
76
  },
77
+ bodyFooter() {
78
+ return this.page.bodyFooter || {};
79
+ },
75
80
  containerComponent() {
76
81
  if (this.formSpec) {
77
82
  this.name = "panels-form";
@@ -214,6 +219,24 @@ body,
214
219
  height: 100%;
215
220
  }
216
221
 
222
+ .pages-body {
223
+ display: flex;
224
+ flex-direction: column;
225
+
226
+ .body-header {
227
+ display: block;
228
+ }
229
+
230
+ .body-content {
231
+ flex: 1 0 auto;
232
+ display: block;
233
+ }
234
+
235
+ .body-footer {
236
+ display: block;
237
+ }
238
+ }
239
+
217
240
  /******/
218
241
 
219
242
  /*** panels/scrollTo support ***/
@@ -2,6 +2,7 @@ import { Chart, Colors } from "chart.js";
2
2
  import chartDataLabels from 'chartjs-plugin-datalabels';
3
3
  import doughnutLabel from 'chartjs-plugin-doughnutlabel-v3';
4
4
  import { Vue } from "../..";
5
+ import { computePosition, flip, offset } from '@floating-ui/dom';
5
6
 
6
7
  import 'chartkick/chart.js';
7
8
 
@@ -30,9 +31,89 @@ const multipleDataSeries = (dataSeries) => {
30
31
 
31
32
  const singleDataSeries = (dataSeries) => dataSeries.reduce((prev, curr) => Object.assign(prev, { [curr.title]: curr.value }), {});
32
33
 
34
+ const getOrCreateTooltip = (chart) => {
35
+ let tooltipEl = chart.canvas.parentNode.querySelector('#_glib-chart-tooltip');
36
+ let referenceEl = chart.canvas.parentNode.querySelector('#_glib-chart-reference');
37
+
38
+ if (!tooltipEl) {
39
+ tooltipEl = document.createElement('div');
40
+ tooltipEl.id = '_glib-chart-tooltip';
41
+ tooltipEl.style.opacity = 1;
42
+ tooltipEl.style.pointerEvents = 'none';
43
+ tooltipEl.style.position = 'absolute';
44
+ tooltipEl.style.transition = 'all .1s ease';
45
+ tooltipEl.style.lineHeight = 1;
46
+
47
+ chart.canvas.parentNode.appendChild(tooltipEl);
48
+ }
49
+
50
+ if (!referenceEl) {
51
+ referenceEl = document.createElement('div');
52
+ referenceEl.id = '_glib-chart-reference';
53
+ referenceEl.style.position = 'absolute';
54
+ referenceEl.style.width = '1px';
55
+ referenceEl.style.height = '1px';
56
+ referenceEl.style.opacity = 0;
57
+
58
+ chart.canvas.parentNode.appendChild(referenceEl);
59
+ }
60
+
61
+ return { tooltipEl, referenceEl };
62
+ };
63
+
64
+ const externalTooltipHandler = (multiple, dataSeries) => {
65
+ return (context) => {
66
+ const tooltipData = getData(multiple, dataSeries, context.tooltip.dataPoints[0]);
67
+
68
+ if (!tooltipData) return;
69
+
70
+ const innerHTML = tooltipData.tooltip;
71
+
72
+ // Tooltip Element
73
+ const { chart, tooltip } = context;
74
+ const { tooltipEl, referenceEl } = getOrCreateTooltip(chart);
75
+
76
+ // Hide if no tooltip
77
+ if (tooltip.opacity === 0) {
78
+ tooltipEl.style.opacity = 0;
79
+ return;
80
+ }
81
+
82
+ if (tooltip.body) {
83
+ tooltipEl.innerHTML = innerHTML;
84
+ }
85
+
86
+ const position = chart.canvas.getBoundingClientRect();
87
+
88
+ referenceEl.style.left = position.left + tooltip.caretX + 'px';
89
+ referenceEl.style.top = position.top + tooltip.caretY + 'px';
90
+ computePosition(referenceEl, tooltipEl, { placement: 'right', middleware: [flip(), offset(8)] })
91
+ .then(({ x, y }) => {
92
+ tooltipEl.style.left = x + 'px';
93
+ tooltipEl.style.top = y + 'px';
94
+ });
95
+
96
+ // Display, position, and set styles for font
97
+ tooltipEl.style.opacity = 1;
98
+ tooltipEl.style.font = tooltip.options.bodyFont.string;
99
+ tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
100
+ };
101
+ };
102
+
103
+ const getData = (multiple, dataSeries, context) => {
104
+ const { dataIndex, datasetIndex } = context;
105
+ const dataset = dataSeries[datasetIndex];
106
+ if (multiple && Array.isArray(dataset.points) && dataset.points[dataIndex]) {
107
+ return dataset.points[dataIndex];
108
+ }
109
+ if (!multiple && dataSeries[dataIndex]) {
110
+ return dataSeries[dataIndex];
111
+ }
112
+ };
113
+
33
114
  function useChart({ dataSeries, spec, multiple = true }) {
34
115
  const isDonut = [spec.styleClasses].flat().includes('donut');
35
- const { datalabels, centerLabel } = spec.plugins || {};
116
+ const { datalabels, centerLabel, customTooltip } = spec.plugins || {};
36
117
  const legend = spec.legend || { display: true };
37
118
 
38
119
  let series = null;
@@ -85,6 +166,13 @@ function useChart({ dataSeries, spec, multiple = true }) {
85
166
  };
86
167
  }
87
168
 
169
+ if (customTooltip) {
170
+ options.plugins.tooltip = {
171
+ enabled: false,
172
+ external: externalTooltipHandler(multiple, dataSeries)
173
+ };
174
+ }
175
+
88
176
  return { series, colors, options };
89
177
  }
90
178
 
@@ -10,7 +10,7 @@
10
10
  <p v-if="props.spec.hint" class="subtitle">{{ props.spec.hint }}</p>
11
11
  </div>
12
12
 
13
- <input v-for="(file, index) in completedFiles" type="hidden" :name="props.spec.name" :value="file.signedId"
13
+ <input v-for="(file, index) in files" type="hidden" :name="props.spec.name" :value="file.signedId"
14
14
  :disabled="inputDisabled" :key="`hidden-${index}`">
15
15
  </div>
16
16
 
@@ -246,8 +246,6 @@ export default defineComponent({
246
246
  return Object.keys(files.value).length > 0;
247
247
  });
248
248
 
249
- const completedFiles = computed(() => Object.values(files.value).filter((value) => value.status == 'completed'));
250
-
251
249
  function handleDrop(e) {
252
250
  e.preventDefault();
253
251
  uploadFiles(
@@ -325,7 +323,6 @@ export default defineComponent({
325
323
  handleClick,
326
324
  handleRemoveFile,
327
325
  showUploadedFile,
328
- completedFiles,
329
326
  responseMessages,
330
327
  uploadTitle,
331
328
  props
@@ -212,14 +212,15 @@ export default {
212
212
  this.$nextTick(() => {
213
213
  const value = newValue || this.fieldModel;
214
214
  const formData = {
215
- [this.fieldName]: value
215
+ [this.spec.paramNameForFieldName || this.fieldName]: value
216
216
  };
217
217
  const params = this.spec.paramNameForFormData
218
218
  ? {
219
- [this.spec.paramNameForFormData]: formData
219
+ [this.spec.paramNameForFormData || formData]: formData
220
220
  }
221
221
  : formData;
222
- const data = merge({}, onChange, { formData: params });
222
+
223
+ const data = merge({}, onChange, params);
223
224
  GLib.action.execute(data, this);
224
225
  });
225
226
  });
@@ -46,15 +46,20 @@ export default {
46
46
  break;
47
47
  }
48
48
 
49
+ const containerHeight = this.spec.height;
49
50
  const chunkSize = 12 / colSize;
50
51
  const panels = []
51
52
  for (let i = 0; i < childViews.length; i += chunkSize) {
52
53
  const chunk = childViews.slice(i, i + chunkSize);
53
54
  panels.push({
54
55
  view: 'panels/responsive',
56
+ height: containerHeight ? containerHeight - 100 : null,
57
+ // backgroundColor: '#ff0000',
55
58
  childViews: chunk.map((panel) => {
56
59
  return {
57
60
  view: 'panels/column',
61
+ // backgroundColor: '#00ff00',
62
+ height: 'matchParent',
58
63
  [breakpoint]: { cols: colSize },
59
64
  childViews: [panel]
60
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "3.24.4",
3
+ "version": "3.25.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {