Atomic Angular — Doc interne

Getting started

Install @sinequa/atomic-angular, connect a client, sign a user in, and render a first authenticated search screen with a facet.

This walks through the whole path from an empty Angular application to a first authenticated screen showing search results and a facet. Each step links to the page that covers it in full — this tutorial only shows the minimum needed to reach the next step.

Prerequisite — a Sinequa server

You need a Sinequa server reachable from the browser, with at least one query web service configured. Nothing here works against a mock — the client, the guard and the query service all make real HTTP requests.

Install

@sinequa/atomic-angular composes two lower-level libraries — @sinequa/galactik (presentation) and @sinequa/atomic (the framework-agnostic client). Both are peer dependencies, alongside @angular/aria.

Install the library and its peer dependencies
terminal
npm install @sinequa/atomic-angular @sinequa/atomic @sinequa/galactik @angular/aria

chart.js/chartjs-chart-matrix and markdown-it are also peer dependencies, but only needed if you use the Chart.js-based data visualization components or the preview's Markdown fallback — skip them otherwise. Likewise vanilla-calendar-pro, with the @sinequa/atomic-angular/styles/calendar.css stylesheet, is only needed for the custom range of a date facet.

Provide a client and bootstrap the application

Every store, service and component reaches the backend through one client. Registering it and bootstrapping the application are two providers in app.config.ts.

app.config.ts
app.config.ts
import { ApplicationConfig, provideAppInitializer } from "@angular/core";
import { bootstrapApp, provideAtomicClient } from "@sinequa/atomic-angular";

export const appConfig: ApplicationConfig = {
  providers: [
    // backendUrl may be omitted — bootstrapApp derives it from the browser URL.
    provideAtomicClient({ app: "my-app" }),
    provideAppInitializer(() => bootstrapApp({ createRoutes: true })),
  ],
};

bootstrapApp() resolves the authentication mode, signs the user in if a session already exists, and initializes the application's stores before the first view renders — see Provide a client and Bootstrap the application for the full contract, including what to do when part of the configuration is only known at runtime.

Authenticate the user

Route /login and /logout to AuthPageComponent — it switches between the credentials form, change-password and forgot-password based on the route and the mode query param — and guard every protected route with AuthGuard().

app.routes.ts
app.routes.ts
import { AuthGuard, AuthPageComponent, ErrorComponent } from "@sinequa/atomic-angular";
import type { Routes } from "@angular/router";
import { SearchComponent } from "./search.component";

export const routes: Routes = [
  { path: "login", component: AuthPageComponent },
  { path: "logout", component: AuthPageComponent },
  { path: "error", component: ErrorComponent },
  { path: "search", component: SearchComponent, canActivate: [AuthGuard()] },
  { path: "", redirectTo: "search", pathMatch: "full" },
];

AuthGuard() checks the session, loads the signed-in user, and — in credentials mode — redirects to change-password when the session's password has expired; it never guards /login//logout themselves. See Sign In for embedding the form outside a full page, and Authentication flows for how the guard, the interceptor, sign-in and logout fit together end to end.

Render a first search screen

QueryService runs the search and exposes the result as a signal; <Aggregation> renders one facet from that same result and turns a click into an applied filter.

Clicking a value in the "Sources" facet applies a filter to the shared query state and re-runs the search on its own — nothing in SearchComponent has to react to that click by hand. See Filtering results for facet types, controlled mode and custom item templates, and Query for paging, running several queries in parallel, and telling a failed request apart from a genuine zero-match.

What's next

On this page