Appearance
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
- Field Definitions: Reusable field templates with types, validation, and default values
- Field Values: Actual data stored against assets
- Field Management: UI for creating, editing, and managing field definitions
- Asset Integration: Components for displaying and editing custom fields on assets
- 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
buildCustomFieldFilterfunction - Constructs custom field filter queries
- Integrates with search API
- Handles multiple field type filters
- Contains
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
- text - Single-line text input
- number - Numeric input with min/max validation
- date - Date picker
- select - Single selection dropdown
- multi_select - Multiple selection dropdown
- boolean - Checkbox (true/false)
- url - URL input with validation
- 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 matchnot_equals- Not equalcontains- 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 dialogApply 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 dialogSearch 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 filterBulk 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 listsComponent 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>Using Custom Fields in Search
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>Related Documentation
- Tags and Custom Fields System - Combined tags and custom fields overview
- Advanced Search Filters - Search filtering including custom fields
- Global Search Functionality - Search system integration
- Typesense Search Integration - Search backend integration