diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2025-09-13 08:33:14 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-13 08:33:14 +0900 |
| commit | 5b4115e21a6822a434a9bfbbd53f22b3ca961239 (patch) | |
| tree | eaac22e870a95feccc47ccc2693b794d0ccd299f /packages/frontend/src/pages/admin | |
| parent | Update CHANGELOG.md (diff) | |
| download | misskey-5b4115e21a6822a434a9bfbbd53f22b3ca961239.tar.gz misskey-5b4115e21a6822a434a9bfbbd53f22b3ca961239.tar.bz2 misskey-5b4115e21a6822a434a9bfbbd53f22b3ca961239.zip | |
refactor(frontend): フロントエンドの型エラー解消(途中まで) (#16539)
* fix(frontend): FormLinkをボタンとして使用した際にエラーが出る問題を修正
* refactor(frontend): フロントエンドの型エラー解消
* remove unused ts-expect-error
* migrate
* remove unrelated changes
* fix lint
* more type fixes
Diffstat (limited to 'packages/frontend/src/pages/admin')
14 files changed, 53 insertions, 44 deletions
diff --git a/packages/frontend/src/pages/admin/custom-emojis-manager.register.vue b/packages/frontend/src/pages/admin/custom-emojis-manager.register.vue index 621ec8a6a8..176d1121c5 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-manager.register.vue +++ b/packages/frontend/src/pages/admin/custom-emojis-manager.register.vue @@ -303,8 +303,8 @@ async function onFileSelectClicked() { const driveFiles = await chooseFileFromPcAndUpload({ multiple: true, folderId: selectedFolderId.value, - // 拡張子は消す - nameConverter: (file) => file.name.replace(/\.[a-zA-Z0-9]+$/, ''), + // // 拡張子は消す + // nameConverter: (file) => file.name.replace(/\.[a-zA-Z0-9]+$/, ''), }); gridItems.value.push(...driveFiles.map(fromDriveFile)); diff --git a/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue b/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue index 9a311b5772..420219c22c 100644 --- a/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue +++ b/packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue @@ -26,10 +26,10 @@ const chartEl = useTemplateRef('chartEl'); const { handler: externalTooltipHandler } = useChartTooltip(); -let chartInstance: Chart; +let chartInstance: Chart | null = null; function setData(values) { - if (chartInstance == null) return; + if (chartInstance == null || chartInstance.data.labels == null) return; for (const value of values) { chartInstance.data.labels.push(''); chartInstance.data.datasets[0].data.push(value); @@ -42,7 +42,7 @@ function setData(values) { } function pushData(value) { - if (chartInstance == null) return; + if (chartInstance == null || chartInstance.data.labels == null) return; chartInstance.data.labels.push(''); chartInstance.data.datasets[0].data.push(value); if (chartInstance.data.datasets[0].data.length > 200) { @@ -69,6 +69,8 @@ const color = onMounted(() => { const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)'; + if (chartEl.value == null) return; + chartInstance = new Chart(chartEl.value, { type: 'line', data: { diff --git a/packages/frontend/src/pages/admin/job-queue.vue b/packages/frontend/src/pages/admin/job-queue.vue index 0856bac860..b18049cb11 100644 --- a/packages/frontend/src/pages/admin/job-queue.vue +++ b/packages/frontend/src/pages/admin/job-queue.vue @@ -210,6 +210,7 @@ async function fetchCurrentQueue() { } async function fetchJobs() { + if (tab.value === '-') return; jobsFetching.value = true; const state = jobState.value; jobs.value = await misskeyApi('admin/queue/jobs', { @@ -307,6 +308,7 @@ async function removeJobs() { } async function refreshJob(jobId: string) { + if (tab.value === '-') return; const newJob = await misskeyApi('admin/queue/show-job', { queue: tab.value, jobId }); const index = jobs.value.findIndex((job) => job.id === jobId); if (index !== -1) { diff --git a/packages/frontend/src/pages/admin/overview.active-users.vue b/packages/frontend/src/pages/admin/overview.active-users.vue index 6c85f11cb1..32a5a6976e 100644 --- a/packages/frontend/src/pages/admin/overview.active-users.vue +++ b/packages/frontend/src/pages/admin/overview.active-users.vue @@ -26,7 +26,7 @@ initChart(); const chartEl = useTemplateRef('chartEl'); const now = new Date(); -let chartInstance: Chart = null; +let chartInstance: Chart | null = null; const chartLimit = 7; const fetching = ref(true); diff --git a/packages/frontend/src/pages/admin/overview.federation.vue b/packages/frontend/src/pages/admin/overview.federation.vue index 50f12cbf45..3c737ad32b 100644 --- a/packages/frontend/src/pages/admin/overview.federation.vue +++ b/packages/frontend/src/pages/admin/overview.federation.vue @@ -23,9 +23,9 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="item _panel sub"> <div class="icon"><i class="ti ti-world-download"></i></div> <div class="body"> - <div class="value"> + <div v-if="federationSubActive != null" class="value"> {{ number(federationSubActive) }} - <MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationSubActiveDiff"></MkNumberDiff> + <MkNumberDiff v-if="federationSubActiveDiff != null" v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationSubActiveDiff"></MkNumberDiff> </div> <div class="label">Sub</div> </div> @@ -33,9 +33,9 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="item _panel pub"> <div class="icon"><i class="ti ti-world-upload"></i></div> <div class="body"> - <div class="value"> + <div v-if="federationPubActive != null" class="value"> {{ number(federationPubActive) }} - <MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationPubActiveDiff"></MkNumberDiff> + <MkNumberDiff v-if="federationPubActiveDiff != null" v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationPubActiveDiff"></MkNumberDiff> </div> <div class="label">Pub</div> </div> diff --git a/packages/frontend/src/pages/admin/overview.heatmap.vue b/packages/frontend/src/pages/admin/overview.heatmap.vue index 7b2b142b16..6192d6eb0f 100644 --- a/packages/frontend/src/pages/admin/overview.heatmap.vue +++ b/packages/frontend/src/pages/admin/overview.heatmap.vue @@ -20,8 +20,9 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref } from 'vue'; import MkHeatmap from '@/components/MkHeatmap.vue'; import MkSelect from '@/components/MkSelect.vue'; +import type { HeatmapSource } from '@/components/MkHeatmap.vue'; -const src = ref('active-users'); +const src = ref<HeatmapSource>('active-users'); </script> <style lang="scss" module> diff --git a/packages/frontend/src/pages/admin/overview.pie.vue b/packages/frontend/src/pages/admin/overview.pie.vue index ec2b558cee..2e874b3505 100644 --- a/packages/frontend/src/pages/admin/overview.pie.vue +++ b/packages/frontend/src/pages/admin/overview.pie.vue @@ -32,15 +32,17 @@ const { handler: externalTooltipHandler } = useChartTooltip({ position: 'middle', }); -let chartInstance: Chart; +let chartInstance: Chart | null = null; onMounted(() => { + if (chartEl.value == null) return; + chartInstance = new Chart(chartEl.value, { type: 'doughnut', data: { labels: props.data.map(x => x.name), datasets: [{ - backgroundColor: props.data.map(x => x.color), + backgroundColor: props.data.map(x => x.color ?? '#000'), borderColor: getComputedStyle(window.document.documentElement).getPropertyValue('--MI_THEME-panel'), borderWidth: 2, hoverOffset: 0, @@ -57,9 +59,10 @@ onMounted(() => { }, }, onClick: (ev) => { - const hit = chartInstance.getElementsAtEventForMode(ev, 'nearest', { intersect: true }, false)[0]; - if (hit && props.data[hit.index].onClick) { - props.data[hit.index].onClick(); + if (ev.native == null) return; + const hit = chartInstance!.getElementsAtEventForMode(ev.native, 'nearest', { intersect: true }, false)[0]; + if (hit && props.data[hit.index].onClick != null) { + props.data[hit.index].onClick!(); } }, plugins: { diff --git a/packages/frontend/src/pages/admin/overview.queue.chart.vue b/packages/frontend/src/pages/admin/overview.queue.chart.vue index 9b9618c4ac..771b35c09f 100644 --- a/packages/frontend/src/pages/admin/overview.queue.chart.vue +++ b/packages/frontend/src/pages/admin/overview.queue.chart.vue @@ -26,10 +26,10 @@ const chartEl = useTemplateRef('chartEl'); const { handler: externalTooltipHandler } = useChartTooltip(); -let chartInstance: Chart; +let chartInstance: Chart | null = null; -function setData(values) { - if (chartInstance == null) return; +function setData(values: number[]) { + if (chartInstance == null || chartInstance.data.labels == null) return; for (const value of values) { chartInstance.data.labels.push(''); chartInstance.data.datasets[0].data.push(value); @@ -41,8 +41,8 @@ function setData(values) { chartInstance.update(); } -function pushData(value) { - if (chartInstance == null) return; +function pushData(value: number) { + if (chartInstance == null || chartInstance.data.labels == null) return; chartInstance.data.labels.push(''); chartInstance.data.datasets[0].data.push(value); if (chartInstance.data.datasets[0].data.length > 100) { @@ -67,6 +67,8 @@ const color = '?' as never; onMounted(() => { + if (chartEl.value == null) return; + const vLineColor = store.s.darkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)'; chartInstance = new Chart(chartEl.value, { diff --git a/packages/frontend/src/pages/admin/overview.queue.vue b/packages/frontend/src/pages/admin/overview.queue.vue index e7e139b74d..e57df3744a 100644 --- a/packages/frontend/src/pages/admin/overview.queue.vue +++ b/packages/frontend/src/pages/admin/overview.queue.vue @@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { markRaw, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'; import * as Misskey from 'misskey-js'; import XChart from './overview.queue.chart.vue'; -import type { ApQueueDomain } from '@/pages/admin/queue.vue'; +import type { ApQueueDomain } from '@/pages/admin/federation-job-queue.vue'; import number from '@/filters/number.js'; import { useStream } from '@/stream.js'; import { genId } from '@/utility/id.js'; @@ -64,10 +64,10 @@ function onStats(stats: Misskey.entities.QueueStats) { delayed.value = stats[props.domain].delayed; waiting.value = stats[props.domain].waiting; - chartProcess.value.pushData(stats[props.domain].activeSincePrevTick); - chartActive.value.pushData(stats[props.domain].active); - chartDelayed.value.pushData(stats[props.domain].delayed); - chartWaiting.value.pushData(stats[props.domain].waiting); + chartProcess.value?.pushData(stats[props.domain].activeSincePrevTick); + chartActive.value?.pushData(stats[props.domain].active); + chartDelayed.value?.pushData(stats[props.domain].delayed); + chartWaiting.value?.pushData(stats[props.domain].waiting); } function onStatsLog(statsLog: Misskey.entities.QueueStatsLog) { @@ -83,10 +83,10 @@ function onStatsLog(statsLog: Misskey.entities.QueueStatsLog) { dataWaiting.push(stats[props.domain].waiting); } - chartProcess.value.setData(dataProcess); - chartActive.value.setData(dataActive); - chartDelayed.value.setData(dataDelayed); - chartWaiting.value.setData(dataWaiting); + chartProcess.value?.setData(dataProcess); + chartActive.value?.setData(dataActive); + chartDelayed.value?.setData(dataDelayed); + chartWaiting.value?.setData(dataWaiting); } onMounted(() => { diff --git a/packages/frontend/src/pages/admin/overview.stats.vue b/packages/frontend/src/pages/admin/overview.stats.vue index fd8145b308..b0669bc557 100644 --- a/packages/frontend/src/pages/admin/overview.stats.vue +++ b/packages/frontend/src/pages/admin/overview.stats.vue @@ -7,13 +7,13 @@ SPDX-License-Identifier: AGPL-3.0-only <div> <Transition :name="prefer.s.animation ? '_transition_zoom' : ''" mode="out-in"> <MkLoading v-if="fetching"/> - <div v-else :class="$style.root"> + <div v-else-if="stats != null" :class="$style.root"> <div class="item _panel users"> <div class="icon"><i class="ti ti-users"></i></div> <div class="body"> <div class="value"> <MkNumber :value="stats.originalUsersCount" style="margin-right: 0.5em;"/> - <MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="usersComparedToThePrevDay"></MkNumberDiff> + <MkNumberDiff v-if="usersComparedToThePrevDay != null" v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="usersComparedToThePrevDay"></MkNumberDiff> </div> <div class="label">Users</div> </div> @@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="body"> <div class="value"> <MkNumber :value="stats.originalNotesCount" style="margin-right: 0.5em;"/> - <MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="notesComparedToThePrevDay"></MkNumberDiff> + <MkNumberDiff v-if="notesComparedToThePrevDay != null" v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="notesComparedToThePrevDay"></MkNumberDiff> </div> <div class="label">Notes</div> </div> @@ -56,6 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> </div> + <MkError v-else/> </Transition> </div> </template> @@ -71,8 +72,8 @@ import { customEmojis } from '@/custom-emojis.js'; import { prefer } from '@/preferences.js'; const stats = ref<Misskey.entities.StatsResponse | null>(null); -const usersComparedToThePrevDay = ref<number>(); -const notesComparedToThePrevDay = ref<number>(); +const usersComparedToThePrevDay = ref<number | null>(null); +const notesComparedToThePrevDay = ref<number | null>(null); const onlineUsersCount = ref(0); const fetching = ref(true); @@ -85,11 +86,11 @@ onMounted(async () => { onlineUsersCount.value = _onlineUsersCount; misskeyApiGet('charts/users', { limit: 2, span: 'day' }).then(chart => { - usersComparedToThePrevDay.value = stats.value.originalUsersCount - chart.local.total[1]; + usersComparedToThePrevDay.value = _stats.originalUsersCount - chart.local.total[1]; }); misskeyApiGet('charts/notes', { limit: 2, span: 'day' }).then(chart => { - notesComparedToThePrevDay.value = stats.value.originalNotesCount - chart.local.total[1]; + notesComparedToThePrevDay.value = _stats.originalNotesCount - chart.local.total[1]; }); fetching.value = false; diff --git a/packages/frontend/src/pages/admin/overview.vue b/packages/frontend/src/pages/admin/overview.vue index 2ad5173618..2c550bd9c3 100644 --- a/packages/frontend/src/pages/admin/overview.vue +++ b/packages/frontend/src/pages/admin/overview.vue @@ -95,7 +95,7 @@ const federationPubActiveDiff = ref<number | null>(null); const federationSubActive = ref<number | null>(null); const federationSubActiveDiff = ref<number | null>(null); const newUsers = ref<Misskey.entities.UserDetailed[] | null>(null); -const activeInstances = shallowRef<Misskey.entities.FederationInstance | null>(null); +const activeInstances = shallowRef<Misskey.entities.FederationInstancesResponse | null>(null); const queueStatsConnection = markRaw(useStream().useChannel('queueStats')); const now = new Date(); const filesPagination = { diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue index e98b4f0129..66004a44bb 100644 --- a/packages/frontend/src/pages/admin/roles.editor.vue +++ b/packages/frontend/src/pages/admin/roles.editor.vue @@ -830,7 +830,6 @@ import { watch, ref, computed } from 'vue'; import { throttle } from 'throttle-debounce'; import * as Misskey from 'misskey-js'; import RolesEditorFormula from './RolesEditorFormula.vue'; -import type { GetMkSelectValueTypesFromDef, MkSelectItem } from '@/components/MkSelect.vue'; import MkInput from '@/components/MkInput.vue'; import MkColorInput from '@/components/MkColorInput.vue'; import MkSelect from '@/components/MkSelect.vue'; diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue index c6c3165828..8e83cdb667 100644 --- a/packages/frontend/src/pages/admin/roles.role.vue +++ b/packages/frontend/src/pages/admin/roles.role.vue @@ -71,7 +71,7 @@ import { Paginator } from '@/utility/paginator.js'; const router = useRouter(); const props = defineProps<{ - id?: string; + id: string; }>(); const usersPaginator = markRaw(new Paginator('admin/roles/users', { diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue index 5323d042cf..6483bf16a8 100644 --- a/packages/frontend/src/pages/admin/roles.vue +++ b/packages/frontend/src/pages/admin/roles.vue @@ -346,6 +346,7 @@ import { definePage } from '@/page.js'; import { instance, fetchInstance } from '@/instance.js'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import { useRouter } from '@/router.js'; +import { deepClone } from '@/utility/clone.js'; import MkTextarea from '@/components/MkTextarea.vue'; const router = useRouter(); @@ -353,10 +354,7 @@ const baseRoleQ = ref(''); const roles = await misskeyApi('admin/roles/list'); -const policies = reactive<Record<typeof Misskey.rolePolicies[number], any>>({}); -for (const ROLE_POLICY of Misskey.rolePolicies) { - policies[ROLE_POLICY] = instance.policies[ROLE_POLICY]; -} +const policies = reactive(deepClone(instance.policies)); const avatarDecorationLimit = computed({ get: () => Math.min(16, Math.max(0, policies.avatarDecorationLimit)), @@ -376,6 +374,7 @@ function matchQuery(keywords: string[]): boolean { async function updateBaseRole() { await os.apiWithDialog('admin/roles/update-default-policies', { + //@ts-expect-error misskey-js側の型定義が不十分 policies, }); fetchInstance(true); |