Labels
User-applied tags on documents — public and private, with a rights model that decides what your interface may offer.
A label is a tag a user puts on documents. Two kinds, and the distinction runs through every call:
| Who sees it | Who may change it | |
|---|---|---|
| Public | Everyone | Only users with the right |
| Private | The user who set it | That user |
Every operation takes a publicOnly flag, defaulting to true. So a call that forgets it acts on public
labels — which is the kind a user may well not be allowed to touch.
Check the rights first
labels.rights() returns what the current user may do. An interface that offers a "manage public labels"
control to someone without the right produces a failed request the user cannot understand.
const rights = await client.api.labels.rights();
// canEditPublicLabels: may add and remove public labels on documents
// canManagePublicLabels: may rename and delete them altogether
if (rights.canEditPublicLabels) showPublicTagging();
if (rights.canManagePublicLabels) showLabelAdministration();Tagging documents
Suggest, apply, and remove a private label
import { createAtomicClient } from "@sinequa/atomic";
const client = createAtomicClient({
app: "<your-app>",
backendUrl: "https://<your-sinequa-server>",
});
await client.initializeConfig();
await client.auth.login();
const rights = await client.api.labels.rights();
/** Autocomplete over existing labels, so users converge on the same vocabulary. */
export function suggest(prefix: string, isPublic = false) {
// The locale matters: labels can be configured per language.
return client.api.labels.get(prefix, isPublic, navigator.language);
}
/** Private by default — public tagging needs the right. */
export async function tag(ids: string[], label: string, isPublic = false) {
if (isPublic && !rights.canEditPublicLabels) {
throw new Error("You cannot edit public labels.");
}
// Note the third argument: omitting it means PUBLIC, not private.
await client.api.labels.add([label], ids, isPublic);
}
export function untag(ids: string[], label: string, isPublic = false) {
return client.api.labels.remove([label], ids, isPublic);
}import { Injectable, inject, resource, signal } from "@angular/core";
import { SINEQUA } from "./sinequa";
@Injectable({ providedIn: "root" })
export class LabelsService {
private readonly client = inject(SINEQUA);
/** What the current user is allowed to do — drives which controls to render. */
readonly rights = resource({ loader: () => this.client.api.labels.rights() });
readonly prefix = signal("");
/** Autocomplete over existing labels, so users converge on one vocabulary. */
readonly suggestions = resource({
params: () => ({ prefix: this.prefix() }),
loader: ({ params }) =>
params.prefix.length < 2
? Promise.resolve([])
: // The locale matters: labels can be configured per language.
this.client.api.labels.get(params.prefix, false, navigator.language),
});
/** Private by default. The third argument defaults to PUBLIC when omitted. */
async tag(ids: string[], label: string, isPublic = false) {
if (isPublic && !this.rights.value()?.canEditPublicLabels) {
throw new Error("You cannot edit public labels.");
}
await this.client.api.labels.add([label], ids, isPublic);
}
untag(ids: string[], label: string, isPublic = false) {
return this.client.api.labels.remove([label], ids, isPublic);
}
}import type { LabelsRights } from "@sinequa/atomic";
import { useCallback, useEffect, useState } from "react";
import { ready, sinequa } from "./sinequa";
export function useLabels() {
const [rights, setRights] = useState<LabelsRights>();
// What the current user is allowed to do — drives which controls to render.
useEffect(() => {
ready.then(() => sinequa.api.labels.rights()).then(setRights);
}, []);
/** Autocomplete over existing labels, so users converge on one vocabulary. */
const suggest = useCallback(async (prefix: string, isPublic = false) => {
if (prefix.length < 2) return [];
await ready;
// The locale matters: labels can be configured per language.
return sinequa.api.labels.get(prefix, isPublic, navigator.language);
}, []);
/** Private by default. The third argument defaults to PUBLIC when omitted. */
const tag = useCallback(
async (ids: string[], label: string, isPublic = false) => {
if (isPublic && !rights?.canEditPublicLabels) {
throw new Error("You cannot edit public labels.");
}
await sinequa.api.labels.add([label], ids, isPublic);
},
[rights],
);
const untag = useCallback(
(ids: string[], label: string, isPublic = false) =>
sinequa.api.labels.remove([label], ids, isPublic),
[],
);
return { rights, suggest, tag, untag };
}The calls
Prop
Type