From 8855f878cbcde9d12cf754f417c839184ce0cbf1 Mon Sep 17 00:00:00 2001
From: Alexey Zinoviev <alexey.zinoviev@xored.com>
Date: Thu, 10 Aug 2023 19:17:44 +0400
Subject: [PATCH] ezqms-245: allow configurable languages per deployments
 (#3579)

Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
---
 dev/prod/src/platform.ts                      |  4 ++++
 .../components/internal/LangSelector.svelte   | 24 +++++++++++++++++--
 .../ui/src/components/internal/Root.svelte    |  2 +-
 packages/ui/src/plugin.ts                     |  1 +
 server/front/src/index.ts                     |  2 ++
 server/front/src/starter.ts                   |  2 ++
 6 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts
index 3e701f1bb4..a6e848bd4c 100644
--- a/dev/prod/src/platform.ts
+++ b/dev/prod/src/platform.ts
@@ -90,6 +90,7 @@ interface Config {
   GMAIL_URL: string
   CALENDAR_URL: string
   TITLE?: string
+  LANGUAGES?: string
   DEFAULT_LANGUAGE?: string
 }
 
@@ -117,6 +118,9 @@ export async function configurePlatform() {
 
   setMetadata(uiPlugin.metadata.DefaultApplication, login.component.LoginApp)
 
+  const languages = config.LANGUAGES ? (config.LANGUAGES as string).split(',').map((l) => l.trim()) : ['en', 'ru']
+
+  setMetadata(uiPlugin.metadata.Languages, languages)
   setMetadata(
     uiPlugin.metadata.Routes,
     new Map([
diff --git a/packages/ui/src/components/internal/LangSelector.svelte b/packages/ui/src/components/internal/LangSelector.svelte
index 43abd741d8..8d09c76370 100644
--- a/packages/ui/src/components/internal/LangSelector.svelte
+++ b/packages/ui/src/components/internal/LangSelector.svelte
@@ -14,6 +14,7 @@
 -->
 <script lang="ts">
   import { getContext } from 'svelte'
+  import { getMetadata } from '@hcengineering/platform'
   import { showPopup } from '../..'
   import LangPopup from './LangPopup.svelte'
   import ui from '../../plugin'
@@ -24,15 +25,34 @@
     currentLanguage: string
     setLanguage: (lang: string) => void
   }
+  const uiLangs = new Set(getMetadata(ui.metadata.Languages))
   const langs = [
     { id: 'en', label: ui.string.English },
     { id: 'ru', label: ui.string.Russian }
-  ]
+  ].filter((lang) => uiLangs.has(lang.id))
+
+  if (langs.findIndex((l) => l.id === currentLanguage) < 0 && langs.length !== 0) {
+    setLanguage(langs[0].id)
+  }
+
+  if (langs.length === 0) {
+    console.error(
+      `List of configured UI languages: [${getMetadata(ui.metadata.Languages)?.join(
+        ', '
+      )}] doesn't contain any languages available in the app. Please check you configuration.`
+    )
+  }
+
+  const isSelectable = langs.length > 1
 
   $: selected = langs.find((item) => item.id === currentLanguage)
   let trigger: HTMLElement
 
   const selectLanguage = (): void => {
+    if (!isSelectable) {
+      return
+    }
+
     showPopup(LangPopup, { langs }, trigger, (result) => {
       if (result) {
         selected = langs.find((item) => item.id === result)
@@ -45,7 +65,7 @@
 <Flags />
 {#if selected}
   <!-- svelte-ignore a11y-click-events-have-key-events -->
-  <div bind:this={trigger} class="flex-center cursor-pointer" on:click={selectLanguage}>
+  <div bind:this={trigger} class="flex-center {isSelectable ? 'cursor-pointer' : ''}" on:click={selectLanguage}>
     <svg class="svg-16px">
       <use href="#{selected.id}-flag" />
     </svg>
diff --git a/packages/ui/src/components/internal/Root.svelte b/packages/ui/src/components/internal/Root.svelte
index 6c6d855223..f330b2a9e8 100644
--- a/packages/ui/src/components/internal/Root.svelte
+++ b/packages/ui/src/components/internal/Root.svelte
@@ -159,7 +159,7 @@
           <div class="clock">
             <Clock />
           </div>
-          <div class="flex-center widget cursor-pointer">
+          <div class="flex-center widget">
             <LangSelector />
           </div>
           <div class="flex-center widget cursor-pointer">
diff --git a/packages/ui/src/plugin.ts b/packages/ui/src/plugin.ts
index 9415bcfd38..1f7eabd42a 100644
--- a/packages/ui/src/plugin.ts
+++ b/packages/ui/src/plugin.ts
@@ -88,6 +88,7 @@ export const uis = plugin(uiId, {
   metadata: {
     DefaultApplication: '' as Metadata<AnyComponent>,
     Routes: '' as Metadata<Map<string, AnyComponent>>,
+    Languages: '' as Metadata<string[]>,
 
     // Will activate network click button
     ShowNetwork: '' as Metadata<(evt: MouseEvent) => void>
diff --git a/server/front/src/index.ts b/server/front/src/index.ts
index cce2f01030..0ec5e2ea2e 100644
--- a/server/front/src/index.ts
+++ b/server/front/src/index.ts
@@ -142,6 +142,7 @@ export function start (
     gmailUrl: string
     calendarUrl: string
     title?: string
+    languages: string
     defaultLanguage: string
   },
   port: number,
@@ -182,6 +183,7 @@ export function start (
       GMAIL_URL: config.gmailUrl,
       CALENDAR_URL: config.calendarUrl,
       TITLE: config.title,
+      LANGUAGES: config.languages,
       DEFAULT_LANGUAGE: config.defaultLanguage,
       ...(extraConfig ?? {})
     })
diff --git a/server/front/src/starter.ts b/server/front/src/starter.ts
index 61b3074c44..5c86bac2a9 100644
--- a/server/front/src/starter.ts
+++ b/server/front/src/starter.ts
@@ -21,6 +21,7 @@ import { start } from '.'
 
 export function startFront (extraConfig?: Record<string, string>): void {
   const defaultLanguage = process.env.DEFAULT_LANGUAGE ?? 'en'
+  const languages = process.env.LANGUAGES ?? 'en,ru'
   const SERVER_PORT = parseInt(process.env.SERVER_PORT ?? '8080')
 
   const transactorEndpoint = process.env.TRANSACTOR_URL
@@ -132,6 +133,7 @@ export function startFront (extraConfig?: Record<string, string>): void {
     rekoniUrl,
     calendarUrl,
     title,
+    languages,
     defaultLanguage
   }
   console.log('Starting Front service with', config)