Skip to content

Custom Fields

Overview

The Custom Fields System provides flexible metadata management for digital assets, allowing workspace administrators to define custom field definitions and apply them to assets. This system supports multiple data types, validation rules, search integration, and workspace-specific configurations. Custom fields enable organizations to extend asset metadata beyond standard properties to capture business-specific information.

Architecture

System Components

  1. Field Definitions: Reusable field templates with types, validation, and default values
  2. Field Values: Actual data stored against assets
  3. Field Management: UI for creating, editing, and managing field definitions
  4. Asset Integration: Components for displaying and editing custom fields on assets
  5. Search Integration: Custom field filtering and search capabilities

File Structure

Core Custom Field Components

Vue Component Files (.vue)

  • components/dam/CustomFieldItem/index.vue - Custom field item component

    • Displays individual custom field items
    • Handles field value rendering based on field type
    • Supports editing inline or via dialog
    • Field validation display
  • components/dam/AssetDetails/CustomFieldsSection.vue - Custom fields section in asset details

    • Displays all custom fields for an asset
    • Grouped field display
    • Edit/update functionality
    • Field value formatting based on type
  • components/dam/Dialogs/ManageCustomFields.vue - Dialog for managing custom fields on assets

    • Bulk custom field management
    • Add/remove custom fields from assets
    • Field value editing
    • Validation and error handling
  • components/dam/Dialogs/Org-Settings/CustomFieldDialog.vue - Dialog for creating/editing custom field definitions

    • Create new custom field definitions
    • Edit existing field definitions
    • Field type selection
    • Validation rule configuration
    • Default value setup

SVG Icon Components

  • components/svg/CollageCustomFieldsIcon.vue - Custom fields icon
    • Used in navigation and UI elements
    • Consistent iconography for custom fields

Custom Field Settings & Management

Vue Page Files (.vue)

  • pages/_workspace_id/workspace-settings/custom-fields/index.vue - Custom field manager page
    • Main settings page for custom field definitions
    • List all custom fields in workspace
    • Create, edit, delete field definitions
    • Field ordering and organization
    • Field usage statistics

Route: /:workspace_id/workspace-settings/custom-fields

Custom Field Display & Asset Integration

Vue Component Files (.vue)

  • pages/_workspace_id/dam/collage_id/index.vue - Collage page
    • Contains custom field update functionality
    • Custom field display in collage context
    • Field value updates for collage assets

Custom Field Search & Filtering

JavaScript Files (.js)

  • mixins/search-common-functions.js - Search common functions mixin
    • Contains buildCustomFieldFilter function
    • Constructs custom field filter queries
    • Integrates with search API
    • Handles multiple field type filters

Vue Component Files (.vue)

  • components/dam/Search/SearchFilter.vue - Search filter component

    • Includes custom field filters
    • Dynamic filter generation based on field definitions
    • Filter value input based on field type
    • Filter application and removal
  • components/dam/Search/ListLevelThree.vue - Search list level three

    • Includes custom field filter options
    • Nested filter display
    • Field-specific filter UI components
  • components/dam/Search/AddedFilterOption.vue - Added filter option component

    • Displays active custom field filters
    • Filter removal functionality
    • Filter value display
    • Filter editing

Custom Field Definition Structure

Field Definition Object

javascript
{
  id: 1,
  workspace_id: 123,
  name: "Project Name",
  field_key: "project_name",
  field_type: "text", // text, number, date, select, multi_select, boolean, url, email
  is_required: false,
  is_searchable: true,
  default_value: null,
  options: null, // For select/multi_select: [{value: "option1", label: "Option 1"}]
  display_order: 0,
  validation_rules: {
    min_length: null,
    max_length: 255,
    min_value: null,
    max_value: null,
    pattern: null
  },
  created_at: "2024-01-15T10:00:00Z",
  updated_at: "2024-01-20T14:30:00Z"
}

Field Value Object

javascript
{
  id: 1,
  asset_id: 456,
  field_definition_id: 1,
  field_value: "Summer Campaign 2024", // Value depends on field_type
  field_key: "project_name",
  created_at: "2024-01-15T10:00:00Z",
  updated_at: "2024-01-20T14:30:00Z"
}

