Skip to content

BlastForm.selectedChannel is a string bound to an object-valued NcSelect, which silently disables Create blast #1719

Description

@rubenvdlinde

What

BlastForm.selectedChannel is treated as a plain string by every consumer, but bound to an NcSelect whose options are {value, label} objects. The moment that model becomes an object, four things break at once and canSubmit() goes false, which is what the surviving requestConsent e2e failure reports.

The inconsistency

src/views/blasts/BlastForm.vue:

// 223 — initialised as a STRING
selectedChannel: 'email',

// 271 — options are OBJECTS
channelOptions() {
  return [
    { value: 'email', label: this.t('pipelinq', 'Email') },
    { value: 'sms',   label: this.t('pipelinq', 'SMS') },
  ]
},
<!-- 68 — bound with label="label", so vue-select hands back the OBJECT -->
<NcSelect v-model="selectedChannel" :options="channelOptions" label="label" :clearable="false" />

Every read assumes the string:

line code breaks as an object
287 this.templates.filter((t) => t.channel === this.selectedChannel) matches nothing, so the template list empties
456 this.selectedChannel !== 'email' always true, so the preflight is skipped
464 channel: this.selectedChannel posts an object where the API expects "email"
517 params: { channel: this.selectedChannel } same, as a query param
323 !!this.selectedChannel still truthy, so canSubmit() gives no warning

Line 323 is why this is quiet: the guard that would catch it only checks truthiness, and an object is truthy.

How it shows up

#1707 observed it from the outside and wrote the warning into the test: "opening it and dismissing it without picking clears the model, which makes canSubmit() false and leaves Create blast permanently disabled. Tried, measured, reverted."

That PR is merged and its serial-mode fix worked. skipAndSend passes now, and requestConsent fails fast with a real message instead of a 120s timeout:

Error: "Create blast" is disabled: canSubmit() is false, so one of
name / segment / template / channel is unset even though every step advanced
33 × locator resolved to <button disabled ...>

Run 33569048537, development at 4d4338b9: 4 failed / 328 passed. This is one of the four.

Fix

Two options, and they are not equivalent.

  1. Keep the model a string and let the select map to it — :reduce="(o) => o.value" — so the four call sites above stay correct as written. Smallest change, matches every existing consumer.
  2. Make the model an object and update all five reads plus the initial value. Larger, and line 464/517 then need .value before hitting the API.

(1) looks right. Whichever is chosen, canSubmit()'s channel term should assert the shape rather than truthiness, or this returns silently the next time.

Not claimed

I have not run the wizard interactively. The code inconsistency above is objective, and the failure mode matches what #1707 measured, but the exact moment the model flips (mount, open-and-dismiss, or advance) is worth confirming before fixing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

triageAwaiting triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions