From 59d7465bffcefb9475f501c6cd1c282dff189c69 Mon Sep 17 00:00:00 2001 From: av-alexistoledo Date: Thu, 18 Jan 2024 09:59:41 +0100 Subject: [PATCH 1/3] refactor translations + improve i18n types --- client/src/App.vue | 10 +++++----- client/src/Types.ts | 13 +++++++++++-- client/src/assets/translations.ts | 4 +++- client/src/lib/conferenceServices.ts | 17 ++++++++++++----- client/src/lib/i18n.ts | 8 ++++---- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/client/src/App.vue b/client/src/App.vue index 17af35a9..e0888b23 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -9,7 +9,7 @@ import Footer from "./components/Footer.vue"; import router from "./router"; import { loadLocaleMessages, setLocale } from "./lib/i18n"; import i18n from "./lib/i18n"; -import type { Locale } from "./Types"; +import type { Locale } from 'vue-i18n'; import { fallbackMessages } from "./assets/translations"; import { defaultTheme } from "./assets/theme"; @@ -68,11 +68,11 @@ const setConfigurations = async ( }; const setLanguage = async (conferenceClient: any) => { - let browserLocale = navigator.languages.find((locale) => - i18n.global.availableLocales.includes(locale as Locale) + let browserLocale: Locale = navigator.languages.find((locale: Locale) => + i18n.global.availableLocales.includes(locale) ); - if (browserLocale) setLocale(browserLocale as Locale); + if (browserLocale) setLocale(browserLocale); let paramLocale = router.currentRoute.value.params.locale?.toString(); @@ -97,7 +97,7 @@ const setLanguage = async (conferenceClient: any) => { response ? loadLocaleMessages(locale, response) - : loadLocaleMessages(locale, (fallbackMessages as any)[locale]); + : loadLocaleMessages(locale, (fallbackMessages)[locale]); } } }; diff --git a/client/src/Types.ts b/client/src/Types.ts index 0625398e..d517273c 100644 --- a/client/src/Types.ts +++ b/client/src/Types.ts @@ -5,6 +5,7 @@ import type { MarkingType, OptionContent, } from "@aion-dk/js-client/dist/lib/av_client/types"; +import type { DefineLocaleMessage, Locale } from 'vue-i18n'; export type Election = any; @@ -79,8 +80,6 @@ export interface Theme { splash: string | null; } -export type Locale = "en" | "da"; - export interface FullOptionContent extends OptionContent { url?: LocalString; videoUrl?: LocalString; @@ -99,3 +98,13 @@ export interface FullContestContent extends ContestContent { markingType: FullMarkingType; votesAllowedPerOption?: number; } + +export interface CurrentTranslations { + translations: { + [locale: Locale]: { + js: DefineLocaleMessage; + }; + }; +} + +export type SpreadableDLM = { [key: string]: any }; \ No newline at end of file diff --git a/client/src/assets/translations.ts b/client/src/assets/translations.ts index 09ccce9c..3226addf 100644 --- a/client/src/assets/translations.ts +++ b/client/src/assets/translations.ts @@ -1,4 +1,6 @@ -export const fallbackMessages = { +import type { SpreadableDLM } from "../Types"; + +export const fallbackMessages: SpreadableDLM = { en: { locales: { en: "English", diff --git a/client/src/lib/conferenceServices.ts b/client/src/lib/conferenceServices.ts index 8caa8783..1ac5a0f9 100644 --- a/client/src/lib/conferenceServices.ts +++ b/client/src/lib/conferenceServices.ts @@ -3,7 +3,8 @@ import { ref } from "vue"; import { responseErrorHandler, responseHandler } from "./axiosConfig"; import config from "./config"; -import type { ElectionStatusResponse } from "../Types"; +import type { ElectionStatusResponse, CurrentTranslations, SpreadableDLM } from "../Types"; +import type { Locale } from 'vue-i18n'; import type { AxiosInstance } from "axios"; const conferenceApi = ref( @@ -12,7 +13,7 @@ const conferenceApi = ref( }) ); -const currentTranslationsData: any = ref(null); +const currentTranslationsData = ref(null); export function useConferenceConnector( organisationSlug: string, @@ -36,15 +37,21 @@ export function useConferenceConnector( `/${organisationSlug}/${electionSlug}/theme` )) as string; }, - async getTranslationsData(locale: string) { + async getTranslationsData(locale: Locale) { if (!currentTranslationsData.value) { currentTranslationsData.value = await conferenceApi.value.get( `/${organisationSlug}/${electionSlug}/translations` ); } - return currentTranslationsData.value?.translations[locale].js - .election_verification_site; + const evsTranslations = { + ...currentTranslationsData.value?.translations[locale].js.election_verification_site as SpreadableDLM, + js: { + components: { ...currentTranslationsData.value?.translations[locale].js.components as SpreadableDLM }, + }, + }; + + return evsTranslations; }, }, }; diff --git a/client/src/lib/i18n.ts b/client/src/lib/i18n.ts index ef7c7ca6..2e930138 100644 --- a/client/src/lib/i18n.ts +++ b/client/src/lib/i18n.ts @@ -1,9 +1,9 @@ import { createI18n } from "vue-i18n"; import { nextTick } from "vue"; -import type { Locale } from "../Types"; +import type { Locale, DefineLocaleMessage } from 'vue-i18n'; -let locale = "en"; -const rtlLanguages = [ +let locale: Locale = "en"; +const rtlLanguages: Locale[] = [ "ar", "dv", "fa", @@ -35,7 +35,7 @@ export function setLocale(locale: Locale) { } export function loadLocaleMessages(locale: string, messages: object) { - i18n.global.setLocaleMessage(locale, messages as any); + i18n.global.setLocaleMessage(locale, messages as DefineLocaleMessage); return nextTick(); } From 454fa2eb9ec1e72a271d8e0ad530fee161e6051e Mon Sep 17 00:00:00 2001 From: av-alexistoledo Date: Thu, 18 Jan 2024 12:14:42 +0100 Subject: [PATCH 2/3] use AVPileSummary component --- client/package-lock.json | 8 +- client/package.json | 2 +- .../src/components/BallotVerifierContest.vue | 190 ++---------------- 3 files changed, 20 insertions(+), 180 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 110eda3c..d101d218 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@aion-dk/js-client": "^3.1.19", - "@assemblyvoting/ui-library": "^3.0.10", + "@assemblyvoting/ui-library": "^3.0.15", "@kalimahapps/vue-popper": "^1.1.6", "@pinia/testing": "^0.0.15", "@playwright/test": "^1.32.3", @@ -107,9 +107,9 @@ } }, "node_modules/@assemblyvoting/ui-library": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@assemblyvoting/ui-library/-/ui-library-3.0.10.tgz", - "integrity": "sha512-ynYYjqPcu0nSTanc1F2f0m/ijMjRSxovfZcFYOfTJBOhDSZGKpBs+XgiMbYAEk7aRtFk+EoJ9bZ/Gr4pUUySGA==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@assemblyvoting/ui-library/-/ui-library-3.0.15.tgz", + "integrity": "sha512-CWIXGy4P6W8f4ss+H3BsjPnu6+g0EqQKK3Z+H+v9aXdS11LeoJHBwjDGqWWu3mTvvTNZF9wFSW+Fn9aQjUfCvg==", "dependencies": { "@aion-dk/js-client": "3.1.19", "@fortawesome/fontawesome-svg-core": "^6.4.0", diff --git a/client/package.json b/client/package.json index c0bbbfe2..c4c8aa29 100644 --- a/client/package.json +++ b/client/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@aion-dk/js-client": "^3.1.19", - "@assemblyvoting/ui-library": "^3.0.10", + "@assemblyvoting/ui-library": "^3.0.15", "@kalimahapps/vue-popper": "^1.1.6", "@pinia/testing": "^0.0.15", "@playwright/test": "^1.32.3", diff --git a/client/src/components/BallotVerifierContest.vue b/client/src/components/BallotVerifierContest.vue index 0a7ef912..73fdbea7 100644 --- a/client/src/components/BallotVerifierContest.vue +++ b/client/src/components/BallotVerifierContest.vue @@ -5,79 +5,28 @@

-
- - {{ - `${$t("views.verifier.spoiled.ballot_selection")} ${pIndex + 1}/${ - contestSelection.piles.length - }` - }} - - - {{ - `${$t("views.verifier.spoiled.assigned")} ${pile.multiplier}` - }} - -
-
-
-
- {{ $t("views.verifier.blank_pile") }} -
- -
-
- -
- {{ parsedOption.title }} -
- -
- -
-
-
+
+ @@ -156,77 +63,10 @@ export default defineComponent({ font-weight: 600; } -.BallotVerifierContest__Pile { - margin-bottom: 1rem; - position: relative; - z-index: 10; -} - -.BallotVerifierContest__Header { +.BallotVerifierContest__Piles { display: flex; - align-items: center; - justify-content: space-between; - padding: 0.5rem; - margin: 0; - background-color: var(--slate-200); -} - -.BallotVerifierContest__Options { - display: grid; - grid-auto-flow: row; - grid-auto-rows: 1fr; - gap: 1rem; - &:not(:first-child) { - border: 1px solid var(--slate-200); - padding: 1rem; - } -} - -.BallotVerifierContest__Option { - position: relative; - z-index: 10; - display: grid; - grid-template-areas: "image title cross" "crosses crosses crosses"; - grid-template-columns: auto 1fr auto; - grid-template-rows: 1fr auto; - border: 1px #dddddd solid; - background-color: white; - align-items: center; -} - -.BallotVerifierContest__Option_Image { - grid-area: image; - height: 4rem; - margin: 1rem; -} - -.BallotVerifierContest__Option_Title { - grid-area: title; - align-self: center; - font-size: 1.25rem; - margin: 1rem; - &:not(:first-child) { - margin-left: 0; - } -} - -.BallotVerifierContest__Title + p { + flex-direction: column; margin-bottom: 1rem; - font-weight: 600; -} - -.BallotVerifierContest__Option_Cross { - grid-area: cross; - margin: 1rem; -} -.BallotVerifierContest__Option_Crosses { - grid-area: crosses; - padding: 1rem; - background-color: #f8f9fa; - border-top: #dddddd 1px solid; - direction: rtl; - display: grid; - grid-template-columns: repeat(auto-fit, 30px); - gap: 0.5rem; + z-index: 10; } From 745d286991f4faee8cc7b51616446ab9e3ab7215 Mon Sep 17 00:00:00 2001 From: av-alexistoledo Date: Thu, 18 Jan 2024 12:26:47 +0100 Subject: [PATCH 3/3] prettier --- client/src/App.vue | 4 ++-- client/src/Types.ts | 4 ++-- client/src/components/BallotVerifierContest.vue | 5 +---- client/src/lib/conferenceServices.ts | 16 ++++++++++++---- client/src/lib/i18n.ts | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/client/src/App.vue b/client/src/App.vue index e0888b23..80a26995 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -9,7 +9,7 @@ import Footer from "./components/Footer.vue"; import router from "./router"; import { loadLocaleMessages, setLocale } from "./lib/i18n"; import i18n from "./lib/i18n"; -import type { Locale } from 'vue-i18n'; +import type { Locale } from "vue-i18n"; import { fallbackMessages } from "./assets/translations"; import { defaultTheme } from "./assets/theme"; @@ -97,7 +97,7 @@ const setLanguage = async (conferenceClient: any) => { response ? loadLocaleMessages(locale, response) - : loadLocaleMessages(locale, (fallbackMessages)[locale]); + : loadLocaleMessages(locale, fallbackMessages[locale]); } } }; diff --git a/client/src/Types.ts b/client/src/Types.ts index d517273c..baaeb964 100644 --- a/client/src/Types.ts +++ b/client/src/Types.ts @@ -5,7 +5,7 @@ import type { MarkingType, OptionContent, } from "@aion-dk/js-client/dist/lib/av_client/types"; -import type { DefineLocaleMessage, Locale } from 'vue-i18n'; +import type { DefineLocaleMessage, Locale } from "vue-i18n"; export type Election = any; @@ -107,4 +107,4 @@ export interface CurrentTranslations { }; } -export type SpreadableDLM = { [key: string]: any }; \ No newline at end of file +export type SpreadableDLM = { [key: string]: any }; diff --git a/client/src/components/BallotVerifierContest.vue b/client/src/components/BallotVerifierContest.vue index 73fdbea7..1692ab1b 100644 --- a/client/src/components/BallotVerifierContest.vue +++ b/client/src/components/BallotVerifierContest.vue @@ -15,7 +15,6 @@ :pile-index="pileIndex" :total-piles="contestSelection.piles.length" active-state="summary" - /> @@ -25,9 +24,7 @@ import useConfigStore from "@/stores/useConfigStore"; import type { PropType } from "vue"; import { defineComponent } from "vue"; -import type { - ContestSelection, -} from "@aion-dk/js-client/dist/lib/av_client/types"; +import type { ContestSelection } from "@aion-dk/js-client/dist/lib/av_client/types"; import type { FullContestContent } from "@/Types"; export default defineComponent({ diff --git a/client/src/lib/conferenceServices.ts b/client/src/lib/conferenceServices.ts index 1ac5a0f9..aa61d530 100644 --- a/client/src/lib/conferenceServices.ts +++ b/client/src/lib/conferenceServices.ts @@ -3,8 +3,12 @@ import { ref } from "vue"; import { responseErrorHandler, responseHandler } from "./axiosConfig"; import config from "./config"; -import type { ElectionStatusResponse, CurrentTranslations, SpreadableDLM } from "../Types"; -import type { Locale } from 'vue-i18n'; +import type { + ElectionStatusResponse, + CurrentTranslations, + SpreadableDLM, +} from "../Types"; +import type { Locale } from "vue-i18n"; import type { AxiosInstance } from "axios"; const conferenceApi = ref( @@ -45,9 +49,13 @@ export function useConferenceConnector( } const evsTranslations = { - ...currentTranslationsData.value?.translations[locale].js.election_verification_site as SpreadableDLM, + ...(currentTranslationsData.value?.translations[locale].js + .election_verification_site as SpreadableDLM), js: { - components: { ...currentTranslationsData.value?.translations[locale].js.components as SpreadableDLM }, + components: { + ...(currentTranslationsData.value?.translations[locale].js + .components as SpreadableDLM), + }, }, }; diff --git a/client/src/lib/i18n.ts b/client/src/lib/i18n.ts index 2e930138..5465e2de 100644 --- a/client/src/lib/i18n.ts +++ b/client/src/lib/i18n.ts @@ -1,6 +1,6 @@ import { createI18n } from "vue-i18n"; import { nextTick } from "vue"; -import type { Locale, DefineLocaleMessage } from 'vue-i18n'; +import type { Locale, DefineLocaleMessage } from "vue-i18n"; let locale: Locale = "en"; const rtlLanguages: Locale[] = [