3
0

Add options for opening links in newTab or modals on WF prompts

This commit is contained in:
Mumbi Francis 2024-03-06 18:26:18 +03:00 committed by Mumbi Francis
parent eb9cce2428
commit dd98df564c
6 changed files with 66 additions and 25 deletions

View File

@ -148,7 +148,7 @@ export default (options = {}) => {
break
case 'error':
console.error('websocket message with error', msg['@value'])
this.toastDanger('Websocket message with error', msg['@value'])
}
})
},

View File

@ -154,7 +154,7 @@ export default (options = {}) => {
break
case 'error':
console.error('websocket message with error', msg['@value'])
this.toastDanger('Websocket message with error', msg['@value'])
}
})
},

View File

@ -96,7 +96,7 @@ export default (options = {}) => {
break
case 'error':
console.error('websocket message with error', msg['@value'])
this.toastDanger('Websocket message with error', msg['@value'])
}
})
},

View File

@ -132,7 +132,7 @@
@input="$root.$emit('change-detected')"
@search="searchWorkflows"
/>
<!-- Clearable -->
<c-input-select
v-else-if="a.input.type === 'select'"
v-model="a.value"
@ -142,6 +142,7 @@
:filter="varFilter"
:reduce="a => a.value"
:placeholder="$t('steps:function.configurator.option-select')"
:clearable="false"
@input="$root.$emit('change-detected')"
/>
@ -520,7 +521,7 @@ export default {
target: param.name,
type: arg.type || this.paramTypes[func.ref][param.name][0],
valueType: this.getValueType(arg, arg.type || this.paramTypes[func.ref][param.name][0], input),
value: arg.value || null,
value: arg.value || input.default || null,
expr: arg.expr || arg.source || null,
required: param.required || false,
input,

View File

@ -11,6 +11,11 @@ const variants = [
{ value: 'dark', text: 'Dark' },
]
const openModeVariants = [
{ value: 'newTab', text: 'Open link in a new tab' },
{ value: 'sameTab', text: 'Open link in the same tab' },
]
export const prompts = Object.freeze([
{
ref: 'redirect',
@ -19,6 +24,7 @@ export const prompts = Object.freeze([
{ name: 'owner', types: ['User', 'ID'], required: false },
{ name: 'url', types: ['String'], required: true },
{ name: 'delay', types: ['Integer'], meta: { description: 'Redirection delay in seconds' } },
{ name: 'openMode', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: openModeVariants }, default: 'sameTab' } } } },
],
},
{
@ -30,6 +36,7 @@ export const prompts = Object.freeze([
{ name: 'params', types: ['KV'] },
{ name: 'query', types: ['KV'] },
{ name: 'delay', types: ['Integer'], meta: { description: 'Redirection delay in seconds' } },
{ name: 'openMode', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: openModeVariants }, default: 'sameTab' } } } },
],
},
{
@ -45,6 +52,7 @@ export const prompts = Object.freeze([
{ name: 'record', types: ['ID', 'ComposeRecord'] },
{ name: 'edit', types: ['Boolean'] },
{ name: 'delay', types: ['Integer'], meta: { description: 'Redirection delay in seconds' } },
{ name: 'openMode', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: [...openModeVariants, { value: 'modal', text: 'Open in a modal' }] }, default: 'sameTab' } } } },
],
},
{
@ -58,7 +66,7 @@ export const prompts = Object.freeze([
{ name: 'owner', types: ['User', 'ID'], required: false },
{ name: 'title', types: ['String'] },
{ name: 'message', types: ['String'], required: true },
{ name: 'variant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants } } } } },
{ name: 'variant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants }, default: 'primary' } } } },
{ name: 'timeout', types: ['Integer'], meta: { description: 'How long do we show the notification in seconds' } },
],
},
@ -70,7 +78,7 @@ export const prompts = Object.freeze([
{ name: 'title', types: ['String'] },
{ name: 'message', types: ['String'], required: true },
{ name: 'buttonLabel', types: ['String'] },
{ name: 'buttonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants } } } } },
{ name: 'buttonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants }, default: 'primary' } } } },
{ name: 'buttonValue', types: ['Any'] },
],
},
@ -82,10 +90,10 @@ export const prompts = Object.freeze([
{ name: 'title', types: ['String'] },
{ name: 'message', types: ['String'], required: true },
{ name: 'confirmButtonLabel', types: ['String'] },
{ name: 'confirmButtonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants } } } } },
{ name: 'confirmButtonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants }, default: 'primary' } } } },
{ name: 'confirmButtonValue', types: ['Any'] },
{ name: 'rejectButtonLabel', types: ['String'] },
{ name: 'rejectButtonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants } } } } },
{ name: 'rejectButtonVariant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants }, default: 'danger' } } } },
{ name: 'rejectButtonValue', types: ['Any'] },
],
results: [
@ -147,7 +155,7 @@ export const prompts = Object.freeze([
parameters: [
{ name: 'owner', types: ['User', 'ID'], required: false },
{ name: 'title', types: ['String'] },
{ name: 'variant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants } } } } },
{ name: 'variant', types: ['String'], meta: { visual: { input: { type: 'select', properties: { options: variants }, default: 'primary' } } } },
{ name: 'message', types: ['String'], required: true },
{ name: 'label', types: ['String'] },
{

View File

@ -6,7 +6,7 @@ import notification from './CPromptNotification.vue'
import options from './CPromptOptions.vue'
import { Component } from 'vue'
import { pType, pVal } from '../utils'
import { automation } from '@cortezaproject/corteza-js'
import { automation, NoID } from '@cortezaproject/corteza-js'
import { KV } from '@cortezaproject/corteza-js/dist/compose/types/chart/util'
interface Handler {
@ -61,11 +61,18 @@ const definitions: Record<string, PromptDefinition> = {
handler: function (v): void {
const url = pVal(v, 'url')
const delay = (pVal(v, 'delay') || 0) as number
const openMode = pVal(v, 'openMode')
if (url !== undefined) {
console.debug('redirect to %s via prompt in %d sec', url, delay)
setTimeout(() => {
// @ts-ignore
window.location = url
if (openMode === 'newTab') {
// @ts-ignore
window.open(url, '_blank')
} else {
// @ts-ignore
window.location = url
}
}, delay * 1000)
}
},
@ -77,11 +84,20 @@ const definitions: Record<string, PromptDefinition> = {
const params = pVal(v, 'params')
const query = pVal(v, 'query')
const delay = (pVal(v, 'delay') || 0) as number
const openMode = pVal(v, 'openMode')
if (name !== undefined) {
console.debug('reroute to %s via prompt in %d sec', name, delay, { params, query })
setTimeout(() => {
// @ts-ignore
this.$router.push({ name, params, query })
const routeParams = { name, params, query }
if (openMode === 'newTab') {
// @ts-ignore
const url = this.$router.resolve(routeParams).href
// @ts-ignore
window.open(url, '_blank')
} else {
// @ts-ignore
this.$router.push(routeParams)
}
}, delay * 1000)
}
},
@ -94,6 +110,7 @@ const definitions: Record<string, PromptDefinition> = {
const record = pVal(v, 'record')
const edit = !!pVal(v, 'edit')
const delay = (pVal(v, 'delay') || 0) as number
const openMode = pVal(v, 'openMode')
let namespaceID = ''
let slug = ''
@ -122,7 +139,9 @@ const definitions: Record<string, PromptDefinition> = {
// @ts-ignore
const { set: nn } = await this.$ComposeAPI.namespaceList({ slug: namespace as string })
if (!nn || nn.length !== 1) {
throw new Error('namespace not resolved')
// @ts-ignore
this.toastDanger('Namespace not resolved', 'Prompt error')
return
}
namespaceID = nn[0].namespaceID
@ -138,7 +157,9 @@ const definitions: Record<string, PromptDefinition> = {
// @ts-ignore
const { set: mm } = await this.$ComposeAPI.moduleList({ handle: module as string, namespaceID })
if (!mm || mm.length !== 1) {
throw new Error('module not resolved')
// @ts-ignore
this.toastDanger('Module not resolved', 'Prompt error')
return
}
moduleID = mm[0].moduleID
@ -155,19 +176,17 @@ const definitions: Record<string, PromptDefinition> = {
// @ts-ignore
const { set: pp } = await this.$ComposeAPI.pageList({ moduleID, namespaceID })
if (!pp || pp.length !== 1) {
throw new Error('record page not resolved')
// @ts-ignore
this.toastDanger('Record page not resolved', 'Prompt error')
return
}
pageID = pp[0].pageID
// @ts-ignore
if (this.$root.$options.name === 'compose') {
if (!edit && !recordID) {
throw new Error('invalid record page prompt configuration')
}
let name = 'page.record'
if (edit) {
name += recordID ? '.edit' : '.create'
if (edit || !recordID || recordID === NoID) {
name += recordID && recordID !== NoID ? '.edit' : '.create'
}
// If name and params match, make sure to refresh page instead of push
@ -176,11 +195,24 @@ const definitions: Record<string, PromptDefinition> = {
setTimeout(() => {
console.debug('reroute to %s via prompt in %d sec', name, delay, { namespaceID, slug, moduleID, recordID })
const routeParams = { name, params: { recordID, pageID, slug } }
if (reloadPage) {
window.location.reload()
} else if (openMode === 'modal') {
// @ts-ignore
this.$root.$emit('show-record-modal', {
recordID: !recordID ? NoID : recordID,
recordPageID: pageID,
})
} else if (openMode === 'newTab') {
// @ts-ignore
const url = this.$router.resolve(routeParams).href
// @ts-ignore
window.open(url, '_blank')
} else {
// @ts-ignore
this.$router.push({ name, params: { recordID, pageID, slug } })
this.$router.push(routeParams)
}
}, delay * 1000)
} else {