Skip to content

Tags

Read and edit the tag catalog and its assignments. Accessed via snaptrude.core.tags.

A tag is a colored label that lives in a category; a space carries at most one tag per category. This namespace is the catalog + assignment surface: the categories and tags themselves, which components carry which tags, and the assign/unassign operations. Tags attach to Mass and Floor spaces only.

Reserved sentinels. The built-in DEPARTMENT category is owned by the program layer — it and its tags are read-only here; create/update/delete/deleteCategory reject it and direct you to snaptrude.program.departments. Every category also has a built-in DEFAULT tag that cannot be deleted; unassigning resets a component's category slot back to DEFAULT (a component is never left with a blank slot).

Reads return plain records and never throw for a miss (get* return null, list* return []). Ids are stable public strings. Deletes are non-undoable and report impact counts.

At a glance

MethodWhat it doesMutates?
listCategories()List every tag category
getCategory(categoryId)One category by id, or null
list(categoryId?)The tags, optionally in one category
get(tagId)One tag by id, or null
getTagsForComponent(componentId)The tags a component carries
listComponents(filter)Components carrying a tag (or untagged in a category)
createCategory(name)Create a tag category
updateCategory(categoryId, name)Rename a category
deleteCategory(categoryId)Delete a category and its tags✓ (not undoable)
create(categoryId, name, color?)Create a tag in a category
update(tagId, options?)Rename / recolor a tag
delete(tagId)Delete a tag✓ (not undoable)
assign(componentIds, categoryName, tagName)Resolve-or-create a category + tag and assign it
unassign(categoryId, componentIds)Reset components back to the category's DEFAULT tag

Types

PluginCoreTagCategory

A tag category — a named slot that holds a set of mutually-exclusive tags.

PropertyTypeDescription
idstringStable public category id
namestringDisplay name
tagIdsstring[]Ids of the tags in this category

PluginCoreTag

A tag — a colored label within a category.

PropertyTypeDescription
idstringStable public tag id
categoryIdstringThe id of the category this tag belongs to
namestringDisplay name
colorstringCSS hex color string (e.g. "#b5e1dc")

PluginCoreComponentTag

A tag as carried by a component — the category and tag names resolved for display.

PropertyTypeDescription
categoryIdstringThe category's id
categoryNamestringThe category's display name
tagIdstringThe tag's id
tagNamestringThe tag's display name
colorstringThe tag's CSS hex color string

PluginCoreAssignOutcome

The outcome of an assign/unassign — which components changed and which were skipped (with a reason).

PropertyTypeDescription
assignedstring[]Ids of the components that changed
skipped{ id: string; reason: "locked" | "not-taggable" | "not-found" }[]Components not changed, each with a reason

Functions

listCategories()

List the tag categories, including the reserved DEPARTMENT category.

  • Returns: { categories: PluginCoreTagCategory[] } — empty when there are none.
ts
const { categories } = await snaptrude.core.tags.listCategories();
for (const c of categories) console.log(c.name, c.tagIds.length);

getCategory(categoryId)

Get a single tag category by id.

  • Parameters:
    • categoryId: string — the id of the category to read
  • Returns: PluginCoreTagCategory | nullnull if no category has that id.
ts
const category = await snaptrude.core.tags.getCategory("cat_3");
if (category) console.log(category.name, category.tagIds);

list(categoryId?)

List tags, optionally within one category.

  • Parameters:
    • categoryId: string | undefined — optional category filter; omit to list every tag
  • Returns: { tags: PluginCoreTag[] } — empty when there are none.
ts
const { tags } = await snaptrude.core.tags.list("cat_3");
for (const t of tags) console.log(t.name, t.color);

get(tagId)

Get a single tag by id.

  • Parameters:
    • tagId: string — the id of the tag to read
  • Returns: PluginCoreTag | nullnull if no tag has that id.
ts
const tag = await snaptrude.core.tags.get("tag_9");
if (tag) console.log(tag.name, tag.color);

getTagsForComponent(componentId)

List the tags carried by a component — one entry per category the component is tagged in, each carrying the category and tag names and the tag color. Untagged (default) category slots are omitted.

  • Parameters:
    • componentId: ComponentHandle — the Component.id to read
  • Returns: { tags: PluginCoreComponentTag[] } — empty when the component has none or does not exist.
ts
const { tags } = await snaptrude.core.tags.getTagsForComponent("cmp_42");
for (const t of tags) console.log(t.categoryName, t.tagName);

listComponents(filter)

List the components carrying a given tag or category. Provide exactly one of filter.tagId (components with that specific tag) or filter.categoryId (components carrying any non-default tag in that category). With categoryId, pass untagged: true to instead return the components that have no non-default tag in that category. untagged is valid only alongside categoryId.

  • Parameters:
    • filter.tagId: string | undefined — components carrying this specific tag
    • filter.categoryId: string | undefined — components carrying any non-default tag in this category
    • filter.untagged: boolean | undefined — with categoryId, return components with no non-default tag in that category instead
  • Returns: { componentIds: ComponentHandle[] } — empty when none match.
ts
const { componentIds } = await snaptrude.core.tags.listComponents({ tagId: "tag_9" });
console.log(`${componentIds.length} components`);

createCategory(name)

Create a new tag category.

  • Parameters:
    • name: string — display name of the new category
  • Returns: PluginCoreTagCategory — the new category.
  • Throws: If the name collides with the reserved DEPARTMENT category, the category could not be created.
ts
const category = await snaptrude.core.tags.createCategory("Fire Rating");

updateCategory(categoryId, name)

Rename a tag category.

  • Parameters:
    • categoryId: string — the id of the category to rename
    • name: string — the category's new display name
  • Returns: PluginCoreTagCategory — the updated category.
  • Throws: If no category has the given id, it is the reserved DEPARTMENT category.
ts
const category = await snaptrude.core.tags.updateCategory("cat_3", "Occupancy");

deleteCategory(categoryId)

Delete a tag category and all its tags. Non-undoable. Every component tagged in this category is reset to the category's DEFAULT; the result reports how many tags were removed and how many components were reset.

  • Parameters:
    • categoryId: string — the id of the category to delete
  • Returns: { deletedTagCount: number; resetComponentCount: number }
  • Throws: If no category has the given id, it is the reserved DEPARTMENT category.
ts
const { deletedTagCount } = await snaptrude.core.tags.deleteCategory("cat_3");

create(categoryId, name, color?)

Create a new tag in a category.

  • Parameters:
    • categoryId: string — the category the new tag belongs to
    • name: string — display name of the new tag
    • color: string | undefined — CSS hex color string (auto-assigned if omitted)
  • Returns: PluginCoreTag — the new tag.
  • Throws: If no category has the given id, it is the reserved DEPARTMENT category.
ts
const tag = await snaptrude.core.tags.create("cat_3", "Retail", "#b5e1dc");

update(tagId, options?)

Update a tag's name and/or color. A sparse update: omitted fields are left unchanged.

  • Parameters:
    • tagId: string — the id of the tag to update
    • options.name: string | undefined — new display name (unchanged if omitted)
    • options.color: string | undefined — new CSS hex color (unchanged if omitted)
  • Returns: PluginCoreTag — the updated tag.
  • Throws: If no tag has the given id, it belongs to the reserved DEPARTMENT category.
ts
const tag = await snaptrude.core.tags.update("tag_9", { name: "Retail" });

delete(tagId)

Delete a tag. Non-undoable. Every component carrying this tag is reset to its category's DEFAULT; the result reports how many components were reset. The built-in DEFAULT tag cannot be deleted.

  • Parameters:
    • tagId: string — the id of the tag to delete
  • Returns: { resetComponentCount: number }
  • Throws: If no tag has the given id, it is a DEFAULT tag, it belongs to the reserved DEPARTMENT category.
ts
const { resetComponentCount } = await snaptrude.core.tags.delete("tag_9");

assign(componentIds, categoryName, tagName)

Assign a tag to components, creating the category and tag if needed. Resolves tagName within the category named categoryName: if the category or the tag doesn't exist yet it is created, otherwise the existing one is reused — resolve-or-create and assign are one atomic, undoable action. Because a component carries one tag per category, this replaces any existing tag from that category. Components that are locked, not taggable, or not found are returned in skipped with a reason — never silently dropped. Rejects the reserved DEPARTMENT category.

  • Parameters:
    • componentIds: ComponentHandle[] — the components to tag (at least one)
    • categoryName: string — the category to resolve or create
    • tagName: string — the tag (within that category) to resolve or create, then apply
  • Returns: PluginCoreAssignOutcome extended with the resolved categoryId / tagId, the categoryCreated / tagCreated flags, and the assigned / skipped split.
  • Throws: If categoryName is the reserved DEPARTMENT category.
ts
const { tagId, tagCreated, assigned } = await snaptrude.core.tags.assign(
  ["cmp_1", "cmp_2"],
  "Zone",
  "Retail"
);

unassign(categoryId, componentIds)

Clear a category's tag from components. Resets each component's slot for the given category back to DEFAULT (a component always has a DEFAULT — the field is never blanked). Components that are locked, not taggable, or not found are returned in skipped. Undoable.

  • Parameters:
    • categoryId: string — the category slot to reset to default
    • componentIds: ComponentHandle[] — the components to clear (at least one)
  • Returns: PluginCoreAssignOutcome — splits assigned (reset to default) from skipped.
  • Throws: If no category has the given id.
ts
await snaptrude.core.tags.unassign("cat_3", ["cmp_1", "cmp_2"]);

Errors

Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:

CodeThrown byWhendetails
HANDLE_INVALIDupdateCategory, deleteCategory, create, unassignNo category has the given idkind: "tag-category"
HANDLE_INVALIDupdate, deleteNo tag has the given idkind: "tag"
PRECONDITION_FAILEDevery catalog write, assignThe target (or the given name) is the reserved DEPARTMENT category — use snaptrude.program.departments
PRECONDITION_FAILEDdeleteThe target is a built-in DEFAULT taghandles — the tag id
OPERATION_FAILEDcatalog writes, assignThe engine rejected the change (empty name, bad color, backend failure) — the message carries the engine's exact reason

Reads never throw on a miss, and assign/unassign never throw for individual components — locked, non-taggable, or unknown components come back in skipped (partial success by contract).