-
Notifications
You must be signed in to change notification settings - Fork 584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get rid of the double modals stack #4536
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just questions for now.
@@ -17,6 +17,10 @@ | |||
<script> | |||
import cuid from 'cuid'; | |||
import AposThemeMixin from 'Modules/@apostrophecms/ui/mixins/AposThemeMixin'; | |||
import { useModalStore } from 'Modules/@apostrophecms/ui/stores/modal'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much value is a new dependency on Pinia bringing? apos.modal.modals
has been visible in the code as a property other modules might try to look at for a while now - can we maintain that interface to reduce backwards compatibility issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apos.modal.modals
comes from the backend and is static data so we have no reason to put it does not move.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh right, never mind.
373b970
to
c4b3e17
Compare
@@ -6,131 +6,72 @@ | |||
<component | |||
v-bind="modal.props" | |||
:is="modal.componentName" | |||
v-for="modal in stack" | |||
v-for="modal in store.stack" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting the stack from the store, dynamic.
if (!elementsToFocus.value.length) { | ||
function cycleElementsToFocus(e, elements) { | ||
const elems = elements || elementsToFocus.value; | ||
if (!elems.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The power of the composable, modals want to pass elements because they come from the store. But in AposButtonSplit
it simply uses the provided elementsToFocus
from this composable.
}); | ||
} | ||
|
||
// Returns true if el1 is "on top of" el2 in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function is never used..
modals use the overlay click event to close themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at AposTiptapAnchor.vue
:
v-click-outside-element="close"
This is used to edit links in rich text. Needs to keep working, so click-outside-element.js
still needs to work, but could be factored to use the store.
30659c0
to
87a9bbb
Compare
@@ -6,7 +6,6 @@ | |||
@inactive="modal.active = false" | |||
@show-modal="modal.showModal = true" | |||
@esc="close" | |||
@no-modal="$emit('safe-close')" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been removed because people using modals forget to call it.
The safe-close event is emitting in AposModal
when it closes.
I kept the event no-modal
to avoid BC.
const modal = apos.modal.getAt(index); | ||
const properties = apos.modal.getProperties(modal.id); | ||
const modal = this.getAt(index); | ||
const properties = this.getProperties(modal.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would still work using apos.modal but more idiomatic way to use store.
// similar functionality. This is necessary because | ||
// sometimes Vue removes elements from the DOM before | ||
// we can examine their relationships. | ||
function onTopOf(el1, el2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method moved in store. Not sure it's used anymore since we use the overlay click to close a modal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See click-outside-element.js
. Make sure that functionality does not break with this change.
apos.modal.getProperties = modalStore.getProperties; | ||
apos.modal.onTopOf = modalStore.onTopOf; | ||
apos.confirm = modalStore.confirm; | ||
apos.alert = modalStore.alert; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We attach methods from the store. it's working well for function (can be used out of vue).
It's not for computed and refs. (That why I added the get function that allow to get all modals or one by ID).
} | ||
store.updateModalData(props.modalId, { modalEl: modalEl.value }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating instantiated Modal in the store (from TheAposModals
) with data only available in this component. Allows to have only one array of modals.
|
||
function onTab(e) { | ||
const currentModal = store.get(props.modalId); | ||
cycleElementsToFocus(e, currentModal.elementsToFocus); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only triggered on tab.
@@ -258,21 +264,24 @@ function trapFocus() { | |||
.map(addExcludingAttributes) | |||
.join(', '); | |||
|
|||
elementsToFocus.value = [ ...modalEl.value.querySelectorAll(selector) ] | |||
const elementsToFocus = [ ...modalEl.value.querySelectorAll(selector) ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now store them in the modal in the store directly.
const properties = { | ||
...this.modals | ||
.find(modal => modal.componentName === stackModal.componentName && | ||
modal.props.moduleName === stackModal.props.moduleName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic moved in the store.
@@ -6,7 +6,6 @@ | |||
@inactive="modal.active = false" | |||
@show-modal="modal.showModal = true" | |||
@esc="confirmAndCancel" | |||
@no-modal="$emit('safe-close')" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad you found a way to eliminate this, I always considered it a code wart but wasn't sure how it could be eliminated.
// similar functionality. This is necessary because | ||
// sometimes Vue removes elements from the DOM before | ||
// we can examine their relationships. | ||
function onTopOf(el1, el2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See click-outside-element.js
. Make sure that functionality does not break with this change.
}); | ||
} | ||
|
||
// Returns true if el1 is "on top of" el2 in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at AposTiptapAnchor.vue
:
v-click-outside-element="close"
This is used to edit links in rich text. Needs to keep working, so click-outside-element.js
still needs to work, but could be factored to use the store.
…attach method to apos.modal
c5d346a
to
4d8b3a8
Compare
…ke shortcuts one)
@boutell The click outside feature is working well.
I keep it for now, I didn't change any behavior about it, and this PR is big enough. But I'll make tests later to see if we can get rid of this |
PRO-5818
Summary
apos.modal
accessible in and out of vue components.apos.modal.stack
isn't existing anymore, a method calledapos.modal.get()
allows to get all modals or one by ID. Not sure users needed to call thisapos.modal.stack
before.esc
that close modals that wasn't working like before.PR in Cypress-tools:
hasModalCount
method has been updated to useapos.modal.get()
instead ofapos.modal.stack
.PR in document-versions:
stack
. It'll need to be updated with core. If needed we can tweakdocument-versions
to support both?Tests are green:
https://github.com/apostrophecms/testbed/actions/runs/9176562447
What are the specific steps to test this change?
Everything works as expected. There is just one fix to make for shortcuts that'll come in another PR.
What kind of change does this PR introduce?
Make sure the PR fulfills these requirements: