summaryrefslogtreecommitdiff
path: root/packages/frontend/src/pages/admin
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-09-13 08:33:14 +0900
committerGitHub <noreply@github.com>2025-09-13 08:33:14 +0900
commit5b4115e21a6822a434a9bfbbd53f22b3ca961239 (patch)
treeeaac22e870a95feccc47ccc2693b794d0ccd299f /packages/frontend/src/pages/admin
parentUpdate CHANGELOG.md (diff)
downloadmisskey-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')
-rw-r--r--packages/frontend/src/pages/admin/custom-emojis-manager.register.vue4
-rw-r--r--packages/frontend/src/pages/admin/federation-job-queue.chart.chart.vue8
-rw-r--r--packages/frontend/src/pages/admin/job-queue.vue2
-rw-r--r--packages/frontend/src/pages/admin/overview.active-users.vue2
-rw-r--r--packages/frontend/src/pages/admin/overview.federation.vue8
-rw-r--r--packages/frontend/src/pages/admin/overview.heatmap.vue3
-rw-r--r--packages/frontend/src/pages/admin/overview.pie.vue13
-rw-r--r--packages/frontend/src/pages/admin/overview.queue.chart.vue12
-rw-r--r--packages/frontend/src/pages/admin/overview.queue.vue18
-rw-r--r--packages/frontend/src/pages/admin/overview.stats.vue15
-rw-r--r--packages/frontend/src/pages/admin/overview.vue2
-rw-r--r--packages/frontend/src/pages/admin/roles.editor.vue1
-rw-r--r--packages/frontend/src/pages/admin/roles.role.vue2
-rw-r--r--packages/frontend/src/pages/admin/roles.vue7
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);