multi select context menu readonly and required

pull/698/merge
Pete Matsyburka 3 weeks ago
parent 61fc24d35d
commit c8e783a210

@ -319,7 +319,7 @@ export default {
default: false default: false
} }
}, },
emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to', 'add-custom-field', 'click-title'], emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to', 'add-custom-field', 'click-title', 'multi-select'],
data () { data () {
return { return {
isContenteditable: false, isContenteditable: false,
@ -798,6 +798,8 @@ export default {
this.selectedAreasRef.value.splice(this.selectedAreasRef.value.indexOf(this.area), 1) this.selectedAreasRef.value.splice(this.selectedAreasRef.value.indexOf(this.area), 1)
} }
this.$emit('multi-select', e)
return return
} }

@ -57,6 +57,7 @@
@scroll-to="$emit('scroll-to', $event)" @scroll-to="$emit('scroll-to', $event)"
@add-custom-field="$emit('add-custom-field', $event)" @add-custom-field="$emit('add-custom-field', $event)"
@contextmenu="openAreaContextMenu($event, item.area, item.field)" @contextmenu="openAreaContextMenu($event, item.area, item.field)"
@multi-select="openMultiSelectContextMenu"
@click-title="closeContextMenu" @click-title="closeContextMenu"
/> />
<FieldArea <FieldArea
@ -408,6 +409,12 @@ export default {
return return
} }
if (this.selectedAreasRef.value.length >= 2) {
this.openSelectionContextMenu(event)
return
}
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -443,6 +450,13 @@ export default {
areas: this.selectedAreasRef.value areas: this.selectedAreasRef.value
} }
}, },
openMultiSelectContextMenu (event) {
if (this.selectedAreasRef.value.length >= 2) {
this.openSelectionContextMenu(event)
} else {
this.closeContextMenu()
}
},
handleSelectionCopy () { handleSelectionCopy () {
this.$emit('copy-selected-areas') this.$emit('copy-selected-areas')

@ -9,6 +9,62 @@
@mousedown.stop @mousedown.stop
@pointerdown.stop @pointerdown.stop
> >
<label
v-if="requiredFields.length"
class="field-settings-required w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm cursor-pointer"
@click.stop
>
<input
:checked="isAllRequired"
:indeterminate="isMixedRequired"
type="checkbox"
class="toggle toggle-xs"
:disabled="!editable"
@change="handleToggleRequired($event.target.checked)"
@click.stop
>
<span>{{ t('required') }}</span>
</label>
<label
v-if="readOnlyFields.length"
class="field-settings-read-only w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm cursor-pointer"
@click.stop
>
<input
:checked="isAllReadOnly"
:indeterminate="isMixedReadOnly"
type="checkbox"
class="toggle toggle-xs"
:disabled="!editable"
@change="handleToggleReadOnly($event.target.checked)"
@click.stop
>
<span>{{ t('read_only') }}</span>
</label>
<hr
v-if="requiredFields.length || readOnlyFields.length"
class="my-1 border-neutral-200"
>
<button
v-if="showFont"
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
@click.stop="openFontModal"
>
<IconTypography class="w-4 h-4" />
<span>{{ t('font') }}</span>
</button>
<button
v-if="showCondition"
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
@click.stop="openConditionModal"
>
<IconRouteAltLeft class="w-4 h-4" />
<span>{{ t('condition') }}</span>
</button>
<hr
v-if="showFont || showCondition"
class="my-1 border-neutral-200"
>
<ContextSubmenu <ContextSubmenu
:icon="IconLayoutAlignMiddle" :icon="IconLayoutAlignMiddle"
:label="t('align')" :label="t('align')"
@ -61,26 +117,6 @@
<span>{{ t('height') }}</span> <span>{{ t('height') }}</span>
</button> </button>
</ContextSubmenu> </ContextSubmenu>
<hr
v-if="showFont || showCondition"
class="my-1 border-neutral-200"
>
<button
v-if="showFont"
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
@click.stop="openFontModal"
>
<IconTypography class="w-4 h-4" />
<span>{{ t('font') }}</span>
</button>
<button
v-if="showCondition"
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center space-x-2 text-sm"
@click.stop="openConditionModal"
>
<IconRouteAltLeft class="w-4 h-4" />
<span>{{ t('condition') }}</span>
</button>
<hr class="my-1 border-neutral-200"> <hr class="my-1 border-neutral-200">
<button <button
class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center justify-between text-sm" class="w-full px-2 py-1 rounded-md hover:bg-neutral-100 flex items-center justify-between text-sm"
@ -192,6 +228,24 @@ export default {
return this.template.fields.find((f) => f.areas?.includes(area)) return this.template.fields.find((f) => f.areas?.includes(area))
}).filter(Boolean) }).filter(Boolean)
}, },
requiredFields () {
return this.selectedFields.filter((f) => !['phone', 'stamp', 'verification', 'strikethrough', 'heading'].includes(f.type))
},
readOnlyFields () {
return this.selectedFields.filter((f) => ['text', 'number', 'radio', 'multiple', 'select'].includes(f.type))
},
isAllRequired () {
return this.requiredFields.every((f) => f.required)
},
isMixedRequired () {
return !this.isAllRequired && this.requiredFields.some((f) => f.required)
},
isAllReadOnly () {
return this.readOnlyFields.every((f) => f.readonly)
},
isMixedReadOnly () {
return !this.isAllReadOnly && this.readOnlyFields.some((f) => f.readonly)
},
isMac () { isMac () {
return (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase()?.includes('mac') return (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase()?.includes('mac')
}, },
@ -234,6 +288,16 @@ export default {
} }
} }
}, },
handleToggleRequired (value) {
this.requiredFields.forEach((field) => { field.required = value })
this.save()
},
handleToggleReadOnly (value) {
this.readOnlyFields.forEach((field) => { field.readonly = value })
this.save()
},
onKeyDown (event) { onKeyDown (event) {
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.preventDefault() event.preventDefault()

Loading…
Cancel
Save