diff --git a/app/javascript/template_builder/area.vue b/app/javascript/template_builder/area.vue index df631ef04..8d53b67a5 100644 --- a/app/javascript/template_builder/area.vue +++ b/app/javascript/template_builder/area.vue @@ -362,7 +362,7 @@ export default { default: null } }, - emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to'], + emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to', 'field-clicked'], data () { return { isShowFormulaModal: false, @@ -823,6 +823,11 @@ export default { this.focusValueInput() } + // Emit field-clicked event if it was a simple click (not a drag) + if (!this.isMoved && this.editable) { + this.$emit('field-clicked', this.field) + } + this.isDragged = false this.isMoved = false diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index ee9958f08..be439d145 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -199,6 +199,7 @@ @draw="[onDraw($event), withSelectedFieldType ? '' : drawFieldType = '', showDrawField = false]" @drop-field="onDropfield" @remove-area="removeArea" + @field-clicked="scrollFieldIntoSidebar" /> s.uuid === field.submitter_uuid) + + // Switch to the correct submitter if needed + if (submitter && submitter !== this.selectedSubmitter) { + this.selectedSubmitter = submitter + } + + // Wait for submitter switch to complete + this.$nextTick(() => { + // Scroll field into view in sidebar (with null check for safety) + if (this.$refs.fields) { + this.$refs.fields.scrollFieldIntoView(field) + } + + // Highlight the field by setting the selected area + const area = field.areas?.[0] + if (area) { + this.selectedAreaRef.value = area + } + }) + }, baseFetch (path, options = {}) { return fetch(this.baseUrl + path, { ...options, diff --git a/app/javascript/template_builder/document.vue b/app/javascript/template_builder/document.vue index 7bba06c71..2c7592c75 100644 --- a/app/javascript/template_builder/document.vue +++ b/app/javascript/template_builder/document.vue @@ -24,6 +24,7 @@ @remove-area="$emit('remove-area', $event)" @scroll-to="scrollToArea" @draw="$emit('draw', { area: {...$event.area, attachment_uuid: document.uuid }, isTooSmall: $event.isTooSmall })" + @field-clicked="$emit('field-clicked', $event)" /> @@ -105,7 +106,7 @@ export default { default: false } }, - emits: ['draw', 'drop-field', 'remove-area'], + emits: ['draw', 'drop-field', 'remove-area', 'field-clicked'], data () { return { pageRefs: [] diff --git a/app/javascript/template_builder/fields.vue b/app/javascript/template_builder/fields.vue index 9a6efc0da..cfd21f613 100644 --- a/app/javascript/template_builder/fields.vue +++ b/app/javascript/template_builder/fields.vue @@ -323,6 +323,30 @@ export default { } }, methods: { + scrollFieldIntoView (field) { + // Wait for next tick to ensure DOM is updated + this.$nextTick(() => { + // Find the field element in the sidebar + const fieldElement = this.$refs.fields.querySelector(`[data-uuid="${field.uuid}"]`) + + if (fieldElement) { + // Scroll the field into view with smooth behavior and centered positioning + fieldElement.scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'nearest' + }) + + // Add temporary highlight class + fieldElement.classList.add('field-highlight') + + // Remove highlight after animation + setTimeout(() => { + fieldElement.classList.remove('field-highlight') + }, 2000) + } + }) + }, onDragstart (event, field) { this.removeDragOverlay(event) @@ -427,3 +451,20 @@ export default { } } + + diff --git a/app/javascript/template_builder/page.vue b/app/javascript/template_builder/page.vue index 3934f24bd..29e2ed4e2 100644 --- a/app/javascript/template_builder/page.vue +++ b/app/javascript/template_builder/page.vue @@ -33,6 +33,7 @@ @stop-resize="resizeDirection = null" @remove="$emit('remove-area', item.area)" @scroll-to="$emit('scroll-to', $event)" + @field-clicked="$emit('field-clicked', $event)" />