Add Filters
${this._draft.length ? html`
(this._picker = null)}"
>` : ''}
(this._search = String((e.target as ZnInput).value ?? ''))}"
@input="${(e: Event) => (this._search = String((e.target as ZnInput).value ?? ''))}"
>
${matches.length === 0
? html`
No matching filters.
`
: matches.map(f => html`
`)}
`;
}
/**
* A select's minimum width, sized so its longest label never truncates
* (estimated per char, plus padding and the chevron). When the row can't
* fit it, flex-wrap gives the select its own full-width line instead.
*/
private static _selectMinWidth(labels: string[]): number {
const longest = Math.max(0, ...labels.map(l => l.length));
return Math.min(260, Math.round(52 + longest * 7.2));
}
private _renderField(condition: FlowBranchCondition, group: number, index: number, field: FlowFilterField) {
const entry = condition.values[field.id] ?? {};
const type = field.type ?? (field.options?.length ? 'select' : 'text');
const set = (patch: { operator?: string; value?: string | number; unit?: string }) =>
this._setField(group, index, field.id, patch);
return html`
${filter?.label ?? condition.filter}
this._removeCondition(group, index)}">
${(filter?.fields ?? []).map(f => this._renderField(condition, group, index, f))}
`;
}
private _renderConditions() {
return html`
${this._draft.map((group, gi) => html`
${gi > 0 ? html`
OR
` : ''}
${group.map((condition, ci) => html`
${ci > 0 ? html`
AND
` : ''}
${this._renderCondition(condition, gi, ci)}
`)}
(this._picker = gi)}" panel-bg>AND
`)}
(this._picker = this._draft.length)}" panel-bg>
OR
`;
}
render() {
// With nothing configured yet, the picker is the first step (as designed).
const picking = this._picker !== null || this._draft.length === 0;
return html`