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.
- package/LICENSE +0 -0
- package/action.js +1 -0
- package/actions/auth/restart.js +0 -0
- package/actions/commands/copy.js +6 -6
- package/actions/dialogs/oauth.js +0 -0
- package/actions/dialogs/options.js +0 -0
- package/actions/windows/openWeb.js +0 -0
- package/components/_message.vue +0 -0
- package/components/_responsive.vue +2 -2
- package/components/datetime.vue +0 -0
- package/components/fab.vue +0 -0
- package/components/fields/check.vue +0 -11
- package/components/fields/checkGroup.vue +56 -14
- 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/location.vue +3 -3
- package/components/fields/richText.vue +7 -4
- 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/markdown.vue +9 -3
- package/components/mixins/longClick.js +0 -0
- package/components/mixins/scrolling.js +0 -0
- package/components/mixins/styles.js +22 -13
- package/components/mixins/table/export.js +0 -0
- package/components/mixins/table/import.js +0 -0
- package/components/p.vue +0 -0
- package/components/panels/carousel.vue +1 -1
- package/components/panels/flow.vue +1 -1
- package/components/panels/grid.vue +1 -1
- package/components/panels/horizontal.vue +1 -1
- package/components/panels/list.vue +2 -1
- package/components/panels/scroll.vue +1 -1
- package/components/panels/split.vue +1 -1
- package/components/panels/table.vue +3 -3
- package/components/panels/ul.vue +1 -1
- package/components/panels/vertical.vue +1 -1
- package/components/shareButton.vue +4 -2
- package/index.js +0 -3
- package/keys.js +0 -0
- package/nav/dialog.vue +11 -6
- 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/thumbnail.vue +20 -3
- package/templates/unsupported.vue +0 -0
- package/utils/dom.js +0 -0
- package/utils/form.js +3 -0
- package/utils/http.js +19 -7
- package/utils/launch.js +12 -0
- package/utils/public.js +0 -0
- package/utils/settings.js +0 -0
- package/utils/storage.js +0 -0
- 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;
|
package/actions/auth/restart.js
CHANGED
|
File without changes
|
package/actions/commands/copy.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export default class {
|
|
2
|
-
execute(properties) {
|
|
3
|
-
let spec = Object.assign({}, properties, {
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
() =>
|
|
8
|
+
() => GLib.action.execute(properties.onCopy, component),
|
|
9
9
|
reason => console.error("Could not copy text: " + reason)
|
|
10
10
|
);
|
|
11
11
|
}
|
package/actions/dialogs/oauth.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/components/_message.vue
CHANGED
|
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
|
-
<
|
|
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
|
-
<
|
|
23
|
+
<glib-component :spec="item" />
|
|
24
24
|
</div>
|
|
25
25
|
</template>
|
|
26
26
|
</v-row>
|
package/components/datetime.vue
CHANGED
|
File without changes
|
package/components/fab.vue
CHANGED
|
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
|
|
3
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
28
|
-
|
|
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
|
|
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
|
-
<
|
|
53
|
+
<glib-component
|
|
54
54
|
v-if="latitudeField"
|
|
55
55
|
ref="latitudeView"
|
|
56
56
|
:spec="latitudeField"
|
|
57
57
|
/>
|
|
58
|
-
<
|
|
58
|
+
<glib-component
|
|
59
59
|
v-if="longitudeField"
|
|
60
60
|
ref="longitudeView"
|
|
61
61
|
:spec="longitudeField"
|
|
62
62
|
/>
|
|
63
|
-
<
|
|
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="
|
|
16
|
-
name="
|
|
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.
|
|
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
|
package/components/html.vue
CHANGED
|
File without changes
|
package/components/markdown.vue
CHANGED
|
@@ -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(
|
|
37
|
+
let anchors = document.querySelectorAll("a");
|
|
38
38
|
for (let i = 0; i < anchors.length; i++) {
|
|
39
|
-
anchors[i].setAttribute(
|
|
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
|
|
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
|
-
|
|
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
|
|
@@ -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
|
-
<
|
|
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
|
-
<!-- <
|
|
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
|
-
<
|
|
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
|
-
<
|
|
87
|
+
<glib-component v-if="$href(cell)" :spec="cell" />
|
|
88
88
|
<a v-else :href="$href(row)" @click="$onClick($event, row)">
|
|
89
|
-
<
|
|
89
|
+
<glib-component :spec="cell" />
|
|
90
90
|
</a>
|
|
91
91
|
</td>
|
|
92
92
|
</tr>
|
package/components/panels/ul.vue
CHANGED
|
@@ -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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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;
|
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/thumbnail.vue
CHANGED
|
@@ -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
|
-
|
|
214
|
-
|
|
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 =
|
|
222
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
234
|
-
!
|
|
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
|