2017-11-13 01:23:39 -05:00
|
|
|
<template lang="html">
|
2018-03-30 17:58:56 -04:00
|
|
|
<div class="ffz--widget ffz--profile-selector">
|
|
|
|
<div
|
|
|
|
ref="button"
|
|
|
|
:class="{active: opened}"
|
|
|
|
tabindex="0"
|
2021-03-02 16:55:25 -05:00
|
|
|
class="tw-flex tw-align-items-center tw-border-radius-medium tw-font-size-6 tw-full-width ffz-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05"
|
2018-03-30 17:58:56 -04:00
|
|
|
@keyup.up.stop.prevent="focusShow"
|
|
|
|
@keyup.left.stop.prevent="focusShow"
|
|
|
|
@keyup.down.stop.prevent="focusShow"
|
|
|
|
@keyup.right.stop.prevent="focusShow"
|
|
|
|
@keyup.enter="focusShow"
|
|
|
|
@keyup.space="focusShow"
|
|
|
|
@click="togglePopup"
|
|
|
|
>
|
2019-10-09 16:02:25 -04:00
|
|
|
{{ context.currentProfile.i18n_key ? t(context.currentProfile.i18n_key, context.currentProfile.title, context.currentProfile) : context.currentProfile.title }}
|
2018-03-30 17:58:56 -04:00
|
|
|
</div>
|
2017-11-13 01:23:39 -05:00
|
|
|
<div
|
2018-03-30 17:58:56 -04:00
|
|
|
v-if="opened"
|
2019-06-20 15:15:54 -04:00
|
|
|
v-on-clickaway="hide"
|
2021-02-11 19:40:12 -05:00
|
|
|
class="ffz-balloon tw-block ffz-balloon--lg ffz-balloon--down ffz-balloon--left tw-z-above"
|
2017-11-13 01:23:39 -05:00
|
|
|
>
|
2018-03-30 17:58:56 -04:00
|
|
|
<div
|
|
|
|
class="ffz--profile-list tw-elevation-2 tw-c-background-alt"
|
|
|
|
@keyup.escape="focusHide"
|
|
|
|
@focusin="focus"
|
|
|
|
@focusout="blur"
|
|
|
|
>
|
2022-12-07 16:52:07 -05:00
|
|
|
<div ref="scroller" class="scrollable-area tw-border-b" data-simplebar>
|
2018-03-30 17:58:56 -04:00
|
|
|
<div class="simplebar-scroll-content">
|
|
|
|
<div ref="popup" class="simplebar-content">
|
2017-11-13 01:23:39 -05:00
|
|
|
<div
|
2018-03-30 17:58:56 -04:00
|
|
|
v-for="p in context.profiles"
|
|
|
|
:key="p.id"
|
|
|
|
:class="{
|
|
|
|
live: p.live,
|
|
|
|
current: p === context.currentProfile
|
|
|
|
}"
|
|
|
|
tabindex="0"
|
|
|
|
class="ffz--profile-row tw-relative tw-border-b tw-pd-y-05 tw-pd-r-3 tw-pd-l-1"
|
|
|
|
@keydown.up.stop.prevent=""
|
|
|
|
@keydown.down.stop.prevent=""
|
|
|
|
@keydown.page-up.stop.prevent=""
|
|
|
|
@keydown.page-down.stop.prevent=""
|
|
|
|
@keyup.up.stop="prevItem"
|
|
|
|
@keyup.down.stop="nextItem"
|
|
|
|
@keyup.home="firstItem"
|
|
|
|
@keyup.end="lastItem"
|
|
|
|
@keyup.page-up.stop="prevPage"
|
|
|
|
@keyup.page-down.stop="nextPage"
|
|
|
|
@keyup.enter="changeProfile(p)"
|
|
|
|
@click="changeProfile(p)"
|
2017-11-13 01:23:39 -05:00
|
|
|
>
|
2021-03-02 16:55:25 -05:00
|
|
|
<div class="ffz--profile-row__icon-tray tw-flex">
|
|
|
|
<div
|
|
|
|
v-if="p.url"
|
2021-05-17 17:02:23 -04:00
|
|
|
:class="`ffz-il-tooltip__container ffz--profile-row__icon ffz-i-download-cloud tw-relative${p.pause_updates ? ' ffz-unmatched-item' : ''}`"
|
2021-03-02 16:55:25 -05:00
|
|
|
>
|
2021-05-17 17:02:23 -04:00
|
|
|
<div v-if="! p.pause_updates" class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
2021-03-02 16:55:25 -05:00
|
|
|
{{ t('setting.profiles.updates', 'This profile will update automatically.') }}
|
|
|
|
</div>
|
2019-10-09 16:02:25 -04:00
|
|
|
</div>
|
2021-03-02 16:55:25 -05:00
|
|
|
<div
|
|
|
|
v-if="! p.toggled"
|
2021-05-17 17:02:23 -04:00
|
|
|
class="ffz-il-tooltip__container ffz--profile-row__icon ffz-i-cancel tw-relative"
|
2021-03-02 16:55:25 -05:00
|
|
|
>
|
2021-05-17 17:02:23 -04:00
|
|
|
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
2021-03-02 16:55:25 -05:00
|
|
|
{{ t('setting.profiles.disabled', 'This profile is disabled.') }}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-if="p.live"
|
2021-05-17 17:02:23 -04:00
|
|
|
class="ffz-il-tooltip__container ffz--profile-row__icon ffz-i-ok tw-relative"
|
2021-03-02 16:55:25 -05:00
|
|
|
>
|
2021-05-17 17:02:23 -04:00
|
|
|
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
2021-03-02 16:55:25 -05:00
|
|
|
{{ t('setting.profiles.active', 'This profile is enabled and active.') }}
|
|
|
|
</div>
|
2018-03-30 17:58:56 -04:00
|
|
|
</div>
|
2017-11-13 01:23:39 -05:00
|
|
|
</div>
|
|
|
|
|
2019-08-05 17:26:11 -04:00
|
|
|
<h4>{{ p.i18n_key ? t(p.i18n_key, p.title, p) : p.title }}</h4>
|
2018-03-30 17:58:56 -04:00
|
|
|
<div v-if="p.description" class="description">
|
2019-08-05 17:26:11 -04:00
|
|
|
{{ p.desc_i18n_key ? t(p.desc_i18n_key, p.description, p) : p.description }}
|
2018-03-30 17:58:56 -04:00
|
|
|
</div>
|
2017-11-13 01:23:39 -05:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2018-03-30 17:58:56 -04:00
|
|
|
<div class="tw-pd-y-05 tw-pd-x-05 tw-align-right">
|
|
|
|
<button class="tw-button tw-button--text" @click="openConfigure">
|
|
|
|
<span class="tw-button__text ffz-i-cog">
|
|
|
|
{{ t('setting.profiles.configure', 'Configure') }}
|
|
|
|
</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
2017-11-13 01:23:39 -05:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
const indexOf = Array.prototype.indexOf;
|
|
|
|
|
|
|
|
export default {
|
|
|
|
props: ['context'],
|
|
|
|
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
opened: false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2022-12-07 16:52:07 -05:00
|
|
|
watch: {
|
|
|
|
opened() {
|
|
|
|
if (this.opened)
|
|
|
|
this.$nextTick(() => this.updateScroller());
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
methods: {
|
2022-12-07 16:52:07 -05:00
|
|
|
updateScroller() {
|
|
|
|
const scroller = this.$refs.scroller;
|
|
|
|
if (!scroller || ! window.ffzSimplebar || scroller.SimpleBar)
|
|
|
|
return;
|
|
|
|
|
|
|
|
new ffzSimplebar(scroller, ffzSimplebar.getElOptions(scroller));
|
|
|
|
},
|
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
openConfigure() {
|
|
|
|
this.hide();
|
|
|
|
this.$emit('navigate', 'data_management.profiles');
|
|
|
|
},
|
|
|
|
|
|
|
|
focus() {
|
|
|
|
this._focused = true;
|
|
|
|
},
|
|
|
|
|
|
|
|
blur() {
|
|
|
|
this._focused = false;
|
|
|
|
if ( ! this._blur_timer )
|
|
|
|
this._blur_timer = setTimeout(() => {
|
|
|
|
this._blur_timer = null;
|
|
|
|
if ( ! this._focused && document.hasFocus() )
|
|
|
|
this.hide();
|
|
|
|
}, 10);
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
hide() {
|
|
|
|
this.opened = false;
|
|
|
|
},
|
|
|
|
|
|
|
|
show() {
|
|
|
|
if ( ! this.opened )
|
|
|
|
this.opened = true;
|
|
|
|
},
|
|
|
|
|
|
|
|
togglePopup() {
|
|
|
|
if ( this.opened )
|
|
|
|
this.hide();
|
|
|
|
else
|
|
|
|
this.show();
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
focusHide() {
|
|
|
|
this.hide();
|
|
|
|
this.$refs.button.focus();
|
|
|
|
},
|
|
|
|
|
|
|
|
focusShow() {
|
|
|
|
this.show();
|
|
|
|
this.$nextTick(() => this.$refs.popup.querySelector('.current').focus());
|
|
|
|
},
|
|
|
|
|
|
|
|
prevItem(e) {
|
|
|
|
const el = e.target.previousSibling;
|
|
|
|
if ( el ) {
|
|
|
|
this.scroll(el);
|
|
|
|
el.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
nextItem(e) {
|
|
|
|
const el = e.target.nextSibling;
|
|
|
|
if ( el ) {
|
|
|
|
this.scroll(el);
|
|
|
|
el.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
firstItem() {
|
|
|
|
const el = this.$refs.popup.firstElementChild;
|
|
|
|
if ( el ) {
|
|
|
|
this.scroll(el);
|
|
|
|
el.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
prevPage(e) {
|
|
|
|
this.select(indexOf.call(this.$refs.popup.children, e.target) - 5);
|
|
|
|
},
|
|
|
|
|
|
|
|
nextPage(e) {
|
|
|
|
this.select(indexOf.call(this.$refs.popup.children, e.target) + 5);
|
|
|
|
},
|
|
|
|
|
|
|
|
select(idx) {
|
|
|
|
const kids = this.$refs.popup.children,
|
|
|
|
el = kids[idx <= 0 ? 0 : Math.min(idx, kids.length - 1)];
|
|
|
|
|
|
|
|
if ( el ) {
|
|
|
|
this.scroll(el);
|
|
|
|
el.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
lastItem() {
|
|
|
|
const el = this.$refs.popup.lastElementChild;
|
|
|
|
if ( el ) {
|
|
|
|
this.scroll(el);
|
|
|
|
el.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
scroll(el) {
|
|
|
|
const scroller = this.$refs.popup.parentElement,
|
|
|
|
|
|
|
|
top = el.offsetTop,
|
|
|
|
bottom = el.offsetHeight + top,
|
|
|
|
|
|
|
|
// We need to use the margin-bottom because of the scrollbar library.
|
|
|
|
// In fact, the scrollbar library is why any of this function exists.
|
|
|
|
scroll_top = scroller.scrollTop,
|
|
|
|
scroll_bottom = scroller.offsetHeight + parseInt(scroller.style.marginBottom || 0, 10) + scroll_top;
|
|
|
|
|
|
|
|
if ( top < scroll_top )
|
|
|
|
scroller.scrollBy(0, top - scroll_top);
|
|
|
|
|
|
|
|
else if ( bottom > scroll_bottom )
|
|
|
|
scroller.scrollBy(0, bottom - scroll_bottom);
|
|
|
|
},
|
|
|
|
|
|
|
|
changeProfile(profile) {
|
|
|
|
this.context.currentProfile = profile;
|
2021-03-02 16:55:25 -05:00
|
|
|
|
|
|
|
try {
|
|
|
|
window.history.replaceState({
|
|
|
|
...window.history.state,
|
|
|
|
ffzccp: profile.id
|
|
|
|
}, document.title);
|
|
|
|
} catch(err) {
|
|
|
|
/* no-op */
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
this.focusHide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
</script>
|