chore: lint + add prettierignore + prettier json rules

This commit is contained in:
axolotle 2024-02-09 15:28:40 +01:00
parent c1d2a98b7a
commit df57e700ef
11 changed files with 84 additions and 35 deletions

2
.prettierignore Normal file
View file

@ -0,0 +1,2 @@
.mypy_cache
README.md

View file

@ -1,5 +1,19 @@
{ {
"semi": false, "semi": false,
"tabWidth": 2, "tabWidth": 2,
"singleQuote": true "singleQuote": true,
"overrides": [
{
"files": "**/*.json",
"options": {
"tabWidth": 4
}
},
{
"files": "./*.json",
"options": {
"tabWidth": 2
}
}
]
} }

View file

@ -17,7 +17,7 @@ try {
v-html="customLogo.src" v-html="customLogo.src"
/> />
<img <img
v-else-if="customLogo?.is === 'svg'" v-else-if="customLogo?.is === 'img'"
:src="customLogo.src" :src="customLogo.src"
alt="" alt=""
aria-hidden="true" aria-hidden="true"

View file

@ -15,7 +15,7 @@ withDefaults(
<template> <template>
<component <component
:tag="tag" :is="tag"
id="main-target" id="main-target"
tabindex="-1" tabindex="-1"
class="inline-block text-4xl font-bold" class="inline-block text-4xl font-bold"

View file

@ -78,10 +78,20 @@ export const useQueryMsg = () => useState<string | null>('queryMsg', () => null)
// SETTINGS // SETTINGS
type AppsSettings = Record<
string,
{
label: string
url: string
description?: Record<string, string>
logo?: string
}
>
export interface Settings { export interface Settings {
domain: string domain: string
public: boolean public: boolean
portal_logo?: { is: 'img' | 'svg', src: string } portal_logo?: { is: 'img' | 'svg'; src: string }
portal_theme: string portal_theme: string
portal_title?: string portal_title?: string
search_engine?: string search_engine?: string
@ -89,7 +99,7 @@ export interface Settings {
show_other_domains_apps: 0 | 1 show_other_domains_apps: 0 | 1
portal_user_intro: string portal_user_intro: string
portal_public_intro: string portal_public_intro: string
apps: Record<string, { label: string; url: string, description?: Record<string, string>, logo?: string }> apps: AppsSettings
} }
const useSettingsState = () => useState<Settings>('settings') const useSettingsState = () => useState<Settings>('settings')
@ -100,16 +110,21 @@ export const useSettings = async () => {
if (!settings.value) { if (!settings.value) {
const { data } = await useApi<Settings>('/public') const { data } = await useApi<Settings>('/public')
const logo = data.value.portal_logo const logo = data.value!.portal_logo as unknown as string | undefined
if (logo) { if (logo) {
const src = `https://${data.value.domain}/yunohost/sso/customassets/${logo}` const src = `https://${data.value.domain}/yunohost/sso/customassets/${logo}`
const is = data.value.portal_logo.substr(-4) === '.svg' ? 'svg' : 'img' const is = logo.slice(-4) === '.svg' ? 'svg' : 'img'
data.value.portal_logo = { is, src: is === 'svg' ? '' : src } data.value!.portal_logo = { is, src: is === 'svg' ? '' : src }
if (is === 'svg') { if (is === 'svg') {
// Query file content to inject inline SVG so that CSS "currentColor" can cascade to it // Query file content to inject inline SVG so that CSS "currentColor" can cascade to it
$fetch(src).then((blob) => blob.text()).then((text) => { $fetch<Blob>(src)
data.value.portal_logo.src = text.replace('<?xml version="1.0" encoding="utf-8"?>', '') .then((blob) => blob.text())
.then((text) => {
data.value!.portal_logo!.src = text.replace(
'<?xml version="1.0" encoding="utf-8"?>',
'',
)
}) })
} }
} }
@ -132,7 +147,7 @@ export interface User {
mailalias: string[] mailalias: string[]
mailforward: string[] mailforward: string[]
groups: string[] groups: string[]
apps: Record<string, { label: string; url: string }> apps: AppsSettings
} }
export const useUserState = () => useState<User | null>('user', () => null) export const useUserState = () => useState<User | null>('user', () => null)

View file

@ -1,5 +1,4 @@
services: services:
portal: portal:
build: . build: .
ports: ports:

View file

@ -71,9 +71,12 @@ async function logout() {
<div <div
class="flex flex-grow flex-wrap min-[500px]:w-full max-[500px]:flex-col max-[500px]:ms-auto" class="flex flex-grow flex-wrap min-[500px]:w-full max-[500px]:flex-col max-[500px]:ms-auto"
> >
<!-- eslint-disable-next-line vuejs-accessibility/click-events-have-key-events vuejs-accessibility/no-static-element-interactions -->
<div v-if="user" class="flex-grow"> <div v-if="user" class="flex-grow">
<div class="profile cursor-pointer flex flex-col" @click="navigateTo('/edit')"> <!-- eslint-disable-next-line vuejs-accessibility/click-events-have-key-events vuejs-accessibility/no-static-element-interactions -->
<div
class="profile cursor-pointer flex flex-col"
@click="navigateTo('/edit')"
>
<span> <span>
<span <span
class="text-2xl font-extrabold tracking-tight leading-none" class="text-2xl font-extrabold tracking-tight leading-none"
@ -89,7 +92,10 @@ async function logout() {
</NuxtLink> </NuxtLink>
</div> </div>
</div> </div>
<p v-else-if="settings.portal_title" class="text-3xl font-bold flex-grow min-[800px]:text-center mb-3"> <p
v-else-if="settings.portal_title"
class="text-3xl font-bold flex-grow min-[800px]:text-center mb-3"
>
{{ settings.portal_title }} {{ settings.portal_title }}
</p> </p>

View file

@ -18,9 +18,7 @@
{ {
"code": "br", "code": "br",
"dir": "ltr", "dir": "ltr",
"fallback": [ "fallback": ["fr"],
"fr"
],
"file": "br.json", "file": "br.json",
"iso": "br", "iso": "br",
"name": "Brezhoneg" "name": "Brezhoneg"

View file

@ -5,7 +5,7 @@ import {
useSettings, useSettings,
} from '@/composables/states' } from '@/composables/states'
export default defineNuxtRouteMiddleware(async (to, from) => { export default defineNuxtRouteMiddleware(async (to) => {
const isLoggedIn = useIsLoggedIn() const isLoggedIn = useIsLoggedIn()
const settings = await useSettings() const settings = await useSettings()

View file

@ -21,25 +21,22 @@ const intro = computed(() => {
return isLoggedIn.value ? userIntro : isPublic ? publicIntro : null return isLoggedIn.value ? userIntro : isPublic ? publicIntro : null
}) })
const apps = Object.entries(appsData.value).map(([id, app]) => { const apps = Object.values(appsData.value).map((app) => {
return { return {
...app, ...app,
url: '//' + app.url, url: '//' + app.url,
description: app.description[locale.value] || app.description.en description: app.description?.[locale.value] || app.description?.en,
} }
}) })
const search = ref('') const search = ref('')
async function onSearchSubmit() { async function onSearchSubmit() {
await navigateTo( await navigateTo(settings.value.search_engine + search.value, {
settings.value.search_engine + search.value,
{
open: { open: {
target: '_blank', target: '_blank',
} },
} })
)
} }
</script> </script>
@ -49,14 +46,31 @@ async function onSearchSubmit() {
<form v-if="settings.search_engine" class="flex my-16" @submit.prevent> <form v-if="settings.search_engine" class="flex my-16" @submit.prevent>
<div class="join w-full max-w-xl mx-auto"> <div class="join w-full max-w-xl mx-auto">
<!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
<label for="search" class="sr-only">
{{
t('search_engine_placeholder', {
engine: settings.search_engine_name,
})
}}
</label>
<input <input
id="search"
v-model="search" v-model="search"
type="search" type="search"
class="input input-bordered join-item w-full" class="input input-bordered join-item w-full"
name="search" name="search"
:placeholder="t('search_engine_placeholder', { engine: settings.search_engine_name })" :placeholder="
t('search_engine_placeholder', {
engine: settings.search_engine_name,
})
"
/>
<button
type="submit"
class="btn btn-primary join-item px-2"
@click="onSearchSubmit"
> >
<button type="submit" class="btn btn-primary join-item px-2" @click="onSearchSubmit">
<YIcon name="magnify" aria-hidden="true" class="m-0" /> <YIcon name="magnify" aria-hidden="true" class="m-0" />
<span class="sr-only">{{ t('search') }}</span> <span class="sr-only">{{ t('search') }}</span>
</button> </button>
@ -77,9 +91,10 @@ async function onSearchSubmit() {
> >
<img <img
v-if="app.logo" v-if="app.logo"
aria-hidden="true" aria-hidden
:src="app.logo" :src="app.logo"
class="w-24 h-24 rounded me-4 bg-white" class="w-24 h-24 rounded me-4 bg-white"
alt=""
/> />
<div> <div>
<h4 class="text-xl font-bold"> <h4 class="text-xl font-bold">