Field Types

Supported Field Types

  1. text - Single-line text input
  2. number - Numeric input with min/max validation
  3. date - Date picker
  4. select - Single selection dropdown
  5. multi_select - Multiple selection dropdown
  6. boolean - Checkbox (true/false)
  7. url - URL input with validation
  8. email - Email input with validation

Component Implementation

Custom Field Item Component

File: components/dam/CustomFieldItem/index.vue

Displays and manages individual custom field items.

Props

javascript
{
  field: {
    type: Object,
    required: true
    // Field definition object
  },
  value: {
    type: [String, Number, Boolean, Array, Date],
    default: null
    // Current field value
  },
  editable: {
    type: Boolean,
    default: false
  },
  assetId: {
    type: [String, Number],
    default: null
  }
}

Methods

javascript
// Update field value
updateValue(newValue) {
  // Validate value based on field type
  // Emit update event
  // Call API to save
}

// Format value for display
formatValue(value, fieldType) {
  // Format based on field type
  // Return formatted string
}

// Validate value
validateValue(value) {
  // Check required
  // Check type-specific validation
  // Check validation rules
  // Return validation result
}

Usage

vue
<template>
  <CustomFieldItem
    :field="fieldDefinition"
    :value="fieldValue"
    :editable="true"
    :asset-id="assetId"
    @update="handleFieldUpdate"
  />
</template>

Custom Fields Section Component

File: components/dam/AssetDetails/CustomFieldsSection.vue

Displays all custom fields for an asset in the asset details view.

Features

  • Lists all custom fields for the asset
  • Groups fields by category (if applicable)
  • Displays field values with proper formatting
  • Edit functionality for each field
  • Add new custom fields to asset
  • Remove custom fields from asset

Props

javascript
{
  assetId: {
    type: [String, Number],
    required: true
  },
  customFields: {
    type: Array,
    default: () => []
    // Array of field definitions
  },
  fieldValues: {
    type: Object,
    default: () => {}
    // Object mapping field_key to value
  },
  editable: {
    type: Boolean,
    default: true
  }
}

Methods

javascript
// Load custom fields for asset
async loadCustomFields() {
  // Fetch field definitions
  // Fetch field values for asset
  // Merge and format data
}

// Update field value
async updateFieldValue(fieldKey, value) {
  // Validate value
  // Call API to update
  // Update local state
  // Show success/error message
}

// Add custom field to asset
async addCustomField(fieldDefinitionId) {
  // Call API to add field
  // Refresh field list
}

// Remove custom field from asset
async removeCustomField(fieldKey) {
  // Call API to remove
  // Update local state
}

Manage Custom Fields Dialog

File: components/dam/Dialogs/ManageCustomFields.vue

Dialog for managing custom fields on one or multiple assets.

Features

  • Bulk field management
  • Add/remove fields from assets
  • Edit field values
  • Field value validation
  • Multi-asset support

Props

javascript
{
  assetIds: {
    type: Array,
    required: true
    // Array of asset IDs
  },
  dialog: {
    type: Boolean,
    default: false
  }
}

Methods

javascript
// Load available custom fields
async loadAvailableFields() {
  // Fetch all field definitions for workspace
}

// Load current field values
async loadFieldValues() {
  // Fetch field values for selected assets
}

// Save field changes
async saveFields() {
  // Validate all fields
  // Call API to update
  // Handle success/error
}

Custom Field Dialog

File: components/dam/Dialogs/Org-Settings/CustomFieldDialog.vue

Dialog for creating and editing custom field definitions.

Features

  • Create new field definitions
  • Edit existing field definitions
  • Field type selection
  • Validation rule configuration
  • Default value setup
  • Options configuration for select fields

Props

javascript
{
  field: {
    type: Object,
    default: null
    // Field definition to edit (null for create)
  },
  dialog: {
    type: Boolean,
    default: false
  }
}

Data

