mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-11 16:24:11 +01:00
People: Adjust menuProps and add focus trap to PConfirmDialog #5307
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -2,24 +2,28 @@
|
||||
<v-dialog
|
||||
ref="dialog"
|
||||
:model-value="visible"
|
||||
:close-delay="0"
|
||||
:open-delay="0"
|
||||
persistent
|
||||
scrim
|
||||
max-width="360"
|
||||
class="p-dialog p-confirm-dialog"
|
||||
retain-focus
|
||||
@keydown.esc.exact.stop.prevent="close"
|
||||
@keydown.enter.exact.stop.prevent="confirm"
|
||||
@keyup.esc.exact="close"
|
||||
@keyup.enter.exact="confirm"
|
||||
@after-enter="afterEnter"
|
||||
@after-leave="afterLeave"
|
||||
@focusout="onFocusOut"
|
||||
>
|
||||
<v-card ref="content" tabindex="1">
|
||||
<v-card ref="content" tabindex="0">
|
||||
<v-card-title class="d-flex justify-start align-center ga-3">
|
||||
<v-icon :icon="icon" :size="iconSize" color="primary"></v-icon>
|
||||
<div class="text-subtitle-1">{{ text ? text : $gettext(`Are you sure?`) }}</div>
|
||||
</v-card-title>
|
||||
<v-card-actions class="action-buttons">
|
||||
<v-btn variant="flat" color="button" class="action-cancel action-close" @click.stop="close">
|
||||
<v-btn variant="flat" tabindex="0" color="button" class="action-cancel action-close" @click.stop="close">
|
||||
{{ $gettext(`Cancel`) }}
|
||||
</v-btn>
|
||||
<v-btn color="highlight" variant="flat" class="action-confirm" @click.stop="confirm">
|
||||
<v-btn color="highlight" tabindex="0" variant="flat" class="action-confirm" @click.stop="confirm">
|
||||
{{ action ? action : $gettext(`Yes`) }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -55,18 +59,31 @@ export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {
|
||||
visible(show) {
|
||||
if (show) {
|
||||
this.$nextTick(() => this.$view.enter(this, this.$refs?.content, ".action-confirm"));
|
||||
} else {
|
||||
this.$view.leave(this);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
afterEnter() {
|
||||
this.$nextTick(() => this.$view.enter(this, this.$refs?.content, ".action-confirm"));
|
||||
this.$view.enter(this);
|
||||
},
|
||||
afterLeave() {
|
||||
this.$view.leave(this);
|
||||
},
|
||||
onFocusOut(ev) {
|
||||
if (!this.$view.isActive(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const el = this.$refs.content?.$el;
|
||||
|
||||
if (!ev || !ev.target || !(ev.target instanceof HTMLElement) || !(el instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const next = ev.relatedTarget;
|
||||
const leavingDialog = !next || !(next instanceof Node) || !el.contains(next);
|
||||
|
||||
if (leavingDialog) {
|
||||
el.focus();
|
||||
ev.preventDefault();
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$emit("close");
|
||||
|
||||
@@ -79,10 +79,9 @@
|
||||
item-title="Name"
|
||||
item-value="Name"
|
||||
:disabled="busy"
|
||||
:menu-props="menuProps"
|
||||
return-object
|
||||
hide-no-data
|
||||
:menu-props="menuProps"
|
||||
:menu="openMenuId === m.UID"
|
||||
hide-details
|
||||
single-line
|
||||
open-on-clear
|
||||
@@ -90,15 +89,9 @@
|
||||
prepend-inner-icon="mdi-account-plus"
|
||||
density="comfortable"
|
||||
class="input-name pa-0 ma-0 text-selectable"
|
||||
@blur="
|
||||
() => {
|
||||
onSetName(m, 'blur');
|
||||
onUpdateMenu(m, false);
|
||||
}
|
||||
"
|
||||
@update:menu="(val) => onUpdateMenu(m, val)"
|
||||
@update:model-value="(person) => onSetPerson(m, person)"
|
||||
@keyup.enter="onSetName(m, 'enter')"
|
||||
@blur="(ev) => onSetName(m, ev)"
|
||||
@keyup.enter="(ev) => onSetName(m, ev)"
|
||||
>
|
||||
</v-combobox>
|
||||
</v-card-actions>
|
||||
@@ -147,9 +140,15 @@ export default {
|
||||
text: this.$gettext("Add person?"),
|
||||
},
|
||||
menuProps: {
|
||||
closeOnClick: false,
|
||||
closeOnContentClick: true,
|
||||
openOnClick: true,
|
||||
openOnFocus: true,
|
||||
closeOnBack: true,
|
||||
closeOnContentClick: true,
|
||||
persistent: false,
|
||||
scrim: true,
|
||||
openDelay: 0,
|
||||
closeDelay: 0,
|
||||
opacity: 0,
|
||||
density: "compact",
|
||||
maxHeight: 300,
|
||||
scrollStrategy: "reposition",
|
||||
@@ -161,7 +160,6 @@ export default {
|
||||
|
||||
return v.length <= this.$config.get("clip") || this.$gettext("Name too long");
|
||||
},
|
||||
openMenuId: "",
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -331,7 +329,7 @@ export default {
|
||||
|
||||
return true;
|
||||
},
|
||||
onSetName(model, trigger) {
|
||||
onSetName(model, ev) {
|
||||
if (this.busy || !model) {
|
||||
return;
|
||||
}
|
||||
@@ -366,7 +364,8 @@ export default {
|
||||
|
||||
model.Name = name;
|
||||
model.SubjUID = "";
|
||||
if (trigger === "enter") {
|
||||
|
||||
if (ev && ev.key === "Enter" && !ev.isComposing && !ev.repeat) {
|
||||
this.setName(model);
|
||||
} else {
|
||||
this.confirm.visible = true;
|
||||
@@ -385,19 +384,6 @@ export default {
|
||||
this.confirm.model.SubjUID = "";
|
||||
}
|
||||
this.confirm.visible = false;
|
||||
this.openMenuId = "";
|
||||
},
|
||||
getModelKey(model) {
|
||||
return model?.UID || model?.ID || "";
|
||||
},
|
||||
onUpdateMenu(model, open) {
|
||||
const key = this.getModelKey(model);
|
||||
if (!key) return;
|
||||
if (open) {
|
||||
this.openMenuId = key;
|
||||
} else if (this.openMenuId === key) {
|
||||
this.openMenuId = "";
|
||||
}
|
||||
},
|
||||
setName(model) {
|
||||
if (this.busy || !model) {
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
single-line
|
||||
density="comfortable"
|
||||
class="input-name pa-0 ma-0"
|
||||
@blur="onSetName(m, 'blur')"
|
||||
@keyup.enter="onSetName(m, 'enter')"
|
||||
@blur="(ev) => onSetName(m, ev)"
|
||||
@keyup.enter="(ev) => onSetName(m, ev)"
|
||||
></v-text-field>
|
||||
<v-combobox
|
||||
v-else
|
||||
@@ -95,10 +95,9 @@
|
||||
item-title="Name"
|
||||
item-value="Name"
|
||||
:readonly="readonly"
|
||||
:menu-props="menuProps"
|
||||
return-object
|
||||
hide-no-data
|
||||
:menu-props="menuProps"
|
||||
:menu="openMenuId === m.ID"
|
||||
hide-details
|
||||
single-line
|
||||
open-on-clear
|
||||
@@ -107,15 +106,9 @@
|
||||
autocomplete="off"
|
||||
density="comfortable"
|
||||
class="input-name pa-0 ma-0 text-selectable"
|
||||
@blur="
|
||||
() => {
|
||||
onSetName(m, 'blur');
|
||||
onUpdateMenu(m, false);
|
||||
}
|
||||
"
|
||||
@update:menu="(val) => onUpdateMenu(m, val)"
|
||||
@update:model-value="(person) => onSetPerson(m, person)"
|
||||
@keyup.enter="onSetName(m, 'enter')"
|
||||
@blur="(ev) => onSetName(m, ev)"
|
||||
@keyup.enter="(ev) => onSetName(m, ev)"
|
||||
>
|
||||
</v-combobox>
|
||||
</v-card-actions>
|
||||
@@ -201,9 +194,15 @@ export default {
|
||||
text: this.$gettext("Add person?"),
|
||||
},
|
||||
menuProps: {
|
||||
closeOnClick: false,
|
||||
closeOnContentClick: true,
|
||||
openOnClick: true,
|
||||
openOnFocus: true,
|
||||
closeOnBack: true,
|
||||
closeOnContentClick: true,
|
||||
persistent: false,
|
||||
scrim: true,
|
||||
openDelay: 0,
|
||||
closeDelay: 0,
|
||||
opacity: 0,
|
||||
density: "compact",
|
||||
maxHeight: 300,
|
||||
scrollStrategy: "reposition",
|
||||
@@ -215,7 +214,6 @@ export default {
|
||||
|
||||
return v.length <= this.$config.get("clip") || this.$gettext("Text too long");
|
||||
},
|
||||
openMenuId: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -653,7 +651,7 @@ export default {
|
||||
|
||||
return true;
|
||||
},
|
||||
onSetName(model, trigger) {
|
||||
onSetName(model, ev) {
|
||||
if (this.busy || !model) {
|
||||
return;
|
||||
}
|
||||
@@ -690,7 +688,7 @@ export default {
|
||||
model.SubjUID = "";
|
||||
|
||||
if (model.Name) {
|
||||
if (trigger === "enter") {
|
||||
if (ev && ev.key === "Enter" && !ev.isComposing && !ev.repeat) {
|
||||
this.setName(model, model.Name);
|
||||
} else {
|
||||
this.confirm.visible = true;
|
||||
@@ -715,19 +713,6 @@ export default {
|
||||
this.confirm.model.SubjUID = "";
|
||||
}
|
||||
this.confirm.visible = false;
|
||||
this.openMenuId = "";
|
||||
},
|
||||
getModelKey(model) {
|
||||
return model?.ID || model?.UID || "";
|
||||
},
|
||||
onUpdateMenu(model, open) {
|
||||
const key = this.getModelKey(model);
|
||||
if (!key) return;
|
||||
if (open) {
|
||||
this.openMenuId = key;
|
||||
} else if (this.openMenuId === key) {
|
||||
this.openMenuId = "";
|
||||
}
|
||||
},
|
||||
setName(model, newName) {
|
||||
if (this.busy || !model || !newName || newName.trim() === "") {
|
||||
|
||||
Reference in New Issue
Block a user