glib-web 0.12.0 → 0.12.2

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 (60) hide show
  1. package/LICENSE +0 -0
  2. package/action.js +1 -0
  3. package/actions/auth/restart.js +0 -0
  4. package/actions/commands/copy.js +6 -6
  5. package/actions/dialogs/oauth.js +0 -0
  6. package/actions/dialogs/options.js +0 -0
  7. package/actions/windows/openWeb.js +0 -0
  8. package/components/_message.vue +0 -0
  9. package/components/_responsive.vue +2 -2
  10. package/components/datetime.vue +0 -0
  11. package/components/fab.vue +0 -0
  12. package/components/fields/check.vue +0 -11
  13. package/components/fields/checkGroup.vue +56 -14
  14. package/components/fields/country/countries.js +0 -0
  15. package/components/fields/country/field.vue +0 -0
  16. package/components/fields/country/regions.js +0 -0
  17. package/components/fields/datetime.vue +0 -0
  18. package/components/fields/dynamicSelect.vue +0 -0
  19. package/components/fields/location.vue +3 -3
  20. package/components/fields/richText.vue +7 -4
  21. package/components/fields/select.vue +0 -0
  22. package/components/fields/timeZone.vue +0 -0
  23. package/components/hr.vue +0 -0
  24. package/components/html.vue +0 -0
  25. package/components/markdown.vue +9 -3
  26. package/components/mixins/longClick.js +0 -0
  27. package/components/mixins/scrolling.js +0 -0
  28. package/components/mixins/styles.js +22 -13
  29. package/components/mixins/table/export.js +0 -0
  30. package/components/mixins/table/import.js +0 -0
  31. package/components/p.vue +0 -0
  32. package/components/panels/carousel.vue +1 -1
  33. package/components/panels/flow.vue +1 -1
  34. package/components/panels/grid.vue +1 -1
  35. package/components/panels/horizontal.vue +1 -1
  36. package/components/panels/list.vue +2 -1
  37. package/components/panels/scroll.vue +1 -1
  38. package/components/panels/split.vue +1 -1
  39. package/components/panels/table.vue +3 -3
  40. package/components/panels/ul.vue +1 -1
  41. package/components/panels/vertical.vue +1 -1
  42. package/components/shareButton.vue +4 -2
  43. package/index.js +0 -3
  44. package/keys.js +0 -0
  45. package/nav/dialog.vue +11 -6
  46. package/nav/drawerButton.vue +0 -0
  47. package/package.json +1 -1
  48. package/settings.json.example +0 -0
  49. package/styles/test.sass +0 -0
  50. package/styles/test.scss +0 -0
  51. package/templates/thumbnail.vue +20 -3
  52. package/templates/unsupported.vue +0 -0
  53. package/utils/dom.js +0 -0
  54. package/utils/form.js +3 -0
  55. package/utils/http.js +19 -7
  56. package/utils/launch.js +12 -0
  57. package/utils/public.js +0 -0
  58. package/utils/settings.js +0 -0
  59. package/utils/storage.js +0 -0
  60. package/utils/url.js +0 -0
package/LICENSE CHANGED
File without changes
package/action.js CHANGED
@@ -162,6 +162,7 @@ export default class Action {
162
162
  }
163
163
 
