Migrate LoginControl to vue
This commit is contained in:
parent
c6502e5023
commit
627e3219d1
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<div id="ui__bottom-left" class="ui__section">
|
<div id="ui__bottom-left" class="ui__section">
|
||||||
<div class="ui__toolbar toolbar--vertical">
|
<div class="ui__toolbar toolbar--vertical">
|
||||||
<LoginControl v-if="loginEnabled" :leaflet="leaflet"></LoginControl>
|
<LoginControl v-if="loginEnabled"></LoginControl>
|
||||||
<ChatControl v-if="chatBoxEnabled"></ChatControl>
|
<ChatControl v-if="chatBoxEnabled"></ChatControl>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui__toolbar">
|
<div class="ui__toolbar">
|
||||||
|
@ -14,30 +14,56 @@
|
|||||||
- limitations under the License.
|
- limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button class="ui__element ui__button" type="button" :title="buttonTitle" :aria-expanded="modalVisible"
|
||||||
|
@click.prevent.stop="handleClick"
|
||||||
|
@keydown.right.prevent.stop="handleClick">
|
||||||
|
<SvgIcon :name="loggedIn ? 'logout' : 'login'"></SvgIcon>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {defineComponent, onMounted, onUnmounted} from "@vue/runtime-core";
|
import {computed, defineComponent} from "@vue/runtime-core";
|
||||||
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
import SvgIcon from "@/components/SvgIcon.vue";
|
||||||
import {LoginControl} from "@/leaflet/control/LoginControl";
|
import {useStore} from "@/store";
|
||||||
|
import {ActionTypes} from "@/store/action-types";
|
||||||
|
import {notify} from "@kyvg/vue3-notification";
|
||||||
|
|
||||||
|
import "@/assets/icons/login.svg";
|
||||||
|
import "@/assets/icons/logout.svg";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
components: {SvgIcon},
|
||||||
leaflet: {
|
|
||||||
type: Object as () => LiveAtlasLeafletMap,
|
setup() {
|
||||||
required: true,
|
const store = useStore(),
|
||||||
|
loggedIn = computed(() => store.state.loggedIn),
|
||||||
|
buttonTitle = computed(() => loggedIn.value ? store.state.messages.logoutTitle : store.state.messages.loginTitle),
|
||||||
|
modalVisible = computed(() => store.state.ui.visibleModal === 'login');
|
||||||
|
|
||||||
|
const handleClick = async () => {
|
||||||
|
const logoutSuccess = computed(() => store.state.messages.logoutSuccess),
|
||||||
|
logoutError = computed(() => store.state.messages.logoutErrorUnknown);
|
||||||
|
|
||||||
|
if (loggedIn.value) {
|
||||||
|
try {
|
||||||
|
await store.dispatch(ActionTypes.LOGOUT, undefined);
|
||||||
|
notify(logoutSuccess.value);
|
||||||
|
} catch(e) {
|
||||||
|
notify(logoutError.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await store.dispatch(ActionTypes.LOGIN, null)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
modalVisible,
|
||||||
|
loggedIn,
|
||||||
|
buttonTitle,
|
||||||
|
|
||||||
|
handleClick
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
|
||||||
const control = new LoginControl({
|
|
||||||
position: 'topleft',
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => props.leaflet.addControl(control));
|
|
||||||
onUnmounted(() => props.leaflet.removeControl(control));
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2022 James Lyne
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Control, ControlOptions, DomEvent, DomUtil} from 'leaflet';
|
|
||||||
import {useStore} from "@/store";
|
|
||||||
import {watch} from "@vue/runtime-core";
|
|
||||||
|
|
||||||
import "@/assets/icons/login.svg";
|
|
||||||
import "@/assets/icons/logout.svg";
|
|
||||||
import {computed} from "vue";
|
|
||||||
import {ActionTypes} from "@/store/action-types";
|
|
||||||
import {notify} from "@kyvg/vue3-notification";
|
|
||||||
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Leaflet map control providing a login/logout button which opens the login modal/logs out on click
|
|
||||||
*/
|
|
||||||
export class LoginControl extends Control {
|
|
||||||
declare _map: LiveAtlasLeafletMap;
|
|
||||||
declare options: ControlOptions;
|
|
||||||
|
|
||||||
private readonly store = useStore();
|
|
||||||
private readonly loggedIn = computed(() => this.store.state.loggedIn);
|
|
||||||
private readonly _button: HTMLButtonElement;
|
|
||||||
|
|
||||||
constructor(options: ControlOptions) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
this._button = DomUtil.create('button',
|
|
||||||
'leaflet-control-bottom leaflet-control-button leaflet-control-login') as HTMLButtonElement;
|
|
||||||
|
|
||||||
this._button.type = 'button';
|
|
||||||
|
|
||||||
this._button.addEventListener('click', async e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
await this.handleClick();
|
|
||||||
});
|
|
||||||
|
|
||||||
//Open login on ArrowRight from button
|
|
||||||
DomEvent.on(this._button,'keydown', async (e: Event) => {
|
|
||||||
if ((e as KeyboardEvent).key === 'ArrowRight') {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
await this.handleClick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(this.loggedIn, () => {
|
|
||||||
this.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
const visibleModal = computed(() => this.store.state.ui.visibleModal);
|
|
||||||
|
|
||||||
watch(visibleModal, (newValue, oldValue) => {
|
|
||||||
this._button.setAttribute('aria-expanded', (newValue === 'login').toString());
|
|
||||||
|
|
||||||
if(this._map && !newValue && oldValue === 'login') {
|
|
||||||
this._button.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
onAdd() {
|
|
||||||
return this._button;
|
|
||||||
}
|
|
||||||
|
|
||||||
private update() {
|
|
||||||
this._button.title = this.loggedIn.value
|
|
||||||
? this.store.state.messages.logoutTitle : this.store.state.messages.loginTitle;
|
|
||||||
this._button.innerHTML = `
|
|
||||||
<svg class="svg-icon">
|
|
||||||
<use xlink:href="#icon--${this.loggedIn.value ? 'logout' : 'login'}" />
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async handleClick() {
|
|
||||||
const logoutSuccess = computed(() => this.store.state.messages.logoutSuccess),
|
|
||||||
logoutError = computed(() => this.store.state.messages.logoutErrorUnknown);
|
|
||||||
|
|
||||||
if (this.loggedIn.value) {
|
|
||||||
try {
|
|
||||||
await this.store.dispatch(ActionTypes.LOGOUT, undefined);
|
|
||||||
notify(logoutSuccess.value);
|
|
||||||
} catch(e) {
|
|
||||||
notify(logoutError.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.store.dispatch(ActionTypes.LOGIN, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user