mirror of
https://github.com/plausible/analytics.git
synced 2024-12-25 10:33:01 +03:00
cc769dfb3d
* Update Goal schema
* Equip ComboBox with the ability of JS selection callbacks
* Update factory so display_name is always present
* Extend Goals context interface
* Update seeds
Also farming unsuspecting BEAM programmers for better
sample page paths :)
* Update ComboBox test
* Unify error message color class with helpers seen elsewhere
* Use goal.display_name where applicable
* Implement LiveView extensions for editing goals
* Sprinkle display name in external stats controller tests
* Format
* Fix goal list mobile view
* Update lib/plausible_web/live/goal_settings/list.ex
Co-authored-by: Artur Pata <artur.pata@gmail.com>
* Update lib/plausible_web/live/goal_settings/form.ex
Co-authored-by: Artur Pata <artur.pata@gmail.com>
* Update the APIs: plugins and external
* Update test so the intent is clearer
* Format
* Update CHANGELOG
* Simplify form tabs tests
* Revert "Format"
This reverts commit c1647b5307
.
* Fixup format commit that went too far
* ComboBox: select the input contents on first focus
* Update lib/plausible/goal/schema.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Update lib/plausible/goals/goals.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Update lib/plausible_web/live/goal_settings/form.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Pass form goal instead of just ID
* Make tab component dumber
* Extract separate render functions for edit and create forms
* Update test to account for extracted forms
* Inline goal get query
* Extract revenue goal settings to a component and avoid computing assigns in flight
* Make LV modal preload optional
* Disable preload for goal settings form modal
* Get rid of phash component ID hack
* For another render after render_submit when testing goal updates
* Fix LV preload option
* Enable preload back for goals modal for now
* Make formatter happy
* Implement support for preopening of LV modal
* Preopen goals modal to avoid feedback gap on loading edited goal
* Remove `console.log` call from modal JS
* Clean up display name input IDs
* Make revenue settings functional on first edit again
* Display names: 2nd stage migration
* Update migration with data backfill
---------
Co-authored-by: Artur Pata <artur.pata@gmail.com>
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
// Courtesy of Benjamin von Polheim:
|
|
// https://blog.devgenius.io/build-a-performat-autocomplete-using-phoenix-liveview-and-alpine-js-8bcbbed17ba7
|
|
|
|
export default (id) => ({
|
|
isOpen: false,
|
|
id: id,
|
|
focus: null,
|
|
selectionInProgress: false,
|
|
firstFocusRegistered: false,
|
|
setFocus(f) {
|
|
this.focus = f;
|
|
},
|
|
initFocus() {
|
|
if (this.focus === null) {
|
|
this.setFocus(this.leastFocusableIndex())
|
|
if (!this.firstFocusRegistered) {
|
|
document.getElementById(this.id).select();
|
|
this.firstFocusRegistered = true;
|
|
}
|
|
}
|
|
},
|
|
trackSubmitValueChange() {
|
|
this.selectionInProgress = false;
|
|
},
|
|
open() {
|
|
if (!this.isOpen) {
|
|
this.initFocus()
|
|
this.isOpen = true
|
|
}
|
|
},
|
|
suggestionsCount() {
|
|
return this.$refs.suggestions?.querySelectorAll('li').length
|
|
},
|
|
hasCreatableOption() {
|
|
return this.$refs.suggestions?.querySelector('li').classList.contains("creatable")
|
|
},
|
|
leastFocusableIndex() {
|
|
if (this.suggestionsCount() === 0) {
|
|
return 0
|
|
}
|
|
return this.hasCreatableOption() ? 0 : 1
|
|
},
|
|
maxFocusableIndex() {
|
|
return this.hasCreatableOption() ? this.suggestionsCount() - 1 : this.suggestionsCount()
|
|
},
|
|
nextFocusableIndex() {
|
|
const currentFocus = this.focus
|
|
return currentFocus + 1 > this.maxFocusableIndex() ? this.leastFocusableIndex() : currentFocus + 1
|
|
},
|
|
prevFocusableIndex() {
|
|
const currentFocus = this.focus
|
|
return currentFocus - 1 >= this.leastFocusableIndex() ? currentFocus - 1 : this.maxFocusableIndex()
|
|
},
|
|
close(e) {
|
|
// Pressing Escape should not propagate to window,
|
|
// so we'll only close the suggestions pop-up
|
|
if (this.isOpen && e.key === "Escape") {
|
|
e.stopPropagation()
|
|
}
|
|
this.isOpen = false
|
|
},
|
|
select() {
|
|
this.$refs[`dropdown-${this.id}-option-${this.focus}`]?.click()
|
|
this.close()
|
|
document.getElementById(this.id).blur()
|
|
},
|
|
scrollTo(idx) {
|
|
this.$refs[`dropdown-${this.id}-option-${idx}`]?.scrollIntoView(
|
|
{ block: 'nearest', behavior: 'smooth', inline: 'start' }
|
|
)
|
|
},
|
|
focusNext() {
|
|
const nextIndex = this.nextFocusableIndex()
|
|
|
|
this.open()
|
|
|
|
this.setFocus(nextIndex)
|
|
this.scrollTo(nextIndex)
|
|
},
|
|
focusPrev() {
|
|
const prevIndex = this.prevFocusableIndex()
|
|
|
|
this.open()
|
|
|
|
this.setFocus(prevIndex)
|
|
this.scrollTo(prevIndex)
|
|
}
|
|
})
|