feat: Ability to change subscription status in workflows
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import {Label, RadioGroup, RadioGroupItem} from '@plunk/ui';
|
||||
import {useState} from 'react';
|
||||
import {toast} from 'sonner';
|
||||
|
||||
@@ -5,31 +6,50 @@ import {KeyValueEditor} from '../KeyValueEditor';
|
||||
|
||||
import {type EditStepDialogProps, getStepConfig, StepDialogShell, useStepUpdate} from './shared';
|
||||
|
||||
type SubscriptionAction = 'none' | 'subscribe' | 'unsubscribe';
|
||||
|
||||
const SUBSCRIPTION_OPTIONS: Array<{value: SubscriptionAction; label: string; description: string}> = [
|
||||
{value: 'none', label: 'Leave as is', description: "Don't change the contact's subscription state."},
|
||||
{value: 'subscribe', label: 'Subscribe', description: 'Mark the contact as subscribed.'},
|
||||
{value: 'unsubscribe', label: 'Unsubscribe', description: 'Mark the contact as unsubscribed.'},
|
||||
];
|
||||
|
||||
export function UpdateContactStepDialog({step, workflowId, open, onOpenChange, onSuccess}: EditStepDialogProps) {
|
||||
const config = getStepConfig(step);
|
||||
const initialUpdates =
|
||||
config.updates && typeof config.updates === 'object'
|
||||
? (config.updates as Record<string, string | number | boolean>)
|
||||
: null;
|
||||
const initialSubscriptionAction: SubscriptionAction =
|
||||
config.subscriptionAction === 'subscribe' || config.subscriptionAction === 'unsubscribe'
|
||||
? config.subscriptionAction
|
||||
: 'none';
|
||||
|
||||
const [name, setName] = useState(step.name);
|
||||
const [contactUpdateData, setContactUpdateData] = useState<Record<string, string | number | boolean> | null>(
|
||||
initialUpdates,
|
||||
);
|
||||
const [subscriptionAction, setSubscriptionAction] = useState<SubscriptionAction>(initialSubscriptionAction);
|
||||
|
||||
const {update, isSubmitting} = useStepUpdate(workflowId, step.id);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!contactUpdateData || Object.keys(contactUpdateData).length === 0) {
|
||||
toast.error('At least one field to update is required');
|
||||
const hasUpdates = contactUpdateData && Object.keys(contactUpdateData).length > 0;
|
||||
const hasSubscriptionAction = subscriptionAction !== 'none';
|
||||
|
||||
if (!hasUpdates && !hasSubscriptionAction) {
|
||||
toast.error('Add at least one field to update or choose a subscription action');
|
||||
return;
|
||||
}
|
||||
|
||||
const ok = await update({
|
||||
name,
|
||||
config: {updates: contactUpdateData},
|
||||
config: {
|
||||
updates: hasUpdates ? contactUpdateData : {},
|
||||
subscriptionAction,
|
||||
},
|
||||
});
|
||||
|
||||
if (ok) {
|
||||
@@ -48,7 +68,32 @@ export function UpdateContactStepDialog({step, workflowId, open, onOpenChange, o
|
||||
onSubmit={handleSubmit}
|
||||
isSubmitting={isSubmitting}
|
||||
>
|
||||
<KeyValueEditor key={`edit-${step.id}`} initialData={contactUpdateData} onChange={setContactUpdateData} />
|
||||
<div className="space-y-2">
|
||||
<Label>Subscription state</Label>
|
||||
<RadioGroup
|
||||
value={subscriptionAction}
|
||||
onValueChange={value => setSubscriptionAction(value as SubscriptionAction)}
|
||||
className="gap-2"
|
||||
>
|
||||
{SUBSCRIPTION_OPTIONS.map(option => (
|
||||
<label
|
||||
key={option.value}
|
||||
htmlFor={`subscriptionAction-${option.value}`}
|
||||
className="flex items-start gap-3 rounded-md border border-neutral-200 p-3 cursor-pointer hover:bg-neutral-50"
|
||||
>
|
||||
<RadioGroupItem id={`subscriptionAction-${option.value}`} value={option.value} className="mt-0.5" />
|
||||
<div className="space-y-0.5">
|
||||
<div className="text-sm font-medium text-neutral-900">{option.label}</div>
|
||||
<div className="text-xs text-neutral-500">{option.description}</div>
|
||||
</div>
|
||||
</label>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<KeyValueEditor key={`edit-${step.id}`} initialData={contactUpdateData} onChange={setContactUpdateData} />
|
||||
</div>
|
||||
</StepDialogShell>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -206,11 +206,18 @@ export default function WorkflowEditorPage() {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'UPDATE_CONTACT':
|
||||
if (!config.updates || (typeof config.updates === 'object' && Object.keys(config.updates).length === 0)) {
|
||||
errors.push(`"${step.name}" step is missing contact updates`);
|
||||
case 'UPDATE_CONTACT': {
|
||||
const hasUpdates =
|
||||
config.updates && typeof config.updates === 'object' && Object.keys(config.updates).length > 0;
|
||||
const hasSubscriptionAction =
|
||||
typeof config.subscriptionAction === 'string' &&
|
||||
config.subscriptionAction !== 'none' &&
|
||||
config.subscriptionAction !== '';
|
||||
if (!hasUpdates && !hasSubscriptionAction) {
|
||||
errors.push(`"${step.name}" step is missing contact updates or a subscription action`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user