fix: misc ts errors

This commit is contained in:
axolotle 2024-08-23 13:49:02 +02:00
parent bb49879225
commit d549d3fafc
22 changed files with 84 additions and 82 deletions

View file

@ -10,7 +10,8 @@
"lint:js": "eslint --ext \".ts,.vue,.cjs,.js\" --ignore-path ../.gitignore .", "lint:js": "eslint --ext \".ts,.vue,.cjs,.js\" --ignore-path ../.gitignore .",
"lint:prettier": "prettier --check .", "lint:prettier": "prettier --check .",
"lint": "yarn lint:js && yarn lint:prettier", "lint": "yarn lint:js && yarn lint:prettier",
"lintfix": "prettier --write --list-different . && yarn lint:js --fix" "lintfix": "prettier --write --list-different . && yarn lint:js --fix",
"type-check": "vue-tsc --noEmit -p tsconfig.json"
}, },
"dependencies": { "dependencies": {
"@fontsource/fira-code": "^5.0.18", "@fontsource/fira-code": "^5.0.18",

View file

@ -46,7 +46,7 @@ onMounted(() => {
if (intersecting) { if (intersecting) {
clearTimeout(unrenderTimer) clearTimeout(unrenderTimer)
// Show the component after a delay (to avoid rendering while scrolling fast) // Show the component after a delay (to avoid rendering while scrolling fast)
renderTimer = setTimeout( renderTimer = window.setTimeout(
() => { () => {
render.value = true render.value = true
}, },
@ -60,7 +60,7 @@ onMounted(() => {
} else if (props.unrender) { } else if (props.unrender) {
clearTimeout(renderTimer) clearTimeout(renderTimer)
// Hide the component after a delay if it's no longer in the viewport // Hide the component after a delay if it's no longer in the viewport
unrenderTimer = setTimeout(() => { unrenderTimer = window.setTimeout(() => {
fixedMinHeight.value = rootElem.value!.clientHeight fixedMinHeight.value = rootElem.value!.clientHeight
render.value = false render.value = false
}, props.unrenderDelay) }, props.unrenderDelay)

View file

@ -61,7 +61,7 @@ const slots = defineSlots<
} & { } & {
[K in KeyOfStr<FFD> as `component:${K}`]?: ( [K in KeyOfStr<FFD> as `component:${K}`]?: (
_: FFD[K]['component'] extends AnyWritableComponents _: FFD[K]['component'] extends AnyWritableComponents
? FFD[K]['cProps'] & BaseItemComputedProps<MV[K]> ? FFD[K]['cProps'] & BaseItemComputedProps
: FFD[K]['component'] extends AnyDisplayComponents : FFD[K]['component'] extends AnyDisplayComponents
? FFD[K]['cProps'] ? FFD[K]['cProps']
: never, : never,
@ -105,12 +105,16 @@ const Fields = createReusableTemplate<{
string string
>][] >][]
}>() }>()
// presence of <!-- @vue-expect-error --> are for `yarn type-check`,
// don't know why custom component slots name doesn't pass
</script> </script>
<template> <template>
<Fields.define v-slot="{ fieldsProps }"> <Fields.define v-slot="{ fieldsProps }">
<template v-for="[k, field] in fieldsProps" :key="k"> <template v-for="[k, field] in fieldsProps" :key="k">
<template v-if="toValue(field.visible) ?? true"> <template v-if="toValue(field.visible) ?? true">
<!-- @vue-expect-error -->
<slot <slot
v-if="isWritableComponent<MV[typeof k]>(field)" v-if="isWritableComponent<MV[typeof k]>(field)"
:name="`field:${k}`" :name="`field:${k}`"
@ -123,7 +127,9 @@ const Fields = createReusableTemplate<{
:validation="props.validations?.form[k]" :validation="props.validations?.form[k]"
@update:model-value="onModelUpdate(k, $event)" @update:model-value="onModelUpdate(k, $event)"
> >
<!-- @vue-expect-error -->
<template v-if="slots[`component:${k}`]" #default="childProps"> <template v-if="slots[`component:${k}`]" #default="childProps">
<!-- @vue-expect-error -->
<slot :name="`component:${k}`" v-bind="childProps" /> <slot :name="`component:${k}`" v-bind="childProps" />
</template> </template>
</FormField> </FormField>
@ -133,6 +139,7 @@ const Fields = createReusableTemplate<{
:model-value="modelValue![k]" :model-value="modelValue![k]"
/> />
</slot> </slot>
<!-- @vue-expect-error -->
<slot <slot
v-else-if="isDisplayComponent(field)" v-else-if="isDisplayComponent(field)"
:name="`component:${k}`" :name="`component:${k}`"

View file

@ -12,7 +12,6 @@ import { omit } from '@/helpers/commons'
import type { import type {
AnyWritableComponents, AnyWritableComponents,
BaseItemComputedProps, BaseItemComputedProps,
FormField,
FormFieldProps, FormFieldProps,
ItemComponentToItemProps, ItemComponentToItemProps,
} from '@/types/form' } from '@/types/form'
@ -45,7 +44,7 @@ defineEmits<{
const slots = defineSlots<{ const slots = defineSlots<{
default?: ( default?: (
componentProps: FormField<C, MV>['cProps'] & BaseItemComputedProps<MV>, componentProps: ItemComponentToItemProps[C] & BaseItemComputedProps,
) => any ) => any
description?: any description?: any
}>() }>()
@ -137,13 +136,13 @@ const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
...(props.cProps ?? ({} as ItemComponentToItemProps[C])), ...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
ariaDescribedby, ariaDescribedby,
state, state,
validation: validation, validation,
}" }"
> >
<!-- if no component was passed as slot, render a component from the props --> <!-- if no component was passed as slot, render a component from the props -->
<Component <Component
v-bind="props.cProps" v-bind="props.cProps"
:is="component" :is="props.component"
v-model="modelValue" v-model="modelValue"
:aria-describedby="ariaDescribedby" :aria-describedby="ariaDescribedby"
:state="state" :state="state"

View file

@ -54,8 +54,7 @@ const emit = defineEmits<{
const slots = defineSlots<{ const slots = defineSlots<{
default?: (_: { default?: (_: {
componentProps: FormField<C, ArrInnerType<MV>>['cProps'] & componentProps: ItemComponentToItemProps[C] & BaseItemComputedProps
BaseItemComputedProps<ArrInnerType<MV>>
index: number index: number
}) => any }) => any
description?: () => any description?: () => any
@ -168,12 +167,14 @@ function updateElement(index: number, newValue: ArrInnerType<MV>) {
<template> <template>
<BFormGroup v-bind="computedAttrs" :id="id" :label="label" :state="state"> <BFormGroup v-bind="computedAttrs" :id="id" :label="label" :state="state">
<div v-for="(fieldProps, index) in subProps" :key="index" class="item"> <div v-for="(fieldProps, index) in subProps" :key="index" class="item">
<!-- @vue-expect-error -->
<FormField <FormField
v-bind="fieldProps" v-bind="fieldProps"
class="w-100 mb-3" class="w-100 mb-3"
@update:model-value="updateElement(index, $event)" @update:model-value="updateElement(index, $event as ArrInnerType<MV>)"
> >
<template v-if="slots.default" #default="componentProps"> <template v-if="slots.default" #default="componentProps">
<!-- @vue-expect-error -->
<slot v-bind="{ componentProps, index }" /> <slot v-bind="{ componentProps, index }" />
</template> </template>
</FormField> </FormField>

View file

@ -17,7 +17,7 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const props = withDefaults(defineProps<FormFieldReadonlyProps<C, MV>>(), { const props = withDefaults(defineProps<FormFieldReadonlyProps<C>>(), {
id: undefined, id: undefined,
cols: () => ({ md: 4, lg: 3 }), cols: () => ({ md: 4, lg: 3 }),
}) })

View file

@ -5,20 +5,17 @@ import type {
BaseItemComputedProps, BaseItemComputedProps,
} from '@/types/form' } from '@/types/form'
withDefaults( withDefaults(defineProps<AdressItemProps & BaseItemComputedProps>(), {
defineProps<AdressItemProps & BaseItemComputedProps<AdressModelValue>>(), id: undefined,
{ name: undefined,
id: undefined, placeholder: undefined,
name: undefined, touchKey: undefined,
placeholder: undefined, type: 'email',
touchKey: undefined,
type: 'email',
state: undefined, state: undefined,
validation: undefined, validation: undefined,
ariaDescribedby: undefined, ariaDescribedby: undefined,
}, })
)
const emit = defineEmits<{ const emit = defineEmits<{
'update:modelValue': [value: AdressModelValue] 'update:modelValue': [value: AdressModelValue]

View file

@ -1,21 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CheckboxItemProps, BaseItemComputedProps } from '@/types/form' import type { CheckboxItemProps, BaseItemComputedProps } from '@/types/form'
withDefaults( withDefaults(defineProps<CheckboxItemProps & BaseItemComputedProps>(), {
defineProps<CheckboxItemProps & BaseItemComputedProps<boolean>>(), id: undefined,
{ name: undefined,
id: undefined, placeholder: undefined,
name: undefined, touchKey: undefined,
placeholder: undefined, label: undefined,
touchKey: undefined, labels: () => ({ true: 'yes', false: 'no' }),
label: undefined,
labels: () => ({ true: 'yes', false: 'no' }),
ariaDescribedby: undefined, ariaDescribedby: undefined,
state: undefined, state: undefined,
validation: undefined, validation: undefined,
}, })
)
const modelValue = defineModel<boolean>() const modelValue = defineModel<boolean>()
</script> </script>

View file

@ -11,7 +11,7 @@ import type {
} from '@/types/form' } from '@/types/form'
const props = withDefaults( const props = withDefaults(
defineProps<FileItemProps & BaseItemComputedProps<FileModelValue>>(), defineProps<FileItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -7,7 +7,7 @@ import type { BaseItemComputedProps, InputItemProps } from '@/types/form'
import { objectGet } from '@/helpers/commons' import { objectGet } from '@/helpers/commons'
const props = withDefaults( const props = withDefaults(
defineProps<InputItemProps & BaseItemComputedProps<string | number | null>>(), defineProps<InputItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -5,7 +5,7 @@ import { ValidationTouchSymbol } from '@/composables/form'
import type { BaseItemComputedProps, SelectItemProps } from '@/types/form' import type { BaseItemComputedProps, SelectItemProps } from '@/types/form'
const props = withDefaults( const props = withDefaults(
defineProps<SelectItemProps & BaseItemComputedProps<string | null>>(), defineProps<SelectItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -5,7 +5,7 @@ import { ValidationTouchSymbol } from '@/composables/form'
import type { BaseItemComputedProps, TagsItemProps } from '@/types/form' import type { BaseItemComputedProps, TagsItemProps } from '@/types/form'
const props = withDefaults( const props = withDefaults(
defineProps<TagsItemProps & BaseItemComputedProps<string[]>>(), defineProps<TagsItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -16,7 +16,7 @@ defineOptions({
}) })
const props = withDefaults( const props = withDefaults(
defineProps<TagsSelectizeItemProps & BaseItemComputedProps<string[]>>(), defineProps<TagsSelectizeItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -5,7 +5,7 @@ import { ValidationTouchSymbol } from '@/composables/form'
import type { BaseItemComputedProps, TextAreaItemProps } from '@/types/form' import type { BaseItemComputedProps, TextAreaItemProps } from '@/types/form'
const props = withDefaults( const props = withDefaults(
defineProps<TextAreaItemProps & BaseItemComputedProps<string | null>>(), defineProps<TextAreaItemProps & BaseItemComputedProps>(),
{ {
id: undefined, id: undefined,
name: undefined, name: undefined,

View file

@ -357,7 +357,7 @@ function useEvaluation(expression: string, form: MaybeRefOrGetter<Obj>) {
ctx[key] = ctx[key].content ctx[key] = ctx[key].content
} }
if (isAdressModelValue(ctx[key])) { if (isAdressModelValue(ctx[key])) {
ctx[key] = ctx[key].value().join('') ctx[key] = Object.values(ctx[key]).join('')
} }
} }

View file

@ -214,5 +214,6 @@ export const useInfos = createGlobalState(() => {
logout, logout,
tryToReconnect, tryToReconnect,
updateHtmlTitle, updateHtmlTitle,
updateRouterKey,
} }
}) })

View file

@ -108,7 +108,7 @@ export const useRequests = createGlobalState(() => {
const r = requests.value[requests.value.length - 1]! const r = requests.value[requests.value.length - 1]!
if (showModal) { if (showModal) {
request.showModalTimeout = setTimeout(() => { request.showModalTimeout = window.setTimeout(() => {
// Display the waiting modal only if the request takes some time. // Display the waiting modal only if the request takes some time.
if (r.status === 'pending') { if (r.status === 'pending') {
r.showModal = true r.showModal = true

View file

@ -182,7 +182,7 @@ export function formatForm<
R extends { [k in keyof T]: Awaited<FormValueReturnType<T[k]>> }, R extends { [k in keyof T]: Awaited<FormValueReturnType<T[k]>> },
>( >(
form: MaybeRef<T>, form: MaybeRef<T>,
{ removeEmpty = false }, { removeEmpty }: { removeEmpty: boolean },
): Promise< ): Promise<
Partial<{ Partial<{
// TODO: using `Partial` for now since i'm not sure we can infer empty `'' | [] | {}` // TODO: using `Partial` for now since i'm not sure we can infer empty `'' | [] | {}`
@ -194,7 +194,7 @@ export function formatForm<
R extends { [k in keyof T]: Awaited<FormValueReturnType<T[k]>> }, R extends { [k in keyof T]: Awaited<FormValueReturnType<T[k]>> },
>( >(
form: MaybeRef<T>, form: MaybeRef<T>,
{ removeNullish = false }, { removeNullish }: { removeNullish: boolean },
): Promise<{ ): Promise<{
[k in keyof R as R[k] extends undefined | null ? never : k]: R[k] [k in keyof R as R[k] extends undefined | null ? never : k]: R[k]
}> }>

View file

@ -294,7 +294,6 @@ export type FormFieldProps<
MV extends any, MV extends any,
> = Omit<FormField<C, MV>, 'hr' | 'visible' | 'readonly'> & > = Omit<FormField<C, MV>, 'hr' | 'visible' | 'readonly'> &
BaseFormFieldComputedProps BaseFormFieldComputedProps
// BaseFormFieldComputedProps<MV>
export type FormFieldReadonlyProps<C extends AnyWritableComponents> = Omit< export type FormFieldReadonlyProps<C extends AnyWritableComponents> = Omit<
FormFieldReadonly<C>, FormFieldReadonly<C>,

View file

@ -85,7 +85,7 @@ function onHistoryBarClick(e: MouseEvent) {
} }
// Delay the mouse move listener to distinguish a click from a drag. // Delay the mouse move listener to distinguish a click from a drag.
const listenToMouseMove = setTimeout(() => { const listenToMouseMove = window.setTimeout(() => {
hElem.style.height = hElem.offsetHeight + 'px' hElem.style.height = hElem.offsetHeight + 'px'
hElem.classList.add('no-max') hElem.classList.add('no-max')
window.addEventListener('mousemove', onMouseMove) window.addEventListener('mousemove', onMouseMove)

View file

@ -224,7 +224,7 @@ async function dismissNotification(name: string) {
humanKey: { key: 'apps.dismiss_notification', name: app.label }, humanKey: { key: 'apps.dismiss_notification', name: app.label },
}) })
// FIXME no need to refetch i guess, filter the reactive notifs? // FIXME no need to refetch i guess, filter the reactive notifs?
.then(() => api.refetch) .then(() => api.refetch())
} }
async function uninstall() { async function uninstall() {

View file

@ -3,7 +3,7 @@ import { defineConfig, loadEnv } from 'vite'
import fs from 'fs' import fs from 'fs'
import createVuePlugin from '@vitejs/plugin-vue' import createVuePlugin from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite' import Components from 'unplugin-vue-components/vite'
import { BootstrapVueNextResolver } from 'unplugin-vue-components/resolvers' import { BootstrapVueNextResolver } from 'bootstrap-vue-next'
import supportedLocales from './src/i18n/supportedLocales' import supportedLocales from './src/i18n/supportedLocales'
@ -13,7 +13,7 @@ const supportedDatefnsLocales = Object.entries(supportedLocales).map(
}, },
) )
export default defineConfig(({ command, mode }) => { export default defineConfig(({ mode }) => {
// Load env file based on `mode` in the current working directory. // Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix. // Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd()) const env = loadEnv(mode, process.cwd())
@ -57,7 +57,7 @@ export default defineConfig(({ command, mode }) => {
build: { build: {
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks: (id) => { manualChunks: (id: string) => {
// Circular import problems, this will merge core deps and api together // Circular import problems, this will merge core deps and api together
if (!id.includes('node_modules') && id.includes('api/')) { if (!id.includes('node_modules') && id.includes('api/')) {
return 'core' return 'core'
@ -65,7 +65,7 @@ export default defineConfig(({ command, mode }) => {
// Translations // Translations
if (id.includes('locales')) { if (id.includes('locales')) {
const match = /.*\/i18n\/locales\/([\w-]+)\.json/.exec(id) const match = /.*\/i18n\/locales\/([\w-]+)\.json/.exec(id)
return `locales/${match[1]}/translations` return `locales/${match![1]}/translations`
} }
// Split date-fns locales // Split date-fns locales
if (id.includes('date-fns')) { if (id.includes('date-fns')) {
@ -93,33 +93,33 @@ export default defineConfig(({ command, mode }) => {
...config, ...config,
base: '/yunohost/admin', base: '/yunohost/admin',
} }
} else if (mode === 'development') { }
return { // mode dev
...config, return {
server: { ...config,
port: 8080, server: {
host: env.VITE_IP, port: 8080,
https: { host: env.VITE_IP,
// Use already created cert from yunohost instance https: {
key: fs.readFileSync('/etc/yunohost/certs/yunohost.org/key.pem'), // Use already created cert from yunohost instance
cert: fs.readFileSync('/etc/yunohost/certs/yunohost.org/crt.pem'), key: fs.readFileSync('/etc/yunohost/certs/yunohost.org/key.pem'),
}, cert: fs.readFileSync('/etc/yunohost/certs/yunohost.org/crt.pem'),
fs: { },
// Needed for special ynh-dev context where node_modules is symlinked fs: {
allow: [ // Needed for special ynh-dev context where node_modules is symlinked
'/ynh-dev/yunohost-admin/app', allow: [
'/var/cache/ynh-dev/yunohost-admin/node_modules', '/ynh-dev/yunohost-admin/app',
], '/var/cache/ynh-dev/yunohost-admin/node_modules',
}, ],
proxy: { },
'/yunohost': { proxy: {
target: `https://${env.VITE_IP}`, '/yunohost': {
ws: true, target: `https://${env.VITE_IP}`,
logLevel: 'info', ws: true,
secure: false, logLevel: 'info',
}, secure: false,
}, },
}, },
} },
} }
}) })