Alerts
List, reorder and delete a user's search alerts, and create or edit one through a callable Signal Forms dialog.
An alert is a saved query the server re-runs on a schedule — a frequency, the weekdays it repeats on, a time of
day. <Alerts> lists, reorders and deletes them; AlertForm opens the dialog that creates or edits one.
Concept — alert
Unlike a saved search a user re-runs by hand, an alert is re-run by the server on a schedule, and (depending on how the deployment is configured) can notify the user out of band when new matches appear.
Minimal example
import { Component, inject, Injector } from "@angular/core";
import { AlertForm, AlertsComponent } from "@sinequa/atomic-angular";
@Component({
selector: "sample-component",
imports: [AlertsComponent],
template: `
<Alerts />
<button type="button" (click)="createAlert()">New alert</button>
`,
})
export class SampleComponent {
private readonly injector = inject(Injector);
protected async createAlert() {
// Omit the index to create; pass one to edit UserSettingsStore.alerts()[index].
await AlertForm.call(undefined, { injector: this.injector });
}
}AlertForm is a callable, not a component — there is nothing to place in a template and no opened flag to
drive. The returned promise resolves with the DialogEvent that closed it: "dialog-confirm" when the alert
was saved, "dialog-cancel" otherwise.
How it works
The whole dialog is one Signal Forms field tree ([formRoot]), and the Confirm button is the form's
submit — there is no separate click handler that reads the model and calls a service. The seven weekday
checkboxes bind to plain booleans, one field each; Alert.Days (the bitfield the server actually stores) only
exists at the edges, folded by flagsFromWeekdays()/unfolded by weekdaysFromFlags().
Recipes
Editing an existing alert
import { Component, inject, Injector, input } from "@angular/core";
import { AlertForm } from "@sinequa/atomic-angular";
@Component({
selector: "alert-row",
template: `<button type="button" (click)="edit()">Edit</button>`,
})
export class AlertRowComponent {
readonly index = input.required<number>();
private readonly injector = inject(Injector);
protected async edit() {
const result = await AlertForm.call(this.index(), { injector: this.injector });
if (result === "dialog-confirm") {
// The row's own display already reflects the store — nothing else to do here.
}
}
}Options
Prop
Type
Neither component takes an input. AlertsComponent reads its list from UserSettingsStore; AlertDialog
receives its index through the callable's props and reports only through the resolved promise.
Pitfalls
What's next
Notifications & feedback
Saved search alerts the server re-runs on a schedule, and the toast interceptor that surfaces a failed HttpClient request to the user.
Toast interceptor
An HttpInterceptorFn that turns a failed HttpClient request into a toast for the status codes worth telling the user about, without wrapping HttpClient itself.