The Different Group Types
The Trio system utilizes a number of group types to implement different storage schemes.
The Lookup Value (LV)
This group's options are stored in lookup tables. Options are required/single. Here is how one is defined in the back end:
namespace App\Services\App\Module\Specific\Ceramic;
class CeramicInitDetails implements InitDetailsInterface
{
// ...
public static function modelGroups(): array
{
return [
// ...
'Primary Classification' => [
'code' => 'LV',
'field_name' => 'primary_classification_id',
'lookup_table_name' => 'primary_classifications',
'lookup_text_field' => 'name',
'dependency' => ['Scope.Artifact'],
],
];
}
}
By convention, the first two values in all lookup tables are 1: "Unassigned" and 2: "Unknown."
Enum Fields (EM)
Enum fields are required/single selection. Possible options are restricted at DB level.
Restricted Values (RV)
These fields' possible options are defined in the Module's Laravel Model. They are used when an enum is inappropriate; that is, when they also serve as primary keys. Options are required/single.
Module Tag (TM)
These groups store their options in the external [module]_tags and [module]_groups tables (see ERD).
namespace App\Services\App\Module\Specific\Ceramic;
class CeramicInitDetails implements InitDetailsInterface
{
// ...
public static function modelGroups(): array
{
return [
// ...
'Vessel Base' => [
'code' => 'TM',
'dependency' => ['Vessel Part.Base'],
'multiple' => true,
],
];
}
}
As these groups represent optional properties, they are commonly dependent upon other options.
Global Tag (TG)
Similar in structure to the module tag group, these groups are common to multiple modules. The tables used to define and use them are:
- tags
- tag_groups
- taggable (polymorphic pivot)
TIP
Deciding on group types should be given due thought and involve user input. Any Open Dig Reports website can be used as an example.
Categorized Groups (CG)
These groups are used to design bespoke filters that may be dependent upon the complete record. For example, we may want to define a “Registration Scope” group with [Basket, Artifact] options, dependent on the condition artifact_no === 0 (A zero artifact_no means that the "Registration Scope" is "Basket").
In the back end we will implement the specific filter logic:
namespace App\Services\App\Module\Specific\Ceramic;
class CeramicReadDetails implements ReadDetailsInterface
{
private static Builder $builder;
public static function applyCategorizedFilters(Builder $builder, array $groups): Builder
{
self::$builder = $builder;
foreach ($groups as $key => $group) {
switch ($group['group_name']) {
case 'Registration Scope':
static::filterScope($group['selected']);
break;
default:
// Do nothing
}
}
return self::$builder;
}
private static function filterScope(array $vals)
{
if (count($vals) !== 1) {
return;
}
static::$builder->Where(function ($query) use ($vals) {
switch ($vals[0]['name']) {
case 'Basket':
$query->where('artifact_no', 0);
return;
case 'Artifact':
$query->Where('artifact_no', '!=', 0);
return;
default:
return;
}
});
}
}
The front end must define corresponding functionality:
export abstract class CeramicConfigs {
private static categorizerFuncs(fields?: TFields) {
const d = fields as TFields<'Ceramic'>
return {
'Registration Scope': d.artifact_no === 0 ? 0 : 1,
'Includes Date': d.date_retrieved === null ? 1 : 0,
}
}
Other filter groups are:
Field Search (FS)
These groups are used to perform simple textual searches on a specific field. Only OR operations between the different values are currently supported.
Order By (OB)
As the name suggests, these groups are used to order by specific columns or, in the case of a "compound" field, on a substring of the field.
Media (MD)
Filter by the existence of a related media type. Options correspond to the distinct values in the application-wide media.collection_name column.
The implementation of the different filters can be found here.