Whole bunch of TypeScript-driven fixes.

This commit is contained in:
Buster Neece 2023-08-27 05:09:37 -05:00
parent 5c9820bdc5
commit 1b6653cd3e
No known key found for this signature in database
41 changed files with 105 additions and 68 deletions

View File

@ -13,6 +13,7 @@ module.exports = {
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^_|props",
}],
"@typescript-eslint/no-explicit-any": "off",
"vue/multi-word-component-names": "off",
"vue/html-indent": ["error", 4, {
"attribute": 1,

View File

@ -29,7 +29,7 @@
"strict": false,
"noUnusedLocals": false,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"vue/**/*.ts",

View File

@ -129,7 +129,7 @@ const fields = [
];
const apiUrl = computed(() => {
const apiUrl = new URL(baseApiUrl.value, document.location);
const apiUrl = new URL(baseApiUrl.value, document.location.href);
const apiUrlParams = apiUrl.searchParams;
apiUrlParams.set('start', DateTime.fromJSDate(dateRange.value.startDate).toISO());

View File

@ -68,7 +68,7 @@
<button
type="button"
class="btn btn-dark"
@click="resetSyncTasks"
@click="resetSyncTasks()"
>
<icon :icon="IconRefresh" />
<span>{{ $gettext('Refresh') }}</span>
@ -119,7 +119,7 @@
<button
type="button"
class="btn btn-dark"
@click="resetQueueTotals"
@click="resetQueueTotals()"
>
<icon :icon="IconRefresh" />
<span>{{ $gettext('Refresh') }}</span>

View File

@ -66,12 +66,9 @@
import {useTranslate} from "~/vendor/gettext.ts";
import {get} from 'lodash';
const props = defineProps({
logs: {
type: Array,
required: true
}
});
const props = defineProps<{
logs: Array<any>
}>();
const badgeClasses = {
100: 'text-bg-info',

View File

@ -16,9 +16,9 @@ import TaskOutput from "~/components/Admin/Debug/TaskOutput.vue";
const $modal: Ref<InstanceType<typeof Modal> | null> = ref(null);
const logOutput: Ref<array> = ref([]);
const logOutput: Ref<Array<object>> = ref([]);
const open = (newLogOutput: array) => {
const open = (newLogOutput: Array<object>) => {
logOutput.value = newLogOutput;
$modal.value?.show();
}

View File

@ -47,12 +47,9 @@ import Tabs from "~/components/Common/Tabs.vue";
import {isObject} from "lodash";
import NetworkStatsTable from "~/components/Admin/Index/NetworkStatsTable.vue";
const props = defineProps({
stats: {
type: Object,
required: true
}
});
const props = defineProps<{
stats: object
}>();
const getNetworkInterfaceTableFields = (interfaceData) => Object.keys(interfaceData);
@ -61,7 +58,7 @@ const getNetworkInterfaceTableItems = (interfaceData) => {
Object.entries(interfaceData).forEach((data) => {
const key = data[0];
let value = data[1];
let value: any = data[1];
if (isObject(value)) {
value = value.readable + '/s';

View File

@ -65,7 +65,7 @@ const props = defineProps({
const remainingStations = computed(() => {
return pickBy(props.stations, (stationName, stationId) => {
return pickBy(props.stations, (_stationName, stationId) => {
return !find(props.form.permissions.$model.station, {'station_id': stationId});
});
});

View File

@ -76,7 +76,7 @@
<script setup lang="ts">
import FormGroupField from "~/components/Form/FormGroupField.vue";
import FormFieldset from "~/components/Form/FormFieldset";
import FormFieldset from "~/components/Form/FormFieldset.vue";
import FormGroupCheckbox from "~/components/Form/FormGroupCheckbox.vue";
import {computed} from "vue";
import {useTranslate} from "~/vendor/gettext";

View File

@ -87,7 +87,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
is_enabled: {},
media_storage_location: {},
recordings_storage_location: {},
@ -105,7 +107,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string]: any
} = {
media_storage_location: '',
recordings_storage_location: '',
podcasts_storage_location: '',

View File

@ -288,7 +288,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
backend_type: {required},
backend_config: {
crossfade_type: {},
@ -321,7 +323,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string | number]: any
} = {
backend_type: BackendAdapter.Liquidsoap,
backend_config: {
crossfade_type: 'normal',

View File

@ -202,7 +202,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
frontend_type: {required},
frontend_config: {
sc_license_id: {},
@ -232,7 +234,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string | number]: any
} = {
frontend_type: FrontendAdapter.Icecast,
frontend_config: {
sc_license_id: '',

View File

@ -111,7 +111,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
enable_hls: {},
backend_config: {
hls_enable_on_public_player: {},
@ -135,7 +137,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string | number]: any
} = {
enable_hls: false,
backend_config: {
hls_enable_on_public_player: false,

View File

@ -156,7 +156,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
name: {required},
description: {},
genre: {},
@ -179,7 +181,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string | number]: any
} = {
name: '',
description: '',
genre: '',

View File

@ -160,7 +160,9 @@ const form = useVModel(props, 'form', emit);
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
let validations = {
let validations: {
[key: string | number]: any
} = {
enable_streamers: {},
disconnect_deactivate_streamer: {},
backend_config: {
@ -187,7 +189,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
let blankForm = {
let blankForm: {
[key: string | number]: any
} = {
enable_streamers: false,
disconnect_deactivate_streamer: 0,
backend_config: {

View File

@ -83,7 +83,7 @@ import mergeExisting from "~/functions/mergeExisting";
import {useVuelidateOnForm} from "~/functions/useVuelidateOnForm";
import stationFormProps from "~/components/Admin/Stations/stationFormProps";
import {useResettableRef} from "~/functions/useResettableRef";
import Loading from '~/components/Common/Loading';
import Loading from '~/components/Common/Loading.vue';
import Tabs from "~/components/Common/Tabs.vue";
import {GlobalPermission, userAllowed} from "~/acl";

View File

@ -141,7 +141,7 @@ const langInstalledVersion = computed(() => {
const {notifyError} = useNotify();
const onError = (file, message) => {
const onError = (_file, message) => {
notifyError(message);
};

View File

@ -166,7 +166,7 @@
column.class,
(column.sortable) ? 'sortable' : ''
]"
@click.stop="sort(column, null, $event)"
@click.stop="sort(column)"
>
<slot
:name="'header('+column.key+')'"
@ -337,7 +337,7 @@ const props = defineProps({
default: true
},
pageOptions: {
type: Array,
type: Array<number>,
default: () => [10, 25, 50, 100, 250, 500, 0]
},
defaultPerPage: {
@ -345,7 +345,7 @@ const props = defineProps({
default: 10
},
fields: {
type: Array,
type: Array<object>,
required: true
},
selectable: {
@ -555,7 +555,9 @@ watch(toRef(props, 'items'), () => {
const {axios} = useAxios();
const refreshServerSide = () => {
const queryParams = {
const queryParams: {
[key: string]: any
} = {
internal: true
};

View File

@ -54,7 +54,7 @@
</template>
<template
v-for="(_, slot) of useSlotsExcept($slots, ['default', 'modal-footer'])"
v-for="(_, slot) of useSlotsExcept(['default', 'modal-footer'])"
#[slot]="scope"
>
<slot

View File

@ -115,7 +115,9 @@ const getLinkClass = (item) => {
}
const getCategoryLink = (item) => {
const linkAttrs = {};
const linkAttrs: {
[key: string]: any
} = {};
if (item.items) {
linkAttrs['data-bs-toggle'] = 'collapse';

View File

@ -352,7 +352,7 @@ const props = defineProps({
}
});
const chartsVisible = useOptionalStorage('dashboard_show_chart', true);
const chartsVisible = useOptionalStorage<boolean>('dashboard_show_chart', true);
const {$gettext} = useTranslate();

View File

@ -34,7 +34,7 @@
:stacked="stacked"
>
<template
v-for="(_, slot) of useSlotsExcept($slots, ['default', 'label', 'description'])"
v-for="(_, slot) of useSlotsExcept(['default', 'label', 'description'])"
#[slot]="scope"
>
<slot

View File

@ -145,7 +145,7 @@ forEach(props.customFields.slice(), (field) => {
sortable: true,
selectable: true,
visible: false,
formatter: (value, key, item) => item.media.custom_fields[field.key]
formatter: (_value, _key, item) => item.media.custom_fields[field.key]
});
});

View File

@ -212,9 +212,9 @@ const $player = ref<InstanceType<typeof AudioPlayer> | null>(null);
const volume = usePlayerVolume();
const urlParamVolume = (new URL(document.location)).searchParams.get('volume');
const urlParamVolume = (new URL(document.location.href)).searchParams.get('volume');
if (null !== urlParamVolume) {
volume.value = urlParamVolume;
volume.value = Number(urlParamVolume);
}
const isMuted = ref(false);

View File

@ -103,7 +103,7 @@
type="file"
class="custom-file-input files"
accept="audio/*"
multiple="multiple"
multiple
@change="addNewFiles($event.target.files)"
>
<label
@ -231,7 +231,7 @@ const isSeeking = ref(false);
const seekingPosition = computed({
get: () => {
return (100.0 * position.value / parseFloat(duration.value));
return (100.0 * (position.value / Number(duration.value)));
},
set: (val) => {
if (!isSeeking.value || !source.value) {

View File

@ -29,7 +29,11 @@ import InfoCard from "~/components/Common/InfoCard.vue";
import settingsProps from "~/components/Admin/settingsProps";
const props = defineProps({
...settingsProps
...settingsProps,
continueUrl: {
type: String,
required: true
}
});
const onSaved = () => {

View File

@ -109,7 +109,7 @@ const {relist} = useHasDatatable($dataTable);
const $editModal = ref<EditModalTemplateRef>(null);
const {doCreate, doEdit} = useHasEditModal($editModal);
const {needsRestart, mayNeedRestart} = useMayNeedRestart(props);
const {needsRestart, mayNeedRestart} = useMayNeedRestart();
const {doDelete} = useConfirmAndDelete(
$gettext('Delete Mount Point?'),

View File

@ -59,7 +59,9 @@ const isIcecast = computed(() => {
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
const validations = {
const validations: {
[key: string | number]: any
} = {
custom_listen_url: {}
};
@ -71,7 +73,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
const blankForm = {
const blankForm: {
[key: string | number]: any
} = {
custom_listen_url: null,
};

View File

@ -137,7 +137,9 @@ const isShoutcast = computed(() => {
const {v$, tabClass} = useVuelidateOnFormTab(
computed(() => {
const validations = {
const validations: {
[key: string | number]: any
} = {
name: {required},
display_name: {},
is_visible_on_public_pages: {},
@ -159,7 +161,9 @@ const {v$, tabClass} = useVuelidateOnFormTab(
}),
form,
() => {
const blankForm = {
const blankForm: {
[key: string | number]: any
} = {
name: null,
display_name: null,
is_visible_on_public_pages: true,

View File

@ -94,7 +94,7 @@ const targetUrl = computed(() => {
: props.newIntroUrl;
});
const onFileSuccess = (file, message) => {
const onFileSuccess = (_file, message) => {
hasIntro.value = true;
if (!props.editIntroUrl) {

View File

@ -372,7 +372,6 @@ const $schedule = ref<InstanceType<typeof Schedule> | null>(null);
const relist = () => {
$datatable.value?.refresh();
$schedule.value?.refresh();
};
const $editModal = ref<EditModalTemplateRef>(null);

View File

@ -1,7 +1,6 @@
<template>
<episodes-view
v-if="activePodcast"
v-bind="pickProps(props, episodesViewProps)"
:podcast="activePodcast"
:quota-url="quotaUrl"
@clear-podcast="onClearPodcast"

View File

@ -99,7 +99,7 @@ const targetUrl = computed(() => {
: props.newMediaUrl;
});
const onFileSuccess = (file, message) => {
const onFileSuccess = (_file, message) => {
hasMedia.value = true;
if (!props.editMediaUrl) {

View File

@ -182,7 +182,7 @@ const props = defineProps({
const emit = defineEmits(['api-call']);
const credentialsVisible = useOptionalStorage('station_show_frontend_credentials', false);
const credentialsVisible = useOptionalStorage<boolean>('station_show_frontend_credentials', false);
const {$gettext} = useTranslate();

View File

@ -28,5 +28,5 @@
import FormMarkup from "~/components/Form/FormMarkup.vue";
import {inject} from "vue";
const nowPlayingUrl = inject('nowPlayingUrl');
const nowPlayingUrl = inject<string>('nowPlayingUrl');
</script>

View File

@ -59,7 +59,7 @@
</template>
<script setup lang="ts">
import FormGroupField from "~/components/Form/FormGroupField";
import FormGroupField from "~/components/Form/FormGroupField.vue";
import CommonFormattingInfo from "./FormattingInfo.vue";
import {includes} from 'lodash';
import {useVModel} from "@vueuse/core";

View File

@ -67,7 +67,6 @@
<common-social-post-fields
v-model:form="form"
:now-playing-url="nowPlayingUrl"
/>
</tab>
</template>
@ -75,7 +74,7 @@
<script setup lang="ts">
import FormGroupField from "~/components/Form/FormGroupField.vue";
import CommonRateLimitFields from "./Common/RateLimitFields.vue";
import CommonSocialPostFields from "./Common/SocialPostFields";
import CommonSocialPostFields from "./Common/SocialPostFields.vue";
import {computed} from "vue";
import {useTranslate} from "~/vendor/gettext";
import FormMarkup from "~/components/Form/FormMarkup.vue";

View File

@ -175,8 +175,8 @@ export function useBaseEditModal(
wrapWithLoading(
axios(buildSubmitRequest())
).then((resp) => {
onSubmitSuccess(resp);
).then(() => {
onSubmitSuccess();
}).catch((err) => {
onSubmitError(err);
});

View File

@ -18,7 +18,7 @@ export default function initApp(appConfig = {}, appCallback = null): InitApp {
/* Pinia */
installPinia(vueApp);
window.vueComponent = (el: string, globalProps: AzuraCastConstants): void => {
(<any>window).vueComponent = (el: string, globalProps: AzuraCastConstants): void => {
setGlobalProps(globalProps);
/* Gettext */

View File

@ -8,7 +8,7 @@ export function installRouter(router: Router, vueApp: App): void {
router.beforeEach(async (to, _, next) => {
if (to.meta.remoteUrl) {
const {axios} = useAxios();
to.meta.state = await axios.get(to.meta.remoteUrl).then(r => r.data);
to.meta.state = await axios.get(to.meta.remoteUrl as string).then(r => r.data);
}
next();
});

View File

@ -165,12 +165,17 @@ final class SetupController
return $response->withRedirect($router->named('setup:' . $currentStep));
}
$router = $request->getRouter();
return $request->getView()->renderVuePage(
response: $response,
component: 'Setup/Settings',
id: 'setup-settings',
title: __('System Settings'),
props: $this->settingsComponent->getProps($request),
props: [
...$this->settingsComponent->getProps($request),
'continueUrl' => $router->named('dashboard'),
],
);
}