glib-web 0.6.16 → 0.7.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/LICENSE +0 -0
- package/actions/auth/restart.js +0 -0
- package/actions/dialogs/oauth.js +0 -0
- package/actions/dialogs/options.js +0 -0
- package/actions/sheets/select.js +0 -0
- package/actions/snackbars/alert.js +0 -0
- package/actions/snackbars/select.js +0 -0
- package/actions/windows/open.js +1 -1
- package/actions/windows/openWeb.js +0 -0
- package/actions/windows/reload.js +0 -15
- package/app.vue +1 -0
- package/components/_message.vue +0 -0
- package/components/avatar.vue +33 -8
- package/components/datetime.vue +0 -0
- package/components/fab.vue +0 -0
- package/components/fields/_select.vue +0 -0
- package/components/fields/country/countries.js +0 -0
- package/components/fields/country/field.vue +0 -0
- package/components/fields/country/regions.js +0 -0
- package/components/fields/datetime.vue +0 -0
- package/components/fields/dynamicSelect.vue +0 -0
- package/components/fields/select.vue +0 -0
- package/components/fields/timeZone.vue +0 -0
- package/components/hr.vue +0 -0
- package/components/html.vue +0 -0
- package/components/image.vue +26 -15
- package/components/mixins/longClick.js +0 -0
- package/components/mixins/scrolling.js +0 -0
- package/components/mixins/styles.js +12 -2
- package/components/mixins/table/export.js +0 -0
- package/components/mixins/table/import.js +0 -1
- package/components/p.vue +0 -0
- package/components/panels/column.vue +0 -0
- package/components/panels/custom.vue +0 -0
- package/components/panels/horizontal.vue +25 -4
- package/components/panels/list.vue +13 -1
- package/components/panels/split.vue +0 -0
- package/components/panels/ul.vue +0 -0
- package/index.js +4 -0
- package/keys.js +0 -0
- package/nav/drawerButton.vue +0 -0
- package/package.json +1 -1
- package/settings.json.example +0 -0
- package/styles/test.sass +0 -0
- package/styles/test.scss +0 -0
- package/templates/comment.vue +41 -21
- package/templates/featured.vue +0 -0
- package/templates/thumbnail.vue +13 -1
- package/templates/unsupported.vue +0 -0
- package/utils/dom.js +0 -0
- package/utils/form.js +3 -2
- package/utils/history.js +9 -0
- package/utils/http.js +32 -1
- package/utils/public.js +0 -0
- package/utils/settings.js +0 -0
- package/utils/storage.js +0 -0
- package/utils/uploader.js +0 -7
- package/utils/url.js +0 -0
package/LICENSE
CHANGED
|
File without changes
|
package/actions/auth/restart.js
CHANGED
|
File without changes
|
package/actions/dialogs/oauth.js
CHANGED
|
File without changes
|
|
File without changes
|
package/actions/sheets/select.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/actions/windows/open.js
CHANGED
|
File without changes
|
|
@@ -1,21 +1,6 @@
|
|
|
1
1
|
export default class {
|
|
2
2
|
execute(properties, component) {
|
|
3
3
|
if (Utils.settings.reactive) {
|
|
4
|
-
// const currentUrl = window.location.href;
|
|
5
|
-
// const data = {
|
|
6
|
-
// url: properties.url || currentUrl
|
|
7
|
-
// };
|
|
8
|
-
|
|
9
|
-
// Utils.http.execute(data, "GET", component, (page, response) => {
|
|
10
|
-
// Utils.http.forceComponentUpdate(() => {
|
|
11
|
-
// window.vueApp.page = page;
|
|
12
|
-
// const redirectUrl = Utils.url.htmlUrl(response.url);
|
|
13
|
-
// Utils.history.updatePage(redirectUrl);
|
|
14
|
-
|
|
15
|
-
// GLib.action.execute(properties["onReload"], null, component);
|
|
16
|
-
// });
|
|
17
|
-
// });
|
|
18
|
-
|
|
19
4
|
Utils.http.reload(properties, component);
|
|
20
5
|
} else {
|
|
21
6
|
window.location.reload();
|
package/app.vue
CHANGED
package/components/_message.vue
CHANGED
|
File without changes
|
package/components/avatar.vue
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
<v-tooltip
|
|
3
|
+
:disabled="tooltip.disabled"
|
|
4
|
+
:top="tooltipPositionMatches('top')"
|
|
5
|
+
:right="tooltipPositionMatches('right')"
|
|
6
|
+
:bottom="tooltipPositionMatches('bottom')"
|
|
7
|
+
:left="tooltipPositionMatches('left')"
|
|
8
|
+
>
|
|
9
|
+
<template v-slot:activator="{ on }">
|
|
10
|
+
<v-avatar
|
|
11
|
+
:style="genericStyles()"
|
|
12
|
+
:class="$classes()"
|
|
13
|
+
:size="spec.size"
|
|
14
|
+
v-on="on"
|
|
15
|
+
>
|
|
16
|
+
<v-img :src="spec.url || spec.base64Data" @click="$onClick()"> </v-img>
|
|
17
|
+
</v-avatar>
|
|
18
|
+
</template>
|
|
19
|
+
<span>{{ tooltip.text }}</span>
|
|
20
|
+
</v-tooltip>
|
|
10
21
|
</template>
|
|
11
22
|
|
|
12
23
|
<script>
|
|
24
|
+
import TooltipMixins from "./mixins/tooltip";
|
|
25
|
+
|
|
13
26
|
export default {
|
|
27
|
+
mixins: [TooltipMixins],
|
|
14
28
|
props: {
|
|
15
29
|
spec: { type: Object, required: true }
|
|
30
|
+
},
|
|
31
|
+
data() {
|
|
32
|
+
return {
|
|
33
|
+
styles: {},
|
|
34
|
+
tooltip: {}
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
methods: {
|
|
38
|
+
$ready() {
|
|
39
|
+
this.tooltip = this.spec.tooltip || { disabled: true };
|
|
40
|
+
}
|
|
16
41
|
}
|
|
17
42
|
};
|
|
18
43
|
</script>
|
package/components/datetime.vue
CHANGED
|
File without changes
|
package/components/fab.vue
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/components/hr.vue
CHANGED
|
File without changes
|
package/components/html.vue
CHANGED
|
File without changes
|
package/components/image.vue
CHANGED
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<v-tooltip
|
|
3
|
+
:disabled="tooltip.disabled"
|
|
4
|
+
:top="tooltipPositionMatches('top')"
|
|
5
|
+
:right="tooltipPositionMatches('right')"
|
|
6
|
+
:bottom="tooltipPositionMatches('bottom')"
|
|
7
|
+
:left="tooltipPositionMatches('left')"
|
|
8
|
+
>
|
|
9
|
+
<template v-slot:activator="{ on }">
|
|
10
|
+
<!-- TODO: Add support for href and :rel="$rel()" -->
|
|
11
|
+
<v-img
|
|
12
|
+
:src="spec.url || spec.base64Data"
|
|
13
|
+
:style="styles"
|
|
14
|
+
v-on="on"
|
|
15
|
+
@click="$onClick()"
|
|
16
|
+
>
|
|
17
|
+
<!-- <v-progress-circular v-if="$isBusy" indeterminate /> -->
|
|
18
|
+
</v-img>
|
|
19
|
+
</template>
|
|
20
|
+
<span>{{ tooltip.text }}</span>
|
|
21
|
+
</v-tooltip>
|
|
6
22
|
</template>
|
|
7
23
|
|
|
8
24
|
<script>
|
|
9
25
|
import Vue from "vue";
|
|
26
|
+
import TooltipMixins from "./mixins/tooltip";
|
|
10
27
|
|
|
11
28
|
export default {
|
|
29
|
+
mixins: [TooltipMixins],
|
|
12
30
|
props: {
|
|
13
31
|
spec: { type: Object, required: true }
|
|
14
32
|
},
|
|
15
33
|
data() {
|
|
16
34
|
return {
|
|
17
|
-
styles: {}
|
|
35
|
+
styles: {},
|
|
36
|
+
tooltip: {}
|
|
18
37
|
};
|
|
19
38
|
},
|
|
20
|
-
// computed: {
|
|
21
|
-
// isOnClickPresent() {
|
|
22
|
-
// return this.spec.hasOwnProperty('onClick')
|
|
23
|
-
// }
|
|
24
|
-
// },
|
|
25
39
|
methods: {
|
|
26
|
-
// styles: function() {
|
|
27
|
-
// // const styles = this.genericStyles(Object.assign({ height: 210 }, this.spec))
|
|
28
|
-
// const styles = this.genericStyles(Object.assign({}, this.spec));
|
|
29
|
-
// return styles;
|
|
30
|
-
// }
|
|
31
40
|
$ready() {
|
|
41
|
+
this.tooltip = this.spec.tooltip || { disabled: true };
|
|
42
|
+
|
|
32
43
|
const styles = this.genericStyles(Object.assign({}, this.spec));
|
|
33
44
|
this.styles = styles;
|
|
34
45
|
|
|
File without changes
|
|
File without changes
|
|
@@ -46,8 +46,18 @@ export default {
|
|
|
46
46
|
this.$internalizeValue(val)
|
|
47
47
|
);
|
|
48
48
|
|
|
49
|
-
//
|
|
50
|
-
//
|
|
49
|
+
// Make sure value has changed and make sure that it is different from the original value.
|
|
50
|
+
// Be strict with this so it doesn't execute when the component is just initializing (e.g value changing
|
|
51
|
+
// from `null` to `this.spec.value`).
|
|
52
|
+
if (
|
|
53
|
+
!window.vueApp.page.disableDirtyPrompt &&
|
|
54
|
+
!window.vueApp.isFormDirty &&
|
|
55
|
+
val != oldVal &&
|
|
56
|
+
val != this.spec.value
|
|
57
|
+
) {
|
|
58
|
+
console.log("Form is now dirty");
|
|
59
|
+
window.vueApp.isFormDirty = true;
|
|
60
|
+
}
|
|
51
61
|
}
|
|
52
62
|
},
|
|
53
63
|
methods: {
|
|
File without changes
|
package/components/p.vue
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -14,13 +14,22 @@ export default {
|
|
|
14
14
|
computed: {
|
|
15
15
|
cssClasses: function() {
|
|
16
16
|
const classes = this.$classes().concat("layouts-horizontal");
|
|
17
|
-
|
|
17
|
+
const distribution = this.spec.distribution;
|
|
18
|
+
switch (distribution) {
|
|
18
19
|
case "fillEqually":
|
|
19
20
|
classes.push("layouts-horizontal--fill-equally");
|
|
20
21
|
break;
|
|
21
22
|
case "spaceEqually":
|
|
22
23
|
classes.push("layouts-horizontal--space-equally");
|
|
23
24
|
break;
|
|
25
|
+
default:
|
|
26
|
+
Utils.type.ifString(distribution, distribution => {
|
|
27
|
+
// Uses Material Design spacings: https://vuetifyjs.com/en/styles/spacing/#how-it-works
|
|
28
|
+
if (distribution.startsWith("overlap")) {
|
|
29
|
+
classes.push(`layouts-horizontal--${distribution}`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
break;
|
|
24
33
|
}
|
|
25
34
|
return classes;
|
|
26
35
|
},
|
|
@@ -67,7 +76,19 @@ export default {
|
|
|
67
76
|
.layouts-horizontal--space-equally > * {
|
|
68
77
|
flex: initial;
|
|
69
78
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
79
|
+
.layouts-horizontal--overlap-1 > *:not(:first-child) {
|
|
80
|
+
margin-left: -4px;
|
|
81
|
+
}
|
|
82
|
+
.layouts-horizontal--overlap-2 > *:not(:first-child) {
|
|
83
|
+
margin-left: -8px;
|
|
84
|
+
}
|
|
85
|
+
.layouts-horizontal--overlap-3 > *:not(:first-child) {
|
|
86
|
+
margin-left: -12px;
|
|
87
|
+
}
|
|
88
|
+
.layouts-horizontal--overlap-4 > *:not(:first-child) {
|
|
89
|
+
margin-left: -16px;
|
|
90
|
+
}
|
|
91
|
+
.layouts-horizontal--overlap-5 > *:not(:first-child) {
|
|
92
|
+
margin-left: -20px;
|
|
93
|
+
}
|
|
73
94
|
</style>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
<component
|
|
30
30
|
:is="template(row)"
|
|
31
|
-
:spec="row"
|
|
31
|
+
:spec="rowSpec(row)"
|
|
32
32
|
:responsive-cols="spec.responsiveCols"
|
|
33
33
|
:index="rowIndex"
|
|
34
34
|
/>
|
|
@@ -113,6 +113,18 @@ export default {
|
|
|
113
113
|
section.rows = section.rows || [];
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
+
rowSpec(row) {
|
|
117
|
+
if (this.spec.fieldPrefix) {
|
|
118
|
+
const prefix = `${this.spec.fieldPrefix}[${row.recordId}]`;
|
|
119
|
+
return Object.assign({}, row, {
|
|
120
|
+
fieldCheckName: `${prefix}[checked]`,
|
|
121
|
+
fieldTitleName: this.spec.fieldTitleName
|
|
122
|
+
? `${prefix}[${this.spec.fieldTitleName}]`
|
|
123
|
+
: null
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return row;
|
|
127
|
+
},
|
|
116
128
|
action_loadNext(spec) {
|
|
117
129
|
console.log("TODO: load new comments and append to this list", spec);
|
|
118
130
|
// TODO
|
|
File without changes
|
package/components/panels/ul.vue
CHANGED
|
File without changes
|
package/index.js
CHANGED
|
@@ -160,6 +160,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
160
160
|
indicator: false,
|
|
161
161
|
// Rename to isPageStale
|
|
162
162
|
isStale: false,
|
|
163
|
+
/// Dirty form handling
|
|
164
|
+
isFormSubmitted: false,
|
|
165
|
+
isFormDirty: false,
|
|
166
|
+
///
|
|
163
167
|
stateUpdatedAt: null,
|
|
164
168
|
webSocket: { channels: {}, header: {} },
|
|
165
169
|
actionCable: { channels: {} },
|
package/keys.js
CHANGED
|
File without changes
|
package/nav/drawerButton.vue
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/settings.json.example
CHANGED
|
File without changes
|
package/styles/test.sass
CHANGED
|
File without changes
|
package/styles/test.scss
CHANGED
|
File without changes
|
package/templates/comment.vue
CHANGED
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
<v-card-title v-if="mode === 'system'" class="caption">{{
|
|
6
6
|
spec.subtitle
|
|
7
7
|
}}</v-card-title>
|
|
8
|
-
<v-avatar
|
|
9
|
-
v-if="spec.imageUrl && mode !== 'outgoing'"
|
|
10
|
-
class="avatar"
|
|
11
|
-
size="30px"
|
|
12
|
-
>
|
|
8
|
+
<v-avatar v-if="spec.imageUrl" class="avatar" size="30px">
|
|
13
9
|
<img :src="spec.imageUrl" alt="avatar" />
|
|
14
10
|
</v-avatar>
|
|
15
11
|
<v-card-title
|
|
@@ -156,47 +152,71 @@ export default {
|
|
|
156
152
|
padding-top: 4px;
|
|
157
153
|
align-self: start;
|
|
158
154
|
}
|
|
155
|
+
|
|
156
|
+
> .avatar {
|
|
157
|
+
grid-row: 1/2;
|
|
158
|
+
grid-column: 1/2;
|
|
159
|
+
padding: 0;
|
|
160
|
+
justify-self: center;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
> .subtitle {
|
|
164
|
+
grid-row: 1/2;
|
|
165
|
+
grid-column: 2/3;
|
|
166
|
+
padding: 0;
|
|
167
|
+
}
|
|
159
168
|
}
|
|
160
|
-
|
|
161
|
-
grid-row: 1/2;
|
|
162
|
-
grid-column: 1/2;
|
|
163
|
-
padding: 0;
|
|
164
|
-
justify-self: center;
|
|
165
|
-
}
|
|
166
|
-
.subtitle {
|
|
167
|
-
grid-row: 1/2;
|
|
168
|
-
grid-column: 2/3;
|
|
169
|
-
padding: 0;
|
|
170
|
-
}
|
|
169
|
+
|
|
171
170
|
.outgoing {
|
|
172
171
|
display: grid;
|
|
173
|
-
grid-template-
|
|
174
|
-
grid-
|
|
172
|
+
grid-template-columns: 36px auto 36px;
|
|
173
|
+
grid-template-rows: 1fr auto 0.5fr;
|
|
174
|
+
grid-column: 4/4;
|
|
175
175
|
|
|
176
176
|
> * {
|
|
177
177
|
justify-self: end;
|
|
178
|
+
grid-column: 2/3;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
> .chips {
|
|
182
|
+
grid-row: 4/4;
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
> .comment-bubble {
|
|
181
186
|
background-color: #0084ff;
|
|
182
187
|
color: #fff;
|
|
183
188
|
border-radius: 10px 10px 0px 10px !important;
|
|
184
|
-
grid-row:
|
|
189
|
+
grid-row: 2/2;
|
|
185
190
|
}
|
|
186
191
|
|
|
187
192
|
> .comment-image {
|
|
188
193
|
max-width: 100%;
|
|
189
194
|
height: 300px;
|
|
190
195
|
border-radius: 10px !important;
|
|
191
|
-
grid-row:
|
|
196
|
+
grid-row: 2/2;
|
|
192
197
|
padding: 0px !important;
|
|
193
198
|
cursor: pointer;
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
> .subsubtitle {
|
|
197
|
-
grid-row:
|
|
202
|
+
grid-row: 3/4;
|
|
198
203
|
padding: 0;
|
|
199
204
|
color: #9e9e9e;
|
|
205
|
+
padding-top: 4px;
|
|
206
|
+
align-self: start;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
> .avatar {
|
|
210
|
+
grid-row: 1/2;
|
|
211
|
+
grid-column: 3/4;
|
|
212
|
+
padding: 0;
|
|
213
|
+
justify-self: end;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
> .subtitle {
|
|
217
|
+
grid-row: 1/2;
|
|
218
|
+
grid-column: 2/3;
|
|
219
|
+
padding: 0;
|
|
200
220
|
}
|
|
201
221
|
}
|
|
202
222
|
</style>
|
package/templates/featured.vue
CHANGED
|
File without changes
|
package/templates/thumbnail.vue
CHANGED
|
@@ -23,6 +23,12 @@
|
|
|
23
23
|
>
|
|
24
24
|
<v-icon v-if="spec.onReorder" class="handle">drag_indicator</v-icon>
|
|
25
25
|
|
|
26
|
+
<v-checkbox
|
|
27
|
+
v-if="spec.fieldCheckName"
|
|
28
|
+
:name="spec.fieldCheckName"
|
|
29
|
+
:value="true"
|
|
30
|
+
></v-checkbox>
|
|
31
|
+
|
|
26
32
|
<div v-if="spec.leftButtons" class="left-universal">
|
|
27
33
|
<template v-for="(item, index) in spec.leftButtons">
|
|
28
34
|
<common-button
|
|
@@ -52,7 +58,13 @@
|
|
|
52
58
|
</div>
|
|
53
59
|
|
|
54
60
|
<v-list-item-content style="display:flex;">
|
|
55
|
-
<v-
|
|
61
|
+
<v-text-field
|
|
62
|
+
v-if="spec.fieldTitleName"
|
|
63
|
+
:name="spec.fieldTitleName"
|
|
64
|
+
:value="spec.title"
|
|
65
|
+
/>
|
|
66
|
+
<v-list-item-title v-else>{{ spec.title }}</v-list-item-title>
|
|
67
|
+
|
|
56
68
|
<v-list-item-subtitle v-if="spec.subtitle">{{
|
|
57
69
|
spec.subtitle
|
|
58
70
|
}}</v-list-item-subtitle>
|
|
File without changes
|
package/utils/dom.js
CHANGED
|
File without changes
|
package/utils/form.js
CHANGED
|
@@ -4,7 +4,7 @@ export default class {
|
|
|
4
4
|
// Button -> Button.onClick() -> form.submit() -- doesn't execute Form.onSubmit(), so cannot call Utils.http.execute() there
|
|
5
5
|
// Submit -> Form.onSubmit() -> Utils.http.execute() -- save autofill values and auto-submit when ENTER is pressed
|
|
6
6
|
static submitData(form, component) {
|
|
7
|
-
// Analogous to Rails' form_with's local
|
|
7
|
+
// Analogous to Rails' form_with's `local: true`
|
|
8
8
|
if (form.dataset.local) {
|
|
9
9
|
form.submit();
|
|
10
10
|
} else {
|
|
@@ -15,13 +15,14 @@ export default class {
|
|
|
15
15
|
const data = {
|
|
16
16
|
url: Utils.url.appendParams(url, formData)
|
|
17
17
|
};
|
|
18
|
-
Utils.http.load(data,
|
|
18
|
+
Utils.http.load(data, component);
|
|
19
19
|
} else {
|
|
20
20
|
const data = {
|
|
21
21
|
url: url,
|
|
22
22
|
formData: formData
|
|
23
23
|
};
|
|
24
24
|
Utils.http.execute(data, method, component, response => {
|
|
25
|
+
Utils.http.notifyFormSubmitted();
|
|
25
26
|
GLib.action.handleResponse(response, component);
|
|
26
27
|
});
|
|
27
28
|
}
|
package/utils/history.js
CHANGED
|
@@ -35,6 +35,15 @@ export default class {
|
|
|
35
35
|
static restoreOnBackOrForward() {
|
|
36
36
|
const vm = this;
|
|
37
37
|
window.onpopstate = event => {
|
|
38
|
+
// TODO: Ideally display a prompt when dirty
|
|
39
|
+
// if (Utils.http.proceedEvenWhenDirty()) {
|
|
40
|
+
// event.preventDefault();
|
|
41
|
+
// history.go(1);
|
|
42
|
+
// return false;
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
window.vueApp.isFormDirty = false;
|
|
46
|
+
|
|
38
47
|
// Save scroll position of the current page when navigating through back/forward button
|
|
39
48
|
this.bodyScrollTops[this.navigationCount] = this._pageBody.scrollTop;
|
|
40
49
|
|
package/utils/http.js
CHANGED
|
@@ -2,6 +2,7 @@ import Type from "./type";
|
|
|
2
2
|
import Action from "../action";
|
|
3
3
|
|
|
4
4
|
let loading = false;
|
|
5
|
+
const dirtyPrompt = "Changes you made have not been saved. Are you sure?";
|
|
5
6
|
|
|
6
7
|
class HttpRequest {
|
|
7
8
|
constructor() {
|
|
@@ -38,9 +39,15 @@ export default class {
|
|
|
38
39
|
return formData;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
static load(properties,
|
|
42
|
+
static load(properties, component) {
|
|
42
43
|
const url = new URL(properties["url"]);
|
|
43
44
|
const domainMatched = window.location.hostname == url.hostname;
|
|
45
|
+
|
|
46
|
+
// If this is an external domain, we rely on `onUnload()` instead.
|
|
47
|
+
if (domainMatched && !this.proceedEvenWhenDirty()) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
44
51
|
if (Utils.settings.reactive && domainMatched) {
|
|
45
52
|
const currentUrl = window.location.href;
|
|
46
53
|
const htmlUrl = Utils.url.htmlUrl(properties["url"]);
|
|
@@ -202,8 +209,32 @@ export default class {
|
|
|
202
209
|
|
|
203
210
|
// Queue the execution so the first isStale has time to resets state before handler gets executed
|
|
204
211
|
setTimeout(() => {
|
|
212
|
+
window.vueApp.isFormSubmitted = false;
|
|
213
|
+
window.vueApp.isFormDirty = false;
|
|
205
214
|
handler();
|
|
206
215
|
window.vueApp.isStale = false;
|
|
207
216
|
}, 0);
|
|
208
217
|
}
|
|
218
|
+
|
|
219
|
+
static promptIfDirtyOnUnload() {
|
|
220
|
+
window.onbeforeunload = function() {
|
|
221
|
+
return window.vueApp.isFormDirty ? dirtyPrompt : null;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static notifyFormSubmitted() {
|
|
226
|
+
window.vueApp.isFormSubmitted = true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
static proceedEvenWhenDirty() {
|
|
230
|
+
// Don't prompt if this is a result of form submission
|
|
231
|
+
if (
|
|
232
|
+
window.vueApp.isFormDirty &&
|
|
233
|
+
!window.vueApp.isFormSubmitted &&
|
|
234
|
+
!confirm(dirtyPrompt)
|
|
235
|
+
) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
209
240
|
}
|
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/uploader.js
CHANGED
|
@@ -5,13 +5,6 @@ import mimeType from "../utils/mime_type";
|
|
|
5
5
|
const MB_SIZE = 1000;
|
|
6
6
|
|
|
7
7
|
export default class Uploader {
|
|
8
|
-
// constructor(input, file, url) {
|
|
9
|
-
// this.input = input
|
|
10
|
-
// this.file = file
|
|
11
|
-
// this.url = url
|
|
12
|
-
// this.upload = new DirectUpload(this.file, this.url, this)
|
|
13
|
-
// }
|
|
14
|
-
|
|
15
8
|
constructor(file, url, progress) {
|
|
16
9
|
this.file = file;
|
|
17
10
|
this.url = url;
|
package/utils/url.js
CHANGED
|
File without changes
|