javascript
data() {
  return {
    form: {
      name: '',
      field_key: '',
      field_type: 'text',
      is_required: false,
      is_searchable: true,
      default_value: null,
      options: [],
      validation_rules: {
        min_length: null,
        max_length: null,
        min_value: null,
        max_value: null,
        pattern: null
      }
    },
    fieldTypes: [
      { value: 'text', label: 'Text' },
      { value: 'number', label: 'Number' },
      { value: 'date', label: 'Date' },
      { value: 'select', label: 'Select' },
      { value: 'multi_select', label: 'Multi-Select' },
      { value: 'boolean', label: 'Boolean' },
      { value: 'url', label: 'URL' },
      { value: 'email', label: 'Email' }
    ]
  }
}

Methods

javascript
// Generate field key from name
generateFieldKey(name) {
  // Convert to snake_case
  // Remove special characters
  // Return field_key
}

// Validate form
validateForm() {
  // Check required fields
  // Validate field_key format
  // Validate field type specific rules
  // Return validation result
}

// Save field definition
async saveField() {
  // Validate form
  // If editing: PUT request
  // If creating: POST request
  // Handle success/error
}

Custom Field Settings Page

File: pages/_workspace_id/workspace-settings/custom-fields/index.vue

Route: /:workspace_id/workspace-settings/custom-fields

Main page for managing custom field definitions in workspace settings.

Features

  • List all custom field definitions
  • Create new field definitions
  • Edit existing field definitions
  • Delete field definitions
  • Reorder fields (display_order)
  • View field usage statistics
  • Field type filtering

Page Structure

vue
<template>
  <div class="custom-fields-settings">
    <v-card>
      <v-card-title>
        Custom Fields
        <v-spacer />
        <v-btn color="primary" @click="openCreateDialog">
          <AddIcon /> Add Custom Field
        </v-btn>
      </v-card-title>
      
      <v-card-text>
        <!-- Field list -->
        <v-list>
          <v-list-item
            v-for="field in customFields"
            :key="field.id"
          >
            <v-list-item-content>
              <v-list-item-title>{{ field.name }}</v-list-item-title>
              <v-list-item-subtitle>
                Type: {{ field.field_type }} |
                Key: {{ field.field_key }} |
                {{ field.is_required ? 'Required' : 'Optional' }}
              </v-list-item-subtitle>
            </v-list-item-content>
            <v-list-item-action>
              <v-btn icon @click="editField(field)">
                <EditIcon />
              </v-btn>
              <v-btn icon @click="deleteField(field)">
                <DeleteIcon />
              </v-btn>
            </v-list-item-action>
          </v-list-item>
        </v-list>
      </v-card-text>
    </v-card>
    
    <!-- Create/Edit Dialog -->
    <CustomFieldDialog
      :dialog="dialogOpen"
      :field="selectedField"
      @close="closeDialog"
      @save="handleSave"
    />
  </div>
</template>

Search Integration

Custom Field Filtering

File: mixins/search-common-functions.js

The buildCustomFieldFilter function constructs filter queries for custom fields.

Function Signature

javascript
buildCustomFieldFilter(fieldKey, fieldType, value, operator = 'equals') {
  // Build filter object based on field type
  // Return filter query object
}

Supported Operators

  • equals - Exact match
  • not_equals - Not equal
  • contains - Contains text (for text fields)
  • greater_than - Greater than (for numbers/dates)
  • less_than - Less than (for numbers/dates)
  • in - In array (for select/multi_select)
  • not_in - Not in array

Usage

javascript
// In search component
import searchCommonFunctions from '~/mixins/search-common-functions'

export default {
  mixins: [searchCommonFunctions],
  methods: {
    applyCustomFieldFilter(field, value) {
      const filter = this.buildCustomFieldFilter(
        field.field_key,
        field.field_type,
        value,
        'equals'
      )
      this.addFilter(filter)
    }
  }
}

Search Filter Component

File: components/dam/Search/SearchFilter.vue

Includes custom field filters in the search interface.

Features

  • Dynamic custom field filter generation
  • Field type-specific input components
  • Filter value validation
  • Filter application and removal
  • Multiple field filter support

Added Filter Option Component

File: components/dam/Search/AddedFilterOption.vue

Displays active custom field filters.

Features

  • Shows active custom field filters
  • Filter value display with formatting
  • Remove filter functionality
  • Edit filter value

API Integration

API Endpoints

List Custom Fields

