Atomic Angular — Doc interne

Labels

Public and private labels on a document — an autosuggest multi-select field, and a bulk-edit dialog that shows both fields side by side, gated by the labels web service's own configuration.

A label is a free-text tag attached to a document, either public (shared, visible to every user) or private (visible only to the user who added it). <multiselect-labels> is the field that adds and removes them on one article field; EditLabels is the dialog that shows the public and private fields together for a single document.

Concept — labels web service

Whether labels are available at all — and which article fields hold the public/private lists — comes from the Sinequa server's labels web service configuration, read through LabelService.getLabelsConfig(). An app with no labels web service configured has no label fields to show; EditLabels renders nothing in that case rather than an empty dialog.

Minimal example

A private-labels field on an article
sample.component.ts
import { Component, signal } from "@angular/core";
import { MultiSelectLabelsComponent } from "@sinequa/atomic-angular";
import type { Article } from "@sinequa/atomic";

@Component({
  selector: "sample-component",
  imports: [MultiSelectLabelsComponent],
  template: `
    <multiselect-labels [(article)]="article" labelsField="privatelabels1" [allowModification]="true" />
  `,
})
export class SampleComponent {
  // Article has no index signature of its own — a document's extra, app-specific
  // fields (like a labels field) need the double cast to bypass the overlap check.
  protected readonly article = signal<Article>({ id: "doc-1", privatelabels1: ["draft"] } as unknown as Article);
}

labelsField names the article property the picked/removed labels are read from and written back to — it has to match the field the labels web service configuration actually uses for that visibility (public or private), which is exactly what EditLabels resolves for you (see Recipes).

How it works

types / picks / removes loader(query) client.api.labels.get() add()/remove() article[labelsField] = labels User MultiSelectLabelsComponent LabelService.fetch() Backend bound article, via [(article)]

MultiSelectLabelsComponent wraps a galactik <Autocomplete> — suggestions come from client.api.labels.get(query, isPublic), and picking or removing a label calls client.api.labels.add/remove directly (not through LabelService, which exists mainly for the bulk and rights-checking operations used elsewhere).

Recipes

Editing both label fields for one document

EditLabels reads the labels web service configuration itself and renders a public field, a private field, or both, depending on what the app actually exposes — the caller does not need to know the field names.

Opening the edit-labels dialog
edit-labels-button.component.ts
import { Component, inject, Injector } from "@angular/core";
import { EditLabels } from "@sinequa/atomic-angular";
import type { Article } from "@sinequa/atomic";

@Component({
  selector: "edit-labels-button",
  template: `<button (click)="edit()">Edit labels…</button>`,
})
export class EditLabelsButtonComponent {
  private readonly injector = inject(Injector);

  protected async edit() {
    const article: Article = { id: "doc-1" } as Article;
    // Resolves with { type, article } once the dialog closes — the article carries whatever
    // label edits were made, ready to merge back into your own state if you're not re-fetching.
    const { article: edited } = await EditLabels.call(article, { injector: this.injector });
    console.log(edited);
  }
}

Options

Prop

Type

Pitfalls

What's next

On this page