164
164
  static handleResponse(response, component) {
165
+ // TODO: The execution should be in the following order: onResponse, page render, onLoad
165
166
  if (response.header || response.body || response.footer) {
166
167
  Utils.http.forceComponentUpdate(() => {
167
168
  window.vueApp.page = response;
File without changes
@@ -1,11 +1,11 @@
1
1
  export default class {
2
- execute(properties) {
3
- let spec = Object.assign({}, properties, {
4
- message: "Copied",
5
- styleClasses: ["success"]
6
- });
2
+ execute(properties, component) {
3
+ // let spec = Object.assign({}, properties, {
4
+ // message: "Copied",
5
+ // styleClasses: ["success"]
6
+ // });
7
7
  navigator.clipboard.writeText(properties.text).then(
8
- () => Utils.launch.snackbar.open(spec),
8
+ () => GLib.action.execute(properties.onCopy, component),
9
9
  reason => console.error("Could not copy text: " + reason)
10
10
  );
11
11
  }
File without changes
File without changes
File without changes
File without changes
@@ -9,7 +9,7 @@
9
9
  >
10
10
  <v-row no-gutters class="full-height">
11
11
  <template v-for="(item, index) in spec.childViews">
12
- <ui-component
12
+ <glib-component
13
13
  v-if="isColumn(item)"
14
14
  :key="viewKey(item, index)"
15
15
  :spec="item"
@@ -20,7 +20,7 @@
20
20
  class="full-width"
21
21
  :style="innerStyles"
22
22
  >
23
- <ui-component :spec="item" />
23
+ <glib-component :spec="item" />
24
24
  </div>
25
25
  </template>
26
26
  </v-row>
File without changes
File without changes
@@ -1,6 +1,5 @@
1
1
  <template>
2
2
  <div :class="$classes()" :style="$styles()">
3
- <!-- <fields-hidden v-if="uncheckSpec" :spec="uncheckSpec" /> -->
4
3
  <!-- This hidden field should always be there to make sure the submitted param is not empty,
5
4
  which could cause "Not accessible" error on the server. -->
6
5
  <input type="hidden" :name="fieldName" :value="spec.uncheckValue" />
@@ -18,12 +17,7 @@
18
17
  </template>
19
18
 
20
19
  <script>
21
- // import HiddenField from "./hidden";
22
-
23
20
  export default {
24
- // components: {
25
- // "fields-hidden": HiddenField
26
- // },
27
21
  props: {
28
22
  spec: { type: Object, required: true }
29
23
  },
@@ -31,7 +25,6 @@ export default {
31
25
  return {
32
26
  groupName: null,
33
27
  fieldType: null
34
- // uncheckSpec: null
35
28
  };
36
29
  },
37
30
  methods: {
@@ -55,10 +48,6 @@ export default {
55
48
  this.fieldType = "switch";
56
49
  }
57
50
  });
58
-
59
- // Utils.type.ifNotNull(this.spec.uncheckValue, value => {
60
- // this.uncheckSpec = { name: this.spec.name, value: value };
61
- // });
62
51
  },
63
52
  changed(event) {
64
53
  // Execute later to ensure the checkbox's checked state has been updated.
@@ -1,35 +1,60 @@
1
1
  <template>
2
- <div ref="checkGroup" data-component="checkGroup" :name="spec.name">
3
- <fields-hidden v-if="!anyChecked" :spec="uncheckSpec" />
2
+ <div
3
+ ref="checkGroup"
4
+ class="checkgroup"
5
+ data-component="checkGroup"
6
+ :name="spec.name"
7
+ >
8
+ <!-- <fields-hidden v-if="!anyChecked" :spec="uncheckSpec" /> -->
4
9
 
5
10
  <div v-for="(item, index) in spec.childViews" :key="index">
6
- <ui-component :spec="item" />
11
+ <glib-component :spec="item" />
7
12
  </div>
13
+
14
+ <v-text-field
15
+ class="checkgroup__uncheckvalue"
16
+ :disabled="anyChecked"
17
+ :name="spec.name"
18
+ :value="spec.uncheckValue"
19
+ :rules="rules"
20
+ />
8
21
  </div>
9
22
  </template>
10
23
 
11
24
  <script>
12
- import HiddenField from "./hidden";
25
+ // import HiddenField from "./hidden";
13
26
 
14
27
  export default {
15
- components: {
16
- "fields-hidden": HiddenField
17
- },
28
+ // components: {
29
+ // "fields-hidden": HiddenField
30
+ // },
18
31
  props: {
19
32
  spec: { type: Object, required: true }
20
33
  },
21
34
  data() {
22
35
  return {
23
- anyChecked: false
36
+ anyChecked: false,
37
+ errorMessage: null,
38
+ rules: [
39
+ _v => {
40
+ return this.anyChecked || this.errorMessage || true;
41
+ }
42
+ ]
24
43
  };
25
44
  },
26
- computed: {
27
- uncheckSpec() {
28
- return { name: this.spec.name, value: this.spec.uncheckValue };
29
- }
30
- },
45
+ // computed: {
46
+ // uncheckSpec() {
47
+ // return { name: this.spec.name, value: this.spec.uncheckValue };
48
+ // }
49
+ // },
31
50
  methods: {
32
51
  $ready() {
52
+ const validation = this.spec.validation || {};
53
+
54
+ Utils.type.ifObject(validation.required, required => {
55
+ this.errorMessage = required.message;
56
+ });
57
+
33
58
  this.detectChecked();
34
59
  const vm = this;
35
60
  this.$el.addEventListener(
@@ -48,6 +73,7 @@ export default {
48
73
  .forEach(function(checkbox) {
49
74
  if (checkbox.checked) {
50
75
  vm.anyChecked = true;
76
+ return;
51
77
  }
52
78
  });
53
79
  }
@@ -55,4 +81,20 @@ export default {
55
81
  };
56
82
  </script>
57
83
 
58
- <style scoped></style>
84
+ <style lang="scss">
85
+ // Hide the uncheck field, but continue to show the validation div.
86
+ .checkgroup__uncheckvalue {
87
+ padding-top: 0px;
88
+
89
+ .v-input__slot {
90
+ display: none;
91
+ }
92
+
93
+ // Hide the entire component unless there is a validation message.
94
+ display: none;
95
+
96
+ &.error--text {
97
+ display: block;
98
+ }
99
+ }
100
+ </style>
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -50,17 +50,17 @@
50
50
  @dragend="onDrag"
51
51
  />
52
52
  </gmap-map>
53
- <ui-component
53
+ <glib-component
54
54
  v-if="latitudeField"
55
55
  ref="latitudeView"
56
56
  :spec="latitudeField"
57
57
  />
58
- <ui-component
58
+ <glib-component
59
59
  v-if="longitudeField"
60
60
  ref="longitudeView"
61
61
  :spec="longitudeField"
62
62
  />
63
- <ui-component v-if="zoomField" ref="zoomView" :spec="zoomField" />
63
+ <glib-component v-if="zoomField" ref="zoomView" :spec="zoomField" />
64
64
  </v-container>
65
65
  </template>
66
66
 
@@ -12,8 +12,8 @@
12
12
  <input
13
13
  v-for="(imageKey, index) in imageKeys"
14
14
  :key="index"
15
- type="hidden"
16
- name="imageUrls[]"
15
+ type="text"
16
+ :name="imageUploader.name"
17
17
  :value="images[imageKey]"
18
18
  />
19
19
 
@@ -52,7 +52,8 @@ export default {
52
52
  cleanValue: "",
53
53
  images: {},
54
54
  imageKeys: [],
55
- progress: { value: -1 }
55
+ progress: { value: -1 },
56
+ imageUploader: {}
56
57
  }),
57
58
  // mounted: function () {
58
59
  // const vm = this
@@ -92,10 +93,12 @@ export default {
92
93
  return "{{IMAGE_NOT_FOUND}}";
93
94
  }
94
95
  );
96
+
97
+ this.imageUploader = this.spec.imageUploader;
95
98
  },
96
99
  uploadImage: function(file, editor, cursorLocation) {
97
100
  let vm = this;
98
- const uploaderSpec = this.spec.imageUploader;
101
+ const uploaderSpec = this.imageUploader;
99
102
  // const input = this.$refs.directUploadFile
100
103
  const upload = new Uploader(
101
104
  file,
File without changes
File without changes
package/components/hr.vue CHANGED
File without changes
File without changes
@@ -34,9 +34,9 @@ export default {
34
34
  }
35
35
  // Set all links to be openWeb or open in a new tab by default
36
36
  if (!this.spec.openWeb) {
37
- let anchors = document.querySelectorAll('a');
37
+ let anchors = document.querySelectorAll("a");
38
38
  for (let i = 0; i < anchors.length; i++) {
39
- anchors[i].setAttribute('target', '_blank')
39
+ anchors[i].setAttribute("target", "_blank");
40
40
  }
41
41
  }
42
42
  },
@@ -56,4 +56,10 @@ export default {
56
56
  };
57
57
  </script>
58
58
 
59
- <style scoped></style>
59
+ <style lang="scss">
60
+ .views-markdown {
61
+ & > span > :last-child {
62
+ margin-bottom: 0;
63
+ }
64
+ }
65
+ </style>
File without changes
File without changes
@@ -1,5 +1,6 @@
1
1
  import Hash from "../../utils/hash";
2
2
  import Vue from "vue";
3
+ import launch from "../../utils/launch";
3
4
 
4
5
  var jsonLogic = require("json-logic-js");
5
6
 
@@ -46,19 +47,7 @@ export default {
46
47
  this.$internalizeValue(val)
47
48
  );
48
49
 
49
- const dirtyCheckEnabled = !this.spec.disableDirtyCheck;
50
- // Make sure value has changed and make sure that it is different from the original value.
51
- // Be strict with this so it doesn't execute when the component is just initializing (e.g value changing
52
- // from `null` to `this.spec.value`).
53
- if (
54
- dirtyCheckEnabled &&
55
- !window.vueApp.isFormDirty &&
56
- val != oldVal &&
57
- val != this.spec.value
58
- ) {
59
- console.log("Form is now dirty");
60
- window.vueApp.isFormDirty = true;
61
- }
50
+ this._checkDirtyState(val, oldVal);
62
51
  }
63
52
  },
64
53
  methods: {
@@ -66,6 +55,26 @@ export default {
66
55
  genericStyles(spec) {
67
56
  return this.$styles(spec);
68
57
  },
58
+ _checkDirtyState(val, oldVal) {
59
+ const dirtyCheckEnabled = !this.spec.disableDirtyCheck;
60
+ // Make sure value has changed and make sure that it is different from the original value.
61
+ // Be strict with this so it doesn't execute when the component is just initializing (e.g value changing
62
+ // from `null` to `this.spec.value`).
63
+ if (dirtyCheckEnabled && val != oldVal && val != this.spec.value) {
64
+ const topDialog = Utils.launch.dialog.topDialog();
65
+ if (topDialog) {
66
+ if (!topDialog.isFormDirty) {
67
+ console.log("Dialog form is now dirty");
68
+ topDialog.isFormDirty = true;
69
+ }
70
+ } else {
71
+ if (!window.vueApp.isFormDirty) {
72
+ console.log("Window form is now dirty");
73
+ window.vueApp.isFormDirty = true;
74
+ }
75
+ }
76
+ }
77
+ },
69
78
  // NOTE: Styles are dynamic, do not save it in $ready().
70
79
  $styles(spec) {
71
80
  const properties = spec || this.spec;
File without changes
File without changes
package/components/p.vue CHANGED
File without changes
@@ -7,7 +7,7 @@
7
7
  :show-arrows-on-hover="$classes().includes('show-arrows-on-hover')"
8
8
  >
9
9
  <v-carousel-item v-for="(item, i) in spec.childViews" :key="i">
10
- <ui-component :spec="item" />
10
+ <glib-component :spec="item" />
11
11
  </v-carousel-item>
12
12
  </v-carousel>
13
13
  </template>
@@ -6,7 +6,7 @@
6
6
  remaining space on the new line.
7
7
  -->
8
8
  <div :key="index" :style="innerStyles">
9
- <ui-component :spec="item" />
9
+ <glib-component :spec="item" />
10
10
  </div>
11
11
  </template>
12
12
  </div>
@@ -2,7 +2,7 @@
2
2
  <div :class="$classes()" :style="cssStyles">
3
3
  <template v-for="(item, index) in spec.childViews">
4
4
  <div :key="index">
5
- <ui-component :spec="item" />
5
+ <glib-component :spec="item" />
6
6
  </div>
7
7
  </template>
8
8
  </div>
@@ -7,7 +7,7 @@
7
7
  @click="$onClick()"
8
8
  >
9
9
  <template v-for="(item, index) in spec.childViews">
10
- <ui-component :key="index" :spec="item" />
10
+ <glib-component :key="index" :spec="item" />
11
11
  </template>
12
12
  </component>
13
13
  </template>
@@ -127,7 +127,8 @@ export default {
127
127
  fieldCheckName: `${prefix}[checked]`,
128
128
  fieldTitleName: this.spec.fieldTitleName
129
129
  ? `${prefix}[${this.spec.fieldTitleName}]`
130
- : null
130
+ : null,
131
+ fieldCheckValueIf: this.spec.fieldCheckValueIf
131
132
  });
132
133
  }
133
134
  return row;
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div :class="cssClasses" :style="cssStyles">
3
3
  <!-- <template v-for="(item, index) in spec.childViews">
4
- <ui-component :key="`${index}_${item.view}`" :spec="item" />
4
+ <glib-component :key="`${index}_${item.view}`" :spec="item" />
5
5
  </template> -->
6
6
  <panels-responsive :spec="spec" />
7
7
  </div>
@@ -8,7 +8,7 @@
8
8
  <panels-responsive v-if="spec.center" :spec="spec.center" />
9
9
  </div>
10
10
 
11
- <!-- <ui-component :spec="spec.centerView" v-if="spec.centerView" class="panels-split__expand"/>
11
+ <!-- <glib-component :spec="spec.centerView" v-if="spec.centerView" class="panels-split__expand"/>
12
12
  <div class="panels-split__expand" v-else></div> -->
13
13
 
14
14
  <div v-if="spec.right" class="layouts-split__side layouts-split__right">
@@ -65,7 +65,7 @@
65
65
  v-else
66
66
  :key="index"
67
67
  >
68
- <ui-component :spec="cell" />
68
+ <glib-component :spec="cell" />
69
69
  </th>
70
70
  </tr>
71
71
  </thead>
@@ -84,9 +84,9 @@
84
84
  :style="colStyles(row, cellIndex)"
85
85
  >
86
86
  <!-- Prevent double links -->
87
- <ui-component v-if="$href(cell)" :spec="cell" />
87
+ <glib-component v-if="$href(cell)" :spec="cell" />
88
88
  <a v-else :href="$href(row)" @click="$onClick($event, row)">
89
- <ui-component :spec="cell" />
89
+ <glib-component :spec="cell" />
90
90
  </a>
91
91
  </td>
92
92
  </tr>
@@ -2,7 +2,7 @@
2
2
  <ul :style="$styles()" :class="$classes()">
3
3
  <!-- Use view name for key to avoid component reuse issue -->
4
4
  <li v-for="(item, index) in spec.childViews" :key="`${index}_${item.view}`">
5
- <ui-component :spec="item" />
5
+ <glib-component :spec="item" />
6
6
  </li>
7
7
  </ul>
8
8
  </template>
@@ -8,7 +8,7 @@
8
8
  >
9
9
  <template v-for="(item, index) in spec.childViews">
10
10
  <!-- Use view name for key to avoid component reuse issue -->
11
- <ui-component :key="`${index}_${item.view}`" :spec="item" />
11
+ <glib-component :key="`${index}_${item.view}`" :spec="item" />
12
12
  </template>
13
13
  </component>
14
14
  </template>
@@ -115,7 +115,7 @@ export default {
115
115
  };
116
116
  </script>
117
117
 
118
- <style scoped>
118
+ <style lang="scss" scoped>
119
119
  a[class^="share-network-"] {
120
120
  flex: none;
121
121
  color: #ffffff;
@@ -127,8 +127,10 @@ a[class^="share-network-"] {
127
127
  align-content: center;
128
128
  align-items: center;
129
129
  cursor: pointer;
130
- margin: 0 10px 10px 0;
131
130
  text-decoration: none;
131
+
132
+ // Avoid hardcoding styling
133
+ // margin: 0 10px 10px 0;
132
134
  }
133
135
 
134
136
  a[class^="share-network-"] .fah {
package/index.js CHANGED
@@ -67,9 +67,6 @@ Vue.component("common-dropdownMenu", CommonDropdownMenu);
67
67
  Vue.component("common-responsive", CommonResponsive);
68
68
  Vue.component("templates-menu", CommonTemplateMenu);
69
69
 
70
- // TODO: Deprecate
71
- Vue.component("ui-component", Component);
72
-
73
70
  Vue.component("glib-component", Component);
74
71
  Vue.component("glib-icon", CommonIcon);
75
72
  Vue.component("glib-panels-responsive", ResponsivePanel);
package/keys.js CHANGED
File without changes
package/nav/dialog.vue CHANGED
@@ -61,7 +61,9 @@ export default {
61
61
  model: null,
62
62
  url: null,
63
63
  urlLoaded: false,
64
- showClose: false
64
+ showClose: false,
65
+ isFormDirty: false,
66
+ isFormSubmitted: false
65
67
  };
66
68
  },
67
69
  watch: {
@@ -77,14 +79,15 @@ export default {
77
79
 
78
80
  this.show(false);
79
81
  this.stack.push(this);
80
- console.log("DIALOG READY1", this.stack.length);
81
82
  },
82
83
  $tearDown() {
83
84
  console.log("Dialog destroyed");
84
85
  this.stack.remove(this);
85
86
  },
86
87
  close() {
87
- this.model = false;
88
+ if (Utils.http.proceedEvenWhenDirty()) {
89
+ this.model = false;
90
+ }
88
91
  },
89
92
  click(spec, event) {
90
93
  const onClick = spec["onClick"];
@@ -92,9 +95,11 @@ export default {
92
95
  Action.execute(onClick, this);
93
96
  },
94
97
  reload(newSpec) {
95
- this.spec = newSpec;
96
- this.urlLoaded = false;
97
- this.show(true);
98
+ if (Utils.http.proceedEvenWhenDirty()) {
99
+ this.spec = newSpec;
100
+ this.urlLoaded = false;
101
+ this.show(true);
102
+ }
98
103
  },
99
104
  show(reload) {
100
105
  const spec = this.spec;
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
File without changes
package/styles/test.sass CHANGED
File without changes
package/styles/test.scss CHANGED
File without changes
@@ -23,11 +23,13 @@
23
23
  >
24
24
  <v-icon v-if="spec.onReorder" class="handle">drag_indicator</v-icon>
25
25
 
26
- <v-checkbox
26
+ <!-- <v-checkbox
27
27
  v-if="spec.fieldCheckName"
28
28
  :name="spec.fieldCheckName"
29
29
  :value="true"
30
- ></v-checkbox>
30
+ ></v-checkbox> -->
31
+
32
+ <fields-check v-if="checkSpec" :spec="checkSpec" />
31
33
 
32
34
  <div v-if="spec.leftButtons" class="left-universal">
33
35
  <template v-for="(item, index) in spec.leftButtons">
@@ -96,7 +98,12 @@
96
98
  </template>
97
99
 
98
100
  <script>
101
+ import CheckField from "../components/fields/check";
102
+
99
103
  export default {
104
+ components: {
105
+ "fields-check": CheckField
106
+ },
100
107
  props: {
101
108
  spec: { type: Object, required: true },
102
109
  responsiveCols: { type: Number, default: () => 0 }
@@ -104,7 +111,8 @@ export default {
104
111
  data() {
105
112
  return {
106
113
  accessory: {},
107
- editButtons: []
114
+ editButtons: [],
115
+ checkSpec: null
108
116
  // chips: []
109
117
  };
110
118
  },
@@ -135,6 +143,15 @@ export default {
135
143
  $ready() {
136
144
  this.accessory = { childViews: this.spec.accessoryViews };
137
145
  this.editButtons = this.spec.editButtons || [];
146
+
147
+ if (this.spec.fieldCheckName) {
148
+ this.checkSpec = {
149
+ view: "fields/checkGroup",
150
+ name: this.spec.fieldCheckName,
151
+ checkValue: true,
152
+ valueIf: this.spec.fieldCheckValueIf
153
+ };
154
+ }
138
155
  },
139
156
  buttonSpec(item) {
140
157
  return Object.assign({}, item, {
File without changes
package/utils/dom.js CHANGED
File without changes
package/utils/form.js CHANGED
@@ -6,6 +6,8 @@ export default class {
6
6
  static submitData(form, component) {
7
7
  // Analogous to Rails' form_with's `local: true`
8
8
  if (form.dataset.local) {
9
+ // Prevent onUnload dirty prompt.
10
+ Utils.http.clearDirtyState();
9
11
  form.submit();
10
12
  } else {
11
13
  const url = form.getAttribute("action");
@@ -15,6 +17,7 @@ export default class {
15
17
  const data = {
16
18
  url: Utils.url.appendParams(url, formData)
17
19
  };
20
+ Utils.http.notifyFormSubmitted();
18
21
  Utils.http.load(data, component);
19
22
  } else {
20
23
  const data = {
package/utils/http.js CHANGED
@@ -206,32 +206,44 @@ export default class {
206
206
 
207
207
  // See generic.js
208
208
  static forceComponentUpdate(handler) {
209
+ const dirtyContext = this.dirtyContext();
210
+
209
211
  window.vueApp.isStale = true;
210
212
 
211
213
  // Queue the execution so the first isStale has time to resets state before handler gets executed
212
214
  setTimeout(() => {
213
- window.vueApp.isFormSubmitted = false;
214
- window.vueApp.isFormDirty = false;
215
+ dirtyContext.isFormSubmitted = false;
216
+ dirtyContext.isFormDirty = false;
215
217
  handler();
216
218
  window.vueApp.isStale = false;
217
219
  }, 0);
218
220
  }
219
221
 
220
222
  static promptIfDirtyOnUnload() {
221
- window.onbeforeunload = function() {
222
- return window.vueApp.isFormDirty ? dirtyPrompt : null;
223
+ window.onbeforeunload = () => {
224
+ return this.dirtyContext().isFormDirty ? dirtyPrompt : null;
223
225
  };
224
226
  }
225
227
 
228
+ static dirtyContext() {
229
+ return Utils.launch.dialog.topDialog() || window.vueApp;
230
+ }
231
+
232
+ static clearDirtyState() {
233
+ this.dirtyContext().isFormDirty = false;
234
+ }
235
+
226
236
  static notifyFormSubmitted() {
227
- window.vueApp.isFormSubmitted = true;
237
+ this.dirtyContext().isFormSubmitted = true;
228
238
  }
229
239
 
240
+ // `context` can be either window or dialog.
230
241
  static proceedEvenWhenDirty() {
242
+ const dirtyContext = this.dirtyContext();
231
243
  // Don't prompt if this is a result of form submission
232
244
  if (
233
- window.vueApp.isFormDirty &&
234
- !window.vueApp.isFormSubmitted &&
245
+ dirtyContext.isFormDirty &&
246
+ !dirtyContext.isFormSubmitted &&
235
247
  !confirm(dirtyPrompt)
236
248
  ) {
237
249
  return false;
package/utils/launch.js CHANGED
@@ -19,6 +19,18 @@ export default class {
19
19
  }
20
20
 
21
21
  class LaunchDialog {
22
+ static _initStack() {
23
+ if (!this.stack) {
24
+ this.stack = [];
25
+ }
26
+ }
27
+
28
+ static topDialog() {
29
+ this._initStack();
30
+
31
+ return this.stack.last();
32
+ }
33
+
22
34
  static open(properties, component) {
23
35
  if (!this.stack) {
24
36
  this.stack = [];
package/utils/public.js CHANGED
File without changes
package/utils/settings.js CHANGED
File without changes
package/utils/storage.js CHANGED
File without changes
package/utils/url.js CHANGED
File without changes