Event Editor Inline Editable Section
A self-contained inline-editable section that handles:
- Displaying data
- Switching between read mode ↔ edit mode
- Inline validation
- Local form state & syncing with parent via v-model
- Calling an API to save changes
The below example uses Basics for the data
Overview of Uranus Inline Edit Component Structure and Responsibilities
| Layer | Purpose |
|---|---|
UranusInlineEditSection |
Provides “editable section” layout and styling |
UranusInlineEditLabel |
Shows label and edit button |
isEditing |
Controls edit/read switching |
local reactive object |
Source of truth while editing |
watch() modelValue → local |
Parent changes update local |
watch()local → parent` |
Two-way binding updates parent |
Computed nameError |
Local inline validation for each data item which need error indication |
save() |
Sends data to server and emits update |
UranusInlineActionBar |
Save and Cancel UX controls |
1. Template: UI Structure & Render Logic
Top-Level Layout
- Provides the “editing frame” (borders, background, etc.)
- Receives the active flag → determines whether edit mode styling is active
Inline Edit Label
<UranusInlineEditLabel
:label-text="t('label')"
:edit-button-text="t('edit')"
@edit-started="startEditing" />
Responsibilities:
- Shows a label for the inline section
- Shows an “Edit” button
- Emits edit-started to trigger edit mode
Edit Mode Content
<UranusInlineSectionLayout> only renders when editing:
<UranusInlineSectionLayout v-if="isEditing">
<UranusTextInput ... />
<UranusTextInput ... />
<UranusInlineActionBar>...</UranusInlineActionBar>
</UranusInlineSectionLayout>
Responsibilities:
- Provides a layout container for editable fields
- Action bar with Save / Cancel buttons
Read Mode Content
Responsibilities:
- Displays the values without editing controls
- Fully decoupled from edit mode
2. Script: Logic & State Management
Props
Responsibilities:
modelValue: receives event basics data from parentnameError: optional external validation error (server or parent UI)
Emit
const emit = defineEmits<{
(e: 'update:modelValue', v: Basics | null): void
(e: 'updated'): void
}>()
Responsibilities:
update:modelValue→ two-way bindingupdated→ tells parent to reload data or show success indicator
Local Editable Copy
const local = reactive<Basics>({
id: props.modelValue?.id,
prop_a: props.modelValue?.prop_a ?? '',
prop_b: props.modelValue?.prop_b ?? null,
})
Responsibilities:
- Keeps all editing state local
- Independent from props.modelValue so cancel is possible
- Ensures form is always non-null, safe to edit
Sync: Parent → Local
Responsibilities:
- Updates local state when parent modifies model
- Keeps the component reactive to external changes
Sync: Local → Parent
Responsibilities:
- Emits partial updates to parent
- Keeps external state updated in real-time
3. Editing State
Responsibilities:
- isEditing toggles between edit + read view
- isSaving shows busy state to UX components
Start Editing
Cancel Editing
Both are consumed by <UranusInlineEditLabel> and the action bar.
4. Save Logic
async function save() {
if (!props.modelValue?.id) return console.error('No event ID available')
isSaving.value = true
try {
await apiFetch(`/api/admin/event/${props.modelValue.id}/header`, {
method: 'PUT',
body: JSON.stringify({
prop_a: local.prop_a.trim(),
prop_b: (local.prop_b ?? '').trim() || null,
}),
})
isEditing.value = false
emit('updated')
} catch (err) {
console.error('Failed to update header', err)
} finally {
isSaving.value = false
}
}
Responsibilities:
- Validates existence of event ID
- Sends a PUT request with the properties
- Updates external state via emit('updated')
- Closes edit mode
- Prevents double submits via isSaving
5. Validation Logic
const propAError = computed(() => {
if (props.titleError) return props.propAError
if (!local.prop_a || local.prop_a.trim() === "")
return t('empty_input_field_message')
return ""
})
Responsibilities:
- Combines internal + external validation
- Ensures empty titles cannot be saved
- Supplies error text to
<UranusTextInput>
6. Styling
Responsibilities:
- Minor layout adjustments for readability