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.
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:
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.
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.
"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.
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
| Column | What it shows | Notes |
|---|---|---|
| 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.
Parent > Child breadcrumb style.
Adding & editing a category
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.
-
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.
-
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).
-
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
| Field | Required | Type | Notes |
|---|---|---|---|
| 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:
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.").
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_acceptanceis on andeula_textis 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_acceptanceis 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.
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."
Permissions recap
| Permission | Label in Roles | Grants |
|---|---|---|
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.