Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/four 10472 option to make the interstitial a loading button #1437

Merged
merged 9 commits into from
Sep 29, 2023
2 changes: 2 additions & 0 deletions src/components/inspector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export { default as ImageVariable } from './image-variable.vue';
export { default as InputVariable } from './input-variable.vue';
export { default as Tooltip } from './tooltip';
export { default as DeviceVisibility } from './device-visibility';
export { default as LoadingSubmitButton } from './loading-submit-button';
export { default as LabelSubmitButton } from './label-submit-button';
44 changes: 44 additions & 0 deletions src/components/inspector/label-submit-button.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<div v-if="event === 'submit'" style="padding-top: 0px !important;">
<div>
<form-input
v-model="loadingLabel"
type="text"
class="mb-3"
:label="$t('Loading Label')"
/>
</div>
</div>
</template>

<script>
export default {
props: ['value', 'selectedControl'],
data() {
return {
event: "",
loadingLabel: null
};
},
computed: {
mode() {
return this.$root.$children[0].mode;
},
},
watch: {
loadingLabel() {
this.$emit('input', this.loadingLabel);
},
value() {
this.loadingLabel = this.value;
},
"selectedControl.config.event": function (newVal) {
this.event = newVal;
}
},
mounted() {
this.event = this.selectedControl.config.event;
this.loadingLabel = this.value;
}
};
</script>
44 changes: 44 additions & 0 deletions src/components/inspector/loading-submit-button.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<div v-if="event === 'submit'" style="border-style: none !important;">
<div>
<form-checkbox
:label="$t('Loading Submit Button')"
v-model="loading"
:toggle="false"
:helper="$t('Loading Submit Button')"
/>
</div>
</div>
</template>

<script>
export default {
props: ['value', 'selectedControl'],
data() {
return {
event: "",
loading: null
};
},
computed: {
mode() {
return this.$root.$children[0].mode;
},
},
watch: {
loading() {
this.$emit('input', this.loading);
},
value() {
this.loading = this.value;
},
"selectedControl.config.event": function (newVal) {
this.event = newVal;
}
},
mounted() {
this.event = this.selectedControl.config.event;
this.loading = this.value;
}
};
</script>
30 changes: 23 additions & 7 deletions src/components/renderer/form-button.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
<template>
<div class="form-group" style="overflow-x: hidden">
<button v-b-tooltip="options" @click="click" :class="classList" :name="name" :aria-label="$attrs['aria-label']" :tabindex="$attrs['tabindex']">
{{ label }}
<div class="form-group" style="overflow-x: hidden">
<button
v-b-tooltip="options"
@click="click"
:class="classList"
:name="name"
:aria-label="$attrs['aria-label']"
:tabindex="$attrs['tabindex']"
:disabled="showSpinner"
>
<b-spinner v-if="showSpinner" small></b-spinner>
{{ showSpinner ? (!loadingLabel ? 'Loading...': loadingLabel) : label }}
</button>
</div>
</template>
Expand All @@ -11,10 +20,14 @@ import Mustache from 'mustache';
import { mapActions, mapState } from "vuex";
import { getValidPath } from '@/mixins';


export default {
mixins: [getValidPath],
props: ['variant', 'label', 'event', 'eventData', 'name', 'fieldValue', 'value', 'tooltip', 'transientData'],
props: ['variant', 'label', 'event', 'eventData', 'name', 'fieldValue', 'value', 'tooltip', 'transientData', 'loading', 'loadingLabel'],
data() {
return {
showSpinner: false
};
},
computed: {
...mapState('globalErrorsModule', ['valid']),
classList() {
Expand Down Expand Up @@ -65,9 +78,12 @@ export default {
this.setValue(this.$parent, this.name, this.fieldValue);
}
if (this.event === 'submit') {
if (this.loading) {
this.showSpinner = true;
}
this.$emit('input', this.fieldValue);
this.$nextTick(()=>{
this.$emit('submit', this.eventData);
this.$nextTick(() => {
this.$emit('submit', this.eventData, this.loading);
});
return;
}
Expand Down
38 changes: 27 additions & 11 deletions src/components/task.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export default {
csrfToken: { type: String, default: null },
value: { type: Object, default: () => {} },
beforeLoadTask: { type: Function, default: defaultBeforeLoadTask },
initialLoopContext: { type: String, default: "" }
initialLoopContext: { type: String, default: "" },
loading: { type: Number, default: null }
},
data() {
return {
Expand All @@ -98,6 +99,7 @@ export default {
hasErrors: false,
refreshScreen: 0,
redirecting: null,
loadingButton: false
};
},
watch: {
Expand Down Expand Up @@ -263,10 +265,15 @@ export default {
});
},
prepareTask() {
this.resetScreenState();
this.requestData = _.get(this.task, 'request_data', {});
this.loopContext = _.get(this.task, "loop_context", "");
this.refreshScreen++;
// If the immediate task status is completed and we are waiting with a loading button,
// do not reset the screen because that would stop displaying the loading spinner
// before the next task is ready.
if (!this.loadingButton || this.task.status === 'ACTIVE') {
this.resetScreenState();
this.requestData = _.get(this.task, 'request_data', {});
this.loopContext = _.get(this.task, "loop_context", "");
this.refreshScreen++;
}

this.$emit('task-updated', this.task);

Expand All @@ -278,6 +285,8 @@ export default {
}
},
resetScreenState() {
this.loadingButton = false;
this.disabled = false;
if (this.$refs.renderer && this.$refs.renderer.$children[0]) {
this.$refs.renderer.$children[0].currentPage = 0;
}
Expand All @@ -303,6 +312,9 @@ export default {
if (this.task.process_request.status === 'COMPLETED') {
this.loadNextAssignedTask(parentRequestId);

} else if (this.loadingButton) {
this.loadNextAssignedTask(parentRequestId);

} else if (this.task.allow_interstitial) {
this.task.interstitial_screen['_interstitial'] = true;
this.screen = this.task.interstitial_screen;
Expand Down Expand Up @@ -362,7 +374,7 @@ export default {
}
return 'card-header text-capitalize text-white ' + header;
},
submit(formData = null) {
submit(formData = null, loading = false) {
//single click
if (this.disabled) {
return;
Expand All @@ -372,12 +384,15 @@ export default {
if (formData) {
this.onUpdate(Object.assign({}, this.requestData, formData));
}
this.$emit('submit', this.task);
this.$nextTick(() => {
this.disabled = false;
});

if (this.task && this.task.allow_interstitial) {
if (loading) {
this.loadingButton = true;
} else {
this.loadingButton = false;
}
this.$emit('submit', this.task, loading);

if (this.task && this.task.allow_interstitial && !this.loadingButton) {
this.task.interstitial_screen['_interstitial'] = true;
this.screen = this.task.interstitial_screen;
}
Expand Down Expand Up @@ -500,6 +515,7 @@ export default {
requestIdNode.setAttribute('content', this.requestId);
}
},

},
mounted() {
this.screenId = this.initialScreenId;
Expand Down
4 changes: 2 additions & 2 deletions src/components/vue-form-renderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ export default {
node.$children.forEach(child => this.registerCustomFunctions(child));
}
},
submit() {
this.$emit('submit', this.data);
submit(eventData, loading = false) {
this.$emit('submit', this.data, loading);
},
parseCss() {
const containerSelector = `.${this.containerClass}`;
Expand Down
8 changes: 7 additions & 1 deletion src/form-builder-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import {
defaultValueProperty,
buttonTypeEvent,
tooltipProperty,
LoadingSubmitButtonProperty,
LabelSubmitButtonProperty
} from './form-control-common-properties';

export default [
Expand Down Expand Up @@ -559,6 +561,8 @@ export default [
label: 'New Submit',
variant: 'primary',
event: 'submit',
loading: false,
loadingLabel: 'Loading...',
defaultSubmit: true,
name: null,
fieldValue: null,
Expand All @@ -582,9 +586,11 @@ export default [
helper: 'A variable name is a symbolic name to reference information.',
validation: 'regex:/^(?:[A-Za-z])(?:[0-9A-Z_.a-z])*(?<![.])$/|not_in:' + javascriptReservedKeywords,

},
},
},
buttonTypeEvent,
LoadingSubmitButtonProperty,
LabelSubmitButtonProperty,
tooltipProperty,
{
type: 'FormInput',
Expand Down
18 changes: 18 additions & 0 deletions src/form-control-common-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,21 @@ export const deviceVisibilityProperty = {
label: 'Device Visibility ',
},
};

export const LoadingSubmitButtonProperty = {
type: 'LoadingSubmitButton',
field: 'loading',
config: {
label: 'Loading Submit Button',
helper: 'Loading Submit Button',
},
};

export const LabelSubmitButtonProperty = {
type: 'LabelSubmitButton',
field: 'loadingLabel',
config: {
label: 'Loading Submit Button Label',
helper: 'Loading Submit Button Label',
},
};
4 changes: 2 additions & 2 deletions src/mixins/Json2Vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ export default {
dot2bracket(str) {
return str.replace(/\.\d/g, match => `[${match.substr(1)}]`);
},
submit() {
this.$emit('submit', this.value);
submit(eventData, loading = false) {
this.$emit('submit', this.value, loading);
},
buildComponent(definition) {
if (window.ProcessMaker && window.ProcessMaker.EventBus) {
Expand Down
4 changes: 2 additions & 2 deletions src/mixins/ScreenBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export default {
return 'MUSTACHE: ' + e.message;
}
},
async submitForm() {
async submitForm(eventData, loading = false) {
await this.validateNow(findRootScreen(this));
this.hasSubmitted(true);
if (!this.valid__ || this.disableSubmit__) {
Expand All @@ -155,7 +155,7 @@ export default {
// if the form is not valid the data is not emitted
return;
}
this.$emit('submit', this.vdata);
this.$emit('submit', this.vdata, loading);
},
resetValue(safeDotName, variableName) {
this.setValue(safeDotName, null);
Expand Down
Loading