Skip to content

The Different Group Types

The Trio system utilizes a number of group types to implement different storage schemes.

Enum Fields (EM)

Enum fields are required/single selection. Possible options are restricted at DB level.

Lookup Value (LV)

This group's options are stored in lookup or related tables. Options are required/single. Lookup groups have a 'field_name' property which "connects" the item's field to the Lookup group. Related groups are used for registration and filtering. In this case, an item may not have a direct field which connects it to a table. In this case the 'filter_by_field_name' property indicates the filter_by criteria. Here are two examples of two groups defined in the back end:

php
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'],
            ],
            'Area' => [
                'code' => 'LV',
                // The next field must match the indexQuery definition e.g.:
                // $m->select('ceramics.id AS id')->join('areas', 'ceramics.area_id', '=', 'areas.id');
                'filter_by_field_name' => 'areas.id',
                'lookup_table_name' => 'areas',
                'lookup_text_field' => 'name',
            ]
        ];
    }
}

By convention, the first two values in lookup tables are 1: "Unassigned" and 2: "Unknown."

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.

Module Tag (TM)

These groups store their options in the external [module]_tags and [module]_groups tables (see ERD).

php
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:

php
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:

js
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:

Order By (OB)

As the name suggests, these groups are used to order by specific columns or, in the case of a composite 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.