Endpoint: GET /digital-assets/custom-field/list

Query Parameters:

  • workspace_id (required) - Workspace identifier

Response:

json
{
  "fields": [
    {
      "id": 1,
      "workspace_id": 123,
      "name": "Project Name",
      "field_key": "project_name",
      "field_type": "text",
      "is_required": false,
      "is_searchable": true,
      "default_value": null,
      "options": null,
      "display_order": 0
    }
  ]
}

Add Custom Field

Endpoint: POST /digital-assets/custom-field/add

Request Body:

json
{
  "workspace_id": 123,
  "name": "Project Name",
  "field_key": "project_name",
  "field_type": "text",
  "is_required": false,
  "is_searchable": true,
  "default_value": null,
  "options": null,
  "validation_rules": {
    "max_length": 255
  }
}

Response:

json
{
  "field": {
    "id": 1,
    "workspace_id": 123,
    "name": "Project Name",
    "field_key": "project_name",
    "field_type": "text",
    "is_required": false,
    "is_searchable": true,
    "default_value": null,
    "options": null,
    "display_order": 0,
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Update Custom Field

Endpoint: PUT /digital-assets/custom-field/update

Request Body:

json
{
  "id": 1,
  "name": "Updated Project Name",
  "field_type": "text",
  "is_required": true,
  "validation_rules": {
    "max_length": 500
  }
}

Response:

json
{
  "field": {
    "id": 1,
    "name": "Updated Project Name",
    "updated_at": "2024-01-20T14:30:00Z"
  }
}

Update Field with Field Data

Endpoint: PUT /digital-assets/custom-field/update-with-field

Request Body:

json
{
  "id": 1,
  "field": {
    "name": "Project Name",
    "field_type": "text",
    "is_required": false,
    "validation_rules": {}
  }
}

Delete Custom Field

Endpoint: DELETE /digital-assets/custom-field/delete

Query Parameters:

  • id (required) - Field definition ID

Response:

json
{
  "success": true,
  "message": "Custom field deleted successfully"
}

Manage Custom Fields for Assets

Endpoint: POST /digital-assets/manage-custom-fields

Request Body:

json
{
  "asset_ids": [456, 457, 458],
  "field_values": {
    "project_name": "Summer Campaign 2024",
    "campaign_type": "marketing"
  },
  "remove_fields": ["old_field_key"]
}

Response:

json
{
  "success": true,
  "updated_assets": 3
}

Update Custom Fields for Assets

Endpoint: POST /digital-assets/update-custom-fields

Request Body:

json
{
  "asset_id": 456,
  "field_values": {
    "project_name": "Summer Campaign 2024",
    "campaign_type": "marketing",
    "budget": 50000
  }
}

Response:

json
{
  "success": true,
  "asset": {
    "id": 456,
    "custom_fields": {
      "project_name": "Summer Campaign 2024",
      "campaign_type": "marketing",
      "budget": 50000
    }
  }
}

Workflows

Create Custom Field Definition

1. Navigate to workspace settings
   Route: /:workspace_id/workspace-settings/custom-fields

2. Click "Add Custom Field"
   Component: CustomFieldDialog.vue opens

3. Fill field definition form
   - Enter field name
   - Field key auto-generated (or manual)
   - Select field type
   - Configure validation rules
   - Set default value (optional)
   - Configure options (for select fields)

4. Validate form
   - Check required fields
   - Validate field_key format
   - Validate field type specific rules

5. Submit form
   API: POST /digital-assets/custom-field/add

6. Field created
   - Field added to workspace
   - Available for use on assets
   - Appears in field list

7. Update UI
   - Refresh field list
   - Show success message
   - Close dialog

Apply Custom Field to Asset

1. Navigate to asset details
   Route: /:workspace_id/dam/assets/:asset_id

2. Open Custom Fields section
   Component: CustomFieldsSection.vue

3. Click "Add Custom Field" or "Manage Fields"
   Dialog: ManageCustomFields.vue opens

4. Select field definition
   - Choose from available fields
   - Or create new field definition

5. Enter field value
   - Input based on field type
   - Validate value

6. Save field value
   API: POST /digital-assets/update-custom-fields
   Body: { asset_id, field_values: { field_key: value } }

7. Field applied
   - Field value saved
   - Displayed in asset details
   - Available for search/filtering

8. Update UI
   - Refresh custom fields section
   - Show success message
   - Close dialog

Search with Custom Field Filter

1. Navigate to search page
   Route: /:workspace_id/dam/search

2. Open search filters
   Component: SearchFilter.vue

3. Select custom field filter
   - Choose field from list
   - Field type determines input component

4. Enter filter value
   - Text: text input
   - Number: number input with min/max
   - Date: date picker
   - Select: dropdown
   - Boolean: checkbox

5. Apply filter
   Mixin: buildCustomFieldFilter()
   - Constructs filter query
   - Adds to search filters

6. Execute search
   API: Search with custom field filter
   - Filter applied to search query
   - Results filtered by custom field

7. Display results
   - Assets matching custom field filter
   - Filter shown in AddedFilterOption component
   - Can remove or edit filter

Bulk Update Custom Fields

1. Select multiple assets
   - Use multi-select in asset list
   - Or select from search results

2. Open "Manage Custom Fields"
   Dialog: ManageCustomFields.vue
   Props: assetIds: [456, 457, 458]

3. Load available fields
   API: GET /digital-assets/custom-field/list

4. Load current field values
   API: GET /digital-assets/asset-custom-fields
   Query: asset_ids=[456,457,458]

5. Edit field values
   - Update values for selected assets
   - Add new fields
   - Remove fields

6. Validate all fields
   - Check required fields
   - Validate field types
   - Check validation rules

7. Save changes
   API: POST /digital-assets/manage-custom-fields
   Body: { asset_ids, field_values, remove_fields }

8. Update complete
   - All selected assets updated
   - Show success message
   - Refresh asset lists

Component Integration

Using Custom Fields in Asset Details

vue
<template>
  <div>
    <!-- Custom Fields Section -->
    <CustomFieldsSection
      :asset-id="assetId"
      :custom-fields="customFields"
      :field-values="fieldValues"
      :editable="canEdit"
      @field-updated="handleFieldUpdate"
    />
  </div>
</template>

<script>
import CustomFieldsSection from '~/components/dam/AssetDetails/CustomFieldsSection.vue'

export default {
  components: {
    CustomFieldsSection
  },
  data() {
    return {
      assetId: this.$route.params.asset_id,
      customFields: [],
      fieldValues: {}
    }
  },
  async mounted() {
    await this.loadCustomFields()
    await this.loadFieldValues()
  },
  methods: {
    async loadCustomFields() {
      const response = await this.$axios.get('/digital-assets/custom-field/list', {
        params: { workspace_id: this.workspaceId }
      })
      this.customFields = response.data.fields
    },
    async loadFieldValues() {
      const response = await this.$axios.get(`/digital-assets/${this.assetId}/custom-fields`)
      this.fieldValues = response.data.field_values
    },
    handleFieldUpdate(fieldKey, value) {
      this.fieldValues[fieldKey] = value
    }
  }
}
</script>
vue
<template>
  <div>
    <SearchFilter
      :custom-fields="customFields"
      @filter-applied="applyFilter"
    />
    
    <AddedFilterOption
      v-for="filter in activeFilters"
      :key="filter.id"
      :filter="filter"
      @remove="removeFilter"
    />
  </div>
</template>

<script>
import SearchFilter from '~/components/dam/Search/SearchFilter.vue'
import AddedFilterOption from '~/components/dam/Search/AddedFilterOption.vue'
import searchCommonFunctions from '~/mixins/search-common-functions'

export default {
  components: {
    SearchFilter,
    AddedFilterOption
  },
  mixins: [searchCommonFunctions],
  data() {
    return {
      customFields: [],
      activeFilters: []
    }
  },
  methods: {
    applyFilter(field, value) {
      const filter = this.buildCustomFieldFilter(
        field.field_key,
        field.field_type,
        value
      )
      this.activeFilters.push(filter)
      this.executeSearch()
    },
    removeFilter(filterId) {
      this.activeFilters = this.activeFilters.filter(f => f.id !== filterId)
      this.executeSearch()
    }
  }
}
</script>