Assets Reference Public

Categories

Catalog & Setup Categories Categories are the classification tree for your asset registry — Hardware > Computers > Laptops, Furniture, Vehicles. Every asset added or edited on the…

Guide version: r1 Module version: 1.0.0 Updated: 2026-07-22 Estimated time: 9 min 1 views
Catalog & Setup

Categories

Categories are the classification tree for your asset registry — Hardware > Computers > Laptops, Furniture, Vehicles. Every asset added or edited on the asset form must be given exactly one category, and the category does real work: it decides which "Additional fields" appear on the asset form (through its bound Fieldset), and it powers the category filter in the asset registry.

ℹ️
Where this screen lives. Categories has its own sidebar entry — open Safekeep → Categories (ams/categories), directly below Assets. It is the first tab of that page's tab strip (Categories / Groups / Status Labels) and is visible only to users who hold the asset_category permission ("Assets: Categories"). The Groups and Status Labels tabs load via AJAX from ams/asset_groups and ams/status_labels.

Why categories matter

A category is more than a folder name. Four different behaviors hang off it:

????
Custom fields ("Additional fields")

The category's Fieldset binding decides which extra fields the asset form shows under the "Additional fields" heading for assets in that category. See Custom Fields & Fieldsets.

????
Registry filter & column

The Browse tab of the asset registry has a category filter dropdown, and its "Category" column shows each asset's full category breadcrumb. See The Asset Registry.

????
Required on every asset

"Category" is a required field when adding or editing an asset — the save is validated server-side. An Asset Model can pre-fill it when you pick a model on the form.

✍️
Acceptance agreement (EULA)

Two database columns on the category (require_acceptance, eula_text) can force assignees to sign an agreement when they Confirm receipt of an asset. See the caveat below and Checkout & Check-in.


The Categories list

The tab shows a searchable DataTable of every category, sorted by the first column descending, with a table refresh button and an XLS export of the data columns. Users with asset_category_create also see an "Add category" button (plus-circle icon) that opens the add modal.

List columns

ColumnWhat it showsNotes
Title The category name, rendered with its full parent path as a breadcrumb. e.g. Hardware > Computers > Laptops — the ancestors are prefixed automatically, so you always see where a category sits in the tree.
Description The category's free-text description. Line breaks preserved.
Date created When the category was created. Raw stored value.
Created by The user who created it, as a profile link. Opens in a new tab.
Options Row actions. Pencil = "Edit category" (needs asset_category_update); × = delete with a confirmation prompt (needs asset_category_delete).

Hierarchy — parent categories & the breadcrumb

Categories form a tree. Each category can name one Parent, and everywhere the module displays a category — the Categories list, the Parent and Category dropdowns, the registry's Category column — it renders the full ancestor path (Grandparent > Parent > Child) so identically-named leaves in different branches stay distinguishable.

  • Depth cap. If the parent you pick already sits more than three levels deep, the save is rejected with "Maximum of 3 layers parenting only". In practice the tree tops out at about four levels.
  • No self-parenting. When editing a category, the category itself is excluded from the Parent dropdown, so you cannot make a category its own parent.
  • Root categories. Leave Parent at its - default to create a top-level category.
????
The same three-layer parenting pattern (and the same error message) applies to Locations. Both trees render the identical Parent > Child breadcrumb style.

Adding & editing a category

????
Purpose: create or change a category so assets can be classified and pick up the right custom fields.
Who: a user with asset_category_create (add) or asset_category_update (edit).
Preconditions: the Assets module is enabled and you can see the Categories page (asset_category). If you want to bind custom fields, the Fieldset should already exist.
  1. Open the modal

    On Safekeep → Categories, click "Add category" — or click the pencil ("Edit category") on an existing row to open the same modal pre-filled.

  2. Fill in the form

    Only Title is required. Pick a Parent to place the category in the tree and a Fieldset to give its assets extra fields (both optional — see the field table below).

  3. Save

    Click "Save" (the modal's single footer button). On success you'll see the toast "The record has been saved." and the row appears in (or updates within) the table without a page reload.

Form fields

FieldRequiredTypeNotes
Title Required Text Autofocused. Enforced client-side ("This field is required."); the server does not re-check it, so don't bypass the form.
Description Optional Rich-text textarea Free-form notes about what belongs in the category.
Parent Optional Select2 dropdown Defaults to - (top level). Lists every other category with its full breadcrumb path; the category being edited is excluded. Subject to the "Maximum of 3 layers parenting only" rule.
Fieldset Optional Select2 dropdown Defaults to - (no extra fields). Lists all Fieldsets by name. This is the binding that drives the asset form's "Additional fields" — see the next section.

The Fieldset binding — how categories drive "Additional fields"

Custom fields never attach to an asset directly. The chain is:

Custom Fields
Global field masters (text, number, date, dropdown…) defined on the Custom Fields page.
Fieldset
An ordered bundle of those fields, with a per-row Required flag, built on the Fieldsets tab.
Category
Binds ONE fieldset via the modal's Fieldset dropdown and caches its compiled schema.
Asset form
Shows the fields under the "Additional fields" heading for every asset in that category; values are stored per asset.

When you save a category, the module immediately recompiles and caches the category's custom-field schema from the bound fieldset, so the asset form (and the mobile API) exposes the fields right away — no waiting, no manual sync. The Fieldsets screen states the same guarantee in its own help text: "Bind custom fields to this fieldset; row order sets the display order. Categories using this fieldset are recompiled automatically."

  • Changing a category's Fieldset (or clearing it back to -) changes which extra fields appear the next time someone opens an asset in that category. Values already entered are kept in the asset's stored data but are no longer shown if their field leaves the schema.
  • On the asset form, switching the Category dropdown reloads the "Additional fields" section live to match the newly selected category's schema.
  • Whether each field is required comes from the fieldset's per-row Required checkbox; a missing required field blocks the asset save with "%s is required." (and numeric fields validate with "%s must be a number.").
????
Asset Models also carry a Fieldset dropdown, but it is the category's binding that the asset form compiles and renders. Bind the fieldset on the category to make fields appear.

Acceptance agreement (EULA) — database-only

Each category row carries two extra columns that plug into the endorsement lifecycle: require_acceptance (on/off) and eula_text (the agreement text). When an asset in such a category is endorsed to a user and that user clicks "Confirm receipt", the acknowledge modal upgrades from a simple confirmation into a signing ceremony:

  • If require_acceptance is on and eula_text is set, the modal shows the agreement under the heading "Acceptance agreement" in a scrollable box, with a mandatory checkbox labeled "I have read and accept the terms above."
  • Whenever require_acceptance is on, the modal adds a required "Type your full name to sign" field.
  • Both are enforced on the server too: submitting without a signature returns "Please type your full name to accept the agreement.", and skipping the checkbox (when an EULA is shown) returns "Please tick the box to accept the terms."
  • On success the module stores the agreement text and the typed signature with the acknowledgment event, logs it on the asset's activity timeline as "Receipt confirmed." with "Signed: name", and marks the endorsement Acknowledged.

The full acknowledge flow — who can confirm, what the timeline records — is documented in Checkout & Check-in.

⚠️
There is no UI to turn this on. The Category modal has only Title, Description, Parent and Fieldset — no form anywhere in the application exposes require_acceptance or eula_text, and no seeded category sets them. The only way to enable the acceptance agreement for a category today is to set those two columns directly in the database (asset_categories table). Until that is done, "Confirm receipt" shows only the plain confirmation message, with no agreement and no signature field.

The category filter in the asset registry

On the Browse tab of the Assets page, one of the filter dropdowns above the table is the category filter. It defaults to "- Categories -" and lists every category by its plain title (no breadcrumb prefix in this dropdown).

  • Exact match only. Picking a category shows assets assigned to that exact category — it does not include assets in its child categories. To review a whole branch such as Hardware, filter each descendant category in turn (or sort/search the Category column).
  • The Category column in the registry shows each asset's full breadcrumb (Hardware > Computers > Laptops), so the tree is still visible even though the filter is flat.
  • A "Category" dropdown also filters the export modal and the QR label generator — there it lists full breadcrumb paths and defaults to -. See Import, Export & Labels.

Deleting a category

The × row action (permission asset_category_delete) asks for confirmation, then soft-deletes the category and shows "The record has been deleted."

????
No in-use protection. The delete always goes through — there is no check for assets, models, or child categories still referencing the category. Consequences of deleting a category that is still in use: assets keep pointing at the deleted category, so the registry's Category column goes blank for them; their "Additional fields" schema can no longer be resolved; and any child categories lose their breadcrumb ancestor. Reassign assets (and re-parent children) to another category before deleting. The message "The record is in use, you can't delete the record!" exists in the codebase but is never actually triggered on this screen.

Permissions recap

PermissionLabel in RolesGrants
asset_category"Assets: Categories" See the Categories sidebar entry and page at all (ams/categories).
asset_category_create"Create Category" The "Add category" button and saving new categories.
asset_category_update"Update Category" The pencil ("Edit category") action and saving edits.
asset_category_delete"Delete Category" The × delete action.

Unlike Models, Status Labels, Custom Fields, Fieldsets and Depreciations (which ride on the single asset permission), Categories has its own full create/update/delete permission set — see Permissions & Roles for the whole matrix.

Related pages

Was this guide helpful?

Report a content problem