Skip to content

Commit

Permalink
Add cancel buttons to all prompts
Browse files Browse the repository at this point in the history
  • Loading branch information
Fajfa committed Mar 4, 2024
1 parent 27e142c commit 3708ca9
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 118 deletions.
19 changes: 7 additions & 12 deletions lib/vue/src/components/prompts/CPromptModal.vue
Expand Up @@ -6,6 +6,7 @@
:hide-footer="!current"
:title="current ? current.title : 'Workflow prompts'"
:busy="isLoading"
footer-class="d-flex"
no-fade
@hide="deactivate()"
>
Expand All @@ -20,29 +21,22 @@
v-else
>
<div
class="d-flex flex-grow-1 align-items-baseline"
class="d-flex flex-grow-1 align-items-baseline mb-2"
v-for="({ key, title, age, prompt }) in list"
:key="key"
>
<span
class="mr-auto"
<a
class="p-0 mr-auto"
@click="activate(prompt)"
>
{{ title }}
{{ title }} -
<time
class="muted small"
:datetime="prompt.createdAt"
>
{{ age }}
</time>
</span>
<b-button
variant="link"
size="sm"
@click="remove(prompt)"
:disabled="isLoading"
v-if="false"
>Remove</b-button>
</a>
</div>
</div>
<template
Expand All @@ -51,6 +45,7 @@
>
<b-button
variant="link"
class="mr-auto"
@click="activate(true)"
>
&laquo; Back to list
Expand Down
96 changes: 65 additions & 31 deletions lib/vue/src/components/prompts/CPromptToast.vue
@@ -1,5 +1,5 @@
<template>
<div>
<div v-if="!hideToasts">
<b-toast
v-for="({ prompt, component, passive }) in toasts"
:id="'wfPromptToast-'+prompt.stateID"
Expand All @@ -9,21 +9,12 @@
solid
:no-auto-hide="!passive"
:auto-hide-delay="pVal(prompt, 'timeout', defaultTimeout) * 1000"
:no-close-button="!passive"
@hide="onToastHide({ prompt, passive })"
>
<template #toast-title>
<div class="d-flex flex-grow-1 align-items-baseline">
<strong class="mr-auto">{{ pVal(prompt, 'title', 'Workflow prompt') }}</strong>
<b-button
variant="link"
size="sm"
v-if="!passive && active.length > 1"
@click="activate(true)"
>
{{ active.length }} waiting
</b-button>
</div>
<strong>{{ pVal(prompt, 'title', 'Workflow prompt') }}</strong>
</template>

<component
v-if="component"
:is="component"
Expand Down Expand Up @@ -52,12 +43,6 @@ export default {
return {
passive: new Set(),
/**
* Set initial value to NULL
*
* First interval will detect that null is not true|false
* and set it accordingly to the current state
*/
hasFocus: null,
hasFocusObserver: 0,
}
Expand Down Expand Up @@ -163,6 +148,7 @@ export default {
methods: {
...mapActions({
resume: 'wfPrompts/resume',
cancel: 'wfPrompts/cancel',
activate: 'wfPrompts/activate',
}),
Expand All @@ -175,6 +161,12 @@ export default {
this.resume(values)
},
onToastHide ({ prompt, passive}) {
if (passive) return
this.cancel(prompt)
},
pVal (prompt, k, def = undefined) {
return pVal(prompt.payload, k, def)
},
Expand All @@ -200,24 +192,66 @@ export default {
},
setDefaultValues () {
this.passive.clear()
this.toasts = []
this.hasFocus = null
this.hasFocusObserver = 0
},
},
}
</script>

<style scoped lang="scss">
.slide-enter-active {
transition: all .3s ease;
}
.slide-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
<style lang="scss">
.toast-header {
align-items: start;
padding: 0.375rem 0.75rem;
strong {
word-break: break-word;
}
.close {
margin-bottom: 0 !important;
}
}
.slide-enter, .slide-leave-to
/* .slide-leave-active below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
// .b-toaster-leave-active {
// width: 100%;
// }
.b-toaster {
&.b-toaster-top-right,
&.b-toaster-top-left,
&.b-toaster-bottom-right,
&.b-toaster-bottom-left {
.b-toast {
&.b-toaster-enter-active,
&.b-toaster-leave-active,
&.b-toaster-move {
transition: transform 0.3s ease-in-out; /* Adjust the timing function for smoother transitions */
opacity: 1; /* Ensure opacity is set to avoid flickering during transition */
}
&.b-toaster-enter {
transform: translate(0, -100%); /* Start off-screen when entering */
opacity: 0; /* Start with 0 opacity */
}
&.b-toaster-enter-to,
&.b-toaster-enter-active {
transform: translate(0, 0); /* Move to the visible position */
opacity: 1; /* Fade in during the transition */
}
&.b-toaster-leave-active {
position: absolute;
transform: translate(0, -100%); /* Move off-screen when leaving */
opacity: 0; /* Fade out during the transition */
}
&.b-toaster-leave-to {
opacity: 0; /* Ensure 0 opacity at the end of the transition */
}
}
}
}
</style>
</style>
7 changes: 3 additions & 4 deletions lib/vue/src/components/prompts/kinds/CPromptAlert.vue
@@ -1,9 +1,8 @@
<template>
<div>
<p v-html="message"></p>
<div
class="text-center m-2"
>
<p v-if="!!message" v-html="message" />

<div class="d-flex justify-content-end gap-1">
<b-button
@click="$emit('submit', { confirmed: pRaw('buttonValue', true, 'Boolean') })"
:variant="pVal('buttonVariant', 'primary')"
Expand Down
10 changes: 5 additions & 5 deletions lib/vue/src/components/prompts/kinds/CPromptChoice.vue
@@ -1,20 +1,20 @@
<template>
<div>
<p v-html="message"></p>
<div
class="text-center m-2"
>
<p v-if="!!message" v-html="message" />

<div class="d-flex align-items-between justify-content-center gap-2">
<b-button
@click="$emit('submit', { value: pRaw('confirmButtonValue', true, 'Boolean') })"
:variant="pVal('confirmButtonVariant', 'primary')"
:disabled="loading"
>
{{ pVal('confirmButtonLabel', 'Yes') }}
</b-button>

<b-button
@click="$emit('submit', { value: pRaw('rejectButtonValue', false, 'Boolean') })"
:disabled="loading"
:variant="pVal('rejectButtonVariant', 'primary')"
:variant="pVal('rejectButtonVariant', 'light')"
>
{{ pVal('rejectButtonLabel', 'No') }}
</b-button>
Expand Down
81 changes: 18 additions & 63 deletions lib/vue/src/components/prompts/kinds/CPromptComposeRecordPicker.vue
@@ -1,22 +1,19 @@
<template>
<div>
<p>
{{ message }}
</p>
<div
class="text-center m-2"
>
<p v-if="!!message" v-html="message" />

<div class="d-flex flex-column gap-1">
<c-input-select
v-model="value"
:options="options"
:get-option-key="getOptionKey"
:loading="processing"
append-to-body
:calculate-position="calculateDropdownPosition"
option-value="recordID"
option-text="label"
placeholder="Select record"
:filterable="false"
:reduce="r => r.recordID"
class="w-100 mb-3"
@search="search"
>
Expand All @@ -31,8 +28,10 @@
</c-input-select>

<b-button
@click="$emit('submit', { value: encodeValue() })"
:disabled="loading"
variant="primary"
class="ml-auto"
@click="$emit('submit', { value: encodeValue() })"
>
{{ pVal('buttonLabel', 'Submit') }}
</b-button>
Expand All @@ -45,7 +44,6 @@ import CPagination from '../common/CPagination.vue'
import { pVal } from '../utils.ts'
import CInputSelect from '../../input/CInputSelect.vue'
import { compose, NoID } from '@cortezaproject/corteza-js'
import { createPopper } from '@popperjs/core'
import { debounce } from 'lodash'
export default {
Expand Down Expand Up @@ -79,12 +77,8 @@ export default {
},
computed: {
// moduleFields returns the available field names
moduleFields () {
if (!this.module) {
return []
}
return this.module.fields.map(({ name }) => name)
labelField () {
return this.module.fields.find(f => f.name === this.pVal('labelField'))
},
showPagination () {
Expand Down Expand Up @@ -165,7 +159,9 @@ export default {
return { '@type': 'Any', '@value': null }
}
return { '@type': 'ComposeRecord', '@value': this.value.record }
const record = this.options.find(({ recordID }) => recordID === this.value)
return { '@type': 'ComposeRecord', '@value': record }
},
loadLatest () {
Expand Down Expand Up @@ -206,51 +202,6 @@ export default {
}
}, 300),
calculateDropdownPosition (dropdownList, component, { width }) {
/**
* We need to explicitly define the dropdown width since
* it is usually inherited from the parent with CSS.
*/
dropdownList.style.width = width
dropdownList.style['z-index'] = 10000
/**
* Here we position the dropdownList relative to the $refs.toggle Element.
*
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
* the dropdownList overlap by 1 pixel.
*
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
* wrapper so that we can set some styles for when the dropdown is placed
* above.
*/
const popper = createPopper(component.$refs.toggle, dropdownList, {
placement: 'bottom',
modifiers: [
{
name: 'offset',
options: {
offset: [0, -1],
},
},
{
name: 'toggleClass',
enabled: true,
phase: 'write',
fn ({ state }) {
component.$el.classList.toggle('drop-up', state.placement === 'top')
},
}],
})
/**
* To prevent memory leaks Popper needs to be destroyed.
* If you return function, it will be called just before dropdown is removed from DOM.
*/
return () => popper.destroy()
},
fetchPrefiltered (q) {
this.processing = true
Expand All @@ -273,11 +224,15 @@ export default {
this.options = set.map(r => {
const record = new compose.Record(this.module, r)
const label = record.values[this.pVal('labelField')] || record.recordID
let label
if (this.labelField) {
label = this.labelField.isMulti ? record.values[this.pVal('labelField')].join(', ') : record.values[this.pVal('labelField')]
}
return {
recordID: record.recordID,
label,
label: label || record.recordID,
record,
}
})
Expand Down
4 changes: 3 additions & 1 deletion lib/vue/src/components/prompts/kinds/CPromptInput.vue
@@ -1,6 +1,7 @@
<template>
<div>
<p v-html="message"></p>
<p v-if="!!message" v-html="message" />

<b-form-group
:label="label"
label-class="text-primary"
Expand All @@ -13,6 +14,7 @@
</b-form-group>
<b-button
:disabled="loading"
variant="primary"
@click="$emit('submit', { value: { '@value': value, '@type': 'String' }})"
>
{{ pVal('buttonLabel', 'Submit') }}
Expand Down

0 comments on commit 3708ca9

Please sign in to comment.