Source

views/LoginModule.vue

<template lang="pug">
  TLayout(
    :syncWithVuex="false"
    :sidebar="false" 
    :menu="false" 
    :rightMenu="false"
    :rightMenuBottom="false"
    )
    template(v-slot:main)
      b-alert.m-0(variant="warning", show style="position:fixed;z-index:100000000;top:0px;width:100%;" v-show="!!getNoticeMessage")
        p.text-center.p-1.m-1 {{ getNoticeMessage }}
      LoginModuleComponent(@onLogin="login" :enabled="!isLoginInProgress")
</template>
<script>
import LoginModuleComponent from '@c/shared/LoginModule/LoginModule.vue'
import TLayout from '@c/shared/TLayout/TLayout.vue'
import Vue from 'vue'
import { getEnvValue } from '@/services/env-service.js'

/**
 * - Retrieves application messages from geonline news
 * - Compute notice message like follow: newest message matching the current locale
 */
const LoginNewsMixin = {
  data() {
    return {
      news: [],
    }
  },
  mounted() {
    if (getEnvValue('VUE_APP_ENABLE_APP_NEWS', '0') === '1') {
      this.$newsService
        .getNews()
        .then((news) => {
          this.news = news
        })
        .catch((err) => {
          this.$logError('Fail to retrieve login page news', err)
        })
    }
  },
  computed: {
    getNoticeMessage() {
      for (var x in this.news) {
        if (this.news[x].lang == this.$locale) {
          return this.news[x].text
        }
      }
      return ''
    },
  },
}

export default {
  name: 'LoginModule',
  components: {
    LoginModuleComponent,
    TLayout,
  },
  mixins: [Vue.$mixins.userRightsMixin, LoginNewsMixin],
  componentType: 'container',
  data() {
    return {
      isLoginInProgress: false,
    }
  },
  methods: {
    async login(form) {
      if (this.isLoginInProgress) {
        return
      }
      this.isLoginInProgress = true
      this.$loader.show()
      try {
        let response = await this.$store.dispatch('auth/login', {
          ...form,
        })

        this.onLoginFinally()

        if (response.shouldRouteToClientSelection) {
          this.$router.push({
            name: 'login_as',
          })
        } else {
          this.$routerPlugin.routeToDefaultRoute()
        }
      } catch (err) {
        this.onLoginFinally()
        if (err.message.includes('401')) {
          this.$log.warn(err)
          await this.$store.dispatch('auth/logout')
          this.$store.dispatch('alert/addAlert', {
            type: 'warning',
            title: 'login.login_fail_title',
            text: 'alerts.BAD_CREDENTIALS',
          })
        } else {
          throw err
        }
      }
    },
    /**
     * We prevent user from executing the login multiple times with a 1sec cooldown flag.
     */
    onLoginFinally() {
      this.$loader.hide()
      setTimeout(() => {
        this.isLoginInProgress = false
      }, 1000)
    },
  },
}
</script>
<style scoped>
.login_form {
  float: right;
  width: 35%;
  border: 1px solid #eee;
  box-shadow: 0 2px 3px #ccc;
  background-color: #f3f5ff;
  height: calc(100vh);
}

.lang {
  display: flex;
}
.app_preview {
  float: left;
  width: 65%;
  border: 1px solid #eee;
  box-shadow: 0 2px 3px #ccc;
  height: calc(100vh);
}
.preview_map_screen {
  width: 100%;
  height: 100%;
}
.contact {
  font-size: 15px;
  color: #555;
}
.lang img {
  cursor: pointer;
}
</style>