refactor(frontend): 非推奨となったReactivity Transformを使わないように (#12539)

* refactor(frontend): 非推奨となったReactivity Transformを使わないように

* refactor: 不要な括弧を除去

* fix: 不要なアノテーションを除去

* fix: Refの配列をrefしている部分の対応

* refactor: 不要な括弧を除去

* fix: lint

* refactor: Ref、ShallowRef、ComputedRefの変数の宣言をletからconstに置換

* fix: type error

* chore: drop reactivity transform from eslint configuration

* refactor: remove unnecessary import

* fix: 対応漏れ
This commit is contained in:
zyoshoka
2023-12-07 14:42:09 +09:00
committed by GitHub
parent e42c91dee7
commit 406b4bdbe7
277 changed files with 3353 additions and 3441 deletions

View File

@@ -69,7 +69,7 @@ const metadata = injectPageMetadata();
const el = shallowRef<HTMLElement>(null);
const tabRefs = {};
const tabHighlightEl = $shallowRef<HTMLElement | null>(null);
const tabHighlightEl = shallowRef<HTMLElement | null>(null);
const bg = ref(null);
const height = ref(0);
const hasTabs = computed(() => {
@@ -131,13 +131,13 @@ onMounted(() => {
watch(() => [props.tab, props.tabs], () => {
nextTick(() => {
const tabEl = tabRefs[props.tab];
if (tabEl && tabHighlightEl) {
if (tabEl && tabHighlightEl.value) {
// offsetWidth や offsetLeft は少数を丸めてしまうため getBoundingClientRect を使う必要がある
// https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetWidth#%E5%80%A4
const parentRect = tabEl.parentElement.getBoundingClientRect();
const rect = tabEl.getBoundingClientRect();
tabHighlightEl.style.width = rect.width + 'px';
tabHighlightEl.style.left = (rect.left - parentRect.left) + 'px';
tabHighlightEl.value.style.width = rect.width + 'px';
tabHighlightEl.value.style.left = (rect.left - parentRect.left) + 'px';
}
});
}, {

View File

@@ -52,7 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, shallowRef, ref } from 'vue';
import XHeader from './_header_.vue';
import MkSelect from '@/components/MkSelect.vue';
@@ -61,31 +61,31 @@ import XAbuseReport from '@/components/MkAbuseReport.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let reports = $shallowRef<InstanceType<typeof MkPagination>>();
const reports = shallowRef<InstanceType<typeof MkPagination>>();
let state = $ref('unresolved');
let reporterOrigin = $ref('combined');
let targetUserOrigin = $ref('combined');
let searchUsername = $ref('');
let searchHost = $ref('');
const state = ref('unresolved');
const reporterOrigin = ref('combined');
const targetUserOrigin = ref('combined');
const searchUsername = ref('');
const searchHost = ref('');
const pagination = {
endpoint: 'admin/abuse-user-reports' as const,
limit: 10,
params: computed(() => ({
state,
reporterOrigin,
targetUserOrigin,
state: state.value,
reporterOrigin: reporterOrigin.value,
targetUserOrigin: targetUserOrigin.value,
})),
};
function resolved(reportId) {
reports.removeItem(reportId);
reports.value.removeItem(reportId);
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.abuseReports,

View File

@@ -85,7 +85,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
@@ -98,7 +98,7 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let ads: any[] = $ref([]);
const ads = ref<any[]>([]);
// ISO形式はTZがUTCになってしまうので、TZ分ずらして時間を初期化
const localTime = new Date();
@@ -109,7 +109,7 @@ let publishing: boolean | null = null;
os.api('admin/ad/list', { publishing: publishing }).then(adsResponse => {
if (adsResponse != null) {
ads = adsResponse.map(r => {
ads.value = adsResponse.map(r => {
const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt);
exdate.setMilliseconds(exdate.getMilliseconds() - localTimeDiff);
@@ -141,7 +141,7 @@ function toggleDayOfWeek(ad, index) {
}
function add() {
ads.unshift({
ads.value.unshift({
id: null,
memo: '',
place: 'square',
@@ -161,7 +161,7 @@ function remove(ad) {
text: i18n.t('removeAreYouSure', { x: ad.url }),
}).then(({ canceled }) => {
if (canceled) return;
ads = ads.filter(x => x !== ad);
ads.value = ads.value.filter(x => x !== ad);
if (ad.id == null) return;
os.apiWithDialog('admin/ad/delete', {
id: ad.id,
@@ -209,9 +209,9 @@ function save(ad) {
}
function more() {
os.api('admin/ad/list', { untilId: ads.reduce((acc, ad) => ad.id != null ? ad : acc).id, publishing: publishing }).then(adsResponse => {
os.api('admin/ad/list', { untilId: ads.value.reduce((acc, ad) => ad.id != null ? ad : acc).id, publishing: publishing }).then(adsResponse => {
if (adsResponse == null) return;
ads = ads.concat(adsResponse.map(r => {
ads.value = ads.value.concat(adsResponse.map(r => {
const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt);
exdate.setMilliseconds(exdate.getMilliseconds() - localTimeDiff);
@@ -228,7 +228,7 @@ function more() {
function refresh() {
os.api('admin/ad/list', { publishing: publishing }).then(adsResponse => {
if (adsResponse == null) return;
ads = adsResponse.map(r => {
ads.value = adsResponse.map(r => {
const exdate = new Date(r.expiresAt);
const stdate = new Date(r.startsAt);
exdate.setMilliseconds(exdate.getMilliseconds() - localTimeDiff);
@@ -244,14 +244,14 @@ function refresh() {
refresh();
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
asFullButton: true,
icon: 'ti ti-plus',
text: i18n.ts.add,
handler: add,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.ads,

View File

@@ -71,7 +71,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
@@ -84,14 +84,14 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkFolder from '@/components/MkFolder.vue';
let announcements: any[] = $ref([]);
const announcements = ref<any[]>([]);
os.api('admin/announcements/list').then(announcementResponse => {
announcements = announcementResponse;
announcements.value = announcementResponse;
});
function add() {
announcements.unshift({
announcements.value.unshift({
_id: Math.random().toString(36),
id: null,
title: 'New announcement',
@@ -111,7 +111,7 @@ function del(announcement) {
text: i18n.t('deleteAreYouSure', { x: announcement.title }),
}).then(({ canceled }) => {
if (canceled) return;
announcements = announcements.filter(x => x !== announcement);
announcements.value = announcements.value.filter(x => x !== announcement);
os.api('admin/announcements/delete', announcement);
});
}
@@ -134,27 +134,27 @@ async function save(announcement) {
}
function more() {
os.api('admin/announcements/list', { untilId: announcements.reduce((acc, announcement) => announcement.id != null ? announcement : acc).id }).then(announcementResponse => {
announcements = announcements.concat(announcementResponse);
os.api('admin/announcements/list', { untilId: announcements.value.reduce((acc, announcement) => announcement.id != null ? announcement : acc).id }).then(announcementResponse => {
announcements.value = announcements.value.concat(announcementResponse);
});
}
function refresh() {
os.api('admin/announcements/list').then(announcementResponse => {
announcements = announcementResponse;
announcements.value = announcementResponse;
});
}
refresh();
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
asFullButton: true,
icon: 'ti ti-plus',
text: i18n.ts.add,
handler: add,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.announcements,

View File

@@ -64,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue';
import { defineAsyncComponent, ref } from 'vue';
import MkRadios from '@/components/MkRadios.vue';
import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
@@ -76,37 +76,37 @@ import { i18n } from '@/i18n.js';
const MkCaptcha = defineAsyncComponent(() => import('@/components/MkCaptcha.vue'));
let provider = $ref(null);
let hcaptchaSiteKey: string | null = $ref(null);
let hcaptchaSecretKey: string | null = $ref(null);
let recaptchaSiteKey: string | null = $ref(null);
let recaptchaSecretKey: string | null = $ref(null);
let turnstileSiteKey: string | null = $ref(null);
let turnstileSecretKey: string | null = $ref(null);
const provider = ref(null);
const hcaptchaSiteKey = ref<string | null>(null);
const hcaptchaSecretKey = ref<string | null>(null);
const recaptchaSiteKey = ref<string | null>(null);
const recaptchaSecretKey = ref<string | null>(null);
const turnstileSiteKey = ref<string | null>(null);
const turnstileSecretKey = ref<string | null>(null);
async function init() {
const meta = await os.api('admin/meta');
hcaptchaSiteKey = meta.hcaptchaSiteKey;
hcaptchaSecretKey = meta.hcaptchaSecretKey;
recaptchaSiteKey = meta.recaptchaSiteKey;
recaptchaSecretKey = meta.recaptchaSecretKey;
turnstileSiteKey = meta.turnstileSiteKey;
turnstileSecretKey = meta.turnstileSecretKey;
hcaptchaSiteKey.value = meta.hcaptchaSiteKey;
hcaptchaSecretKey.value = meta.hcaptchaSecretKey;
recaptchaSiteKey.value = meta.recaptchaSiteKey;
recaptchaSecretKey.value = meta.recaptchaSecretKey;
turnstileSiteKey.value = meta.turnstileSiteKey;
turnstileSecretKey.value = meta.turnstileSecretKey;
provider = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : meta.enableTurnstile ? 'turnstile' : null;
provider.value = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : meta.enableTurnstile ? 'turnstile' : null;
}
function save() {
os.apiWithDialog('admin/update-meta', {
enableHcaptcha: provider === 'hcaptcha',
hcaptchaSiteKey,
hcaptchaSecretKey,
enableRecaptcha: provider === 'recaptcha',
recaptchaSiteKey,
recaptchaSecretKey,
enableTurnstile: provider === 'turnstile',
turnstileSiteKey,
turnstileSecretKey,
enableHcaptcha: provider.value === 'hcaptcha',
hcaptchaSiteKey: hcaptchaSiteKey.value,
hcaptchaSecretKey: hcaptchaSecretKey.value,
enableRecaptcha: provider.value === 'recaptcha',
recaptchaSiteKey: recaptchaSiteKey.value,
recaptchaSecretKey: recaptchaSecretKey.value,
enableTurnstile: provider.value === 'turnstile',
turnstileSiteKey: turnstileSiteKey.value,
turnstileSecretKey: turnstileSecretKey.value,
}).then(() => {
fetchInstance();
});

View File

@@ -94,7 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import JSON5 from 'json5';
import XHeader from './_header_.vue';
import MkSwitch from '@/components/MkSwitch.vue';
@@ -111,55 +111,55 @@ import MkButton from '@/components/MkButton.vue';
import MkColorInput from '@/components/MkColorInput.vue';
import { host } from '@/config.js';
let iconUrl: string | null = $ref(null);
let app192IconUrl: string | null = $ref(null);
let app512IconUrl: string | null = $ref(null);
let bannerUrl: string | null = $ref(null);
let backgroundImageUrl: string | null = $ref(null);
let themeColor: any = $ref(null);
let defaultLightTheme: any = $ref(null);
let defaultDarkTheme: any = $ref(null);
let serverErrorImageUrl: string | null = $ref(null);
let infoImageUrl: string | null = $ref(null);
let notFoundImageUrl: string | null = $ref(null);
let manifestJsonOverride: string = $ref('{}');
const iconUrl = ref<string | null>(null);
const app192IconUrl = ref<string | null>(null);
const app512IconUrl = ref<string | null>(null);
const bannerUrl = ref<string | null>(null);
const backgroundImageUrl = ref<string | null>(null);
const themeColor = ref<any>(null);
const defaultLightTheme = ref<any>(null);
const defaultDarkTheme = ref<any>(null);
const serverErrorImageUrl = ref<string | null>(null);
const infoImageUrl = ref<string | null>(null);
const notFoundImageUrl = ref<string | null>(null);
const manifestJsonOverride = ref<string>('{}');
async function init() {
const meta = await os.api('admin/meta');
iconUrl = meta.iconUrl;
app192IconUrl = meta.app192IconUrl;
app512IconUrl = meta.app512IconUrl;
bannerUrl = meta.bannerUrl;
backgroundImageUrl = meta.backgroundImageUrl;
themeColor = meta.themeColor;
defaultLightTheme = meta.defaultLightTheme;
defaultDarkTheme = meta.defaultDarkTheme;
serverErrorImageUrl = meta.serverErrorImageUrl;
infoImageUrl = meta.infoImageUrl;
notFoundImageUrl = meta.notFoundImageUrl;
manifestJsonOverride = meta.manifestJsonOverride === '' ? '{}' : JSON.stringify(JSON.parse(meta.manifestJsonOverride), null, '\t');
iconUrl.value = meta.iconUrl;
app192IconUrl.value = meta.app192IconUrl;
app512IconUrl.value = meta.app512IconUrl;
bannerUrl.value = meta.bannerUrl;
backgroundImageUrl.value = meta.backgroundImageUrl;
themeColor.value = meta.themeColor;
defaultLightTheme.value = meta.defaultLightTheme;
defaultDarkTheme.value = meta.defaultDarkTheme;
serverErrorImageUrl.value = meta.serverErrorImageUrl;
infoImageUrl.value = meta.infoImageUrl;
notFoundImageUrl.value = meta.notFoundImageUrl;
manifestJsonOverride.value = meta.manifestJsonOverride === '' ? '{}' : JSON.stringify(JSON.parse(meta.manifestJsonOverride), null, '\t');
}
function save() {
os.apiWithDialog('admin/update-meta', {
iconUrl,
app192IconUrl,
app512IconUrl,
bannerUrl,
backgroundImageUrl,
themeColor: themeColor === '' ? null : themeColor,
defaultLightTheme: defaultLightTheme === '' ? null : defaultLightTheme,
defaultDarkTheme: defaultDarkTheme === '' ? null : defaultDarkTheme,
infoImageUrl,
notFoundImageUrl,
serverErrorImageUrl,
manifestJsonOverride: manifestJsonOverride === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride)),
iconUrl: iconUrl.value,
app192IconUrl: app192IconUrl.value,
app512IconUrl: app512IconUrl.value,
bannerUrl: bannerUrl.value,
backgroundImageUrl: backgroundImageUrl.value,
themeColor: themeColor.value === '' ? null : themeColor.value,
defaultLightTheme: defaultLightTheme.value === '' ? null : defaultLightTheme.value,
defaultDarkTheme: defaultDarkTheme.value === '' ? null : defaultDarkTheme.value,
infoImageUrl: infoImageUrl.value,
notFoundImageUrl: notFoundImageUrl.value,
serverErrorImageUrl: serverErrorImageUrl.value,
manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)),
}).then(() => {
fetchInstance();
});
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.branding,

View File

@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { computed } from 'vue';
import FormSuspense from '@/components/form/suspense.vue';
import MkKeyValue from '@/components/MkKeyValue.vue';
import * as os from '@/os.js';
@@ -29,9 +29,9 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
const databasePromiseFactory = () => os.api('admin/get-table-stats').then(res => Object.entries(res).sort((a, b) => b[1].size - a[1].size));
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.database,

View File

@@ -64,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInput from '@/components/MkInput.vue';
@@ -78,23 +78,23 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
let enableEmail: boolean = $ref(false);
let email: any = $ref(null);
let smtpSecure: boolean = $ref(false);
let smtpHost: string = $ref('');
let smtpPort: number = $ref(0);
let smtpUser: string = $ref('');
let smtpPass: string = $ref('');
const enableEmail = ref<boolean>(false);
const email = ref<any>(null);
const smtpSecure = ref<boolean>(false);
const smtpHost = ref<string>('');
const smtpPort = ref<number>(0);
const smtpUser = ref<string>('');
const smtpPass = ref<string>('');
async function init() {
const meta = await os.api('admin/meta');
enableEmail = meta.enableEmail;
email = meta.email;
smtpSecure = meta.smtpSecure;
smtpHost = meta.smtpHost;
smtpPort = meta.smtpPort;
smtpUser = meta.smtpUser;
smtpPass = meta.smtpPass;
enableEmail.value = meta.enableEmail;
email.value = meta.email;
smtpSecure.value = meta.smtpSecure;
smtpHost.value = meta.smtpHost;
smtpPort.value = meta.smtpPort;
smtpUser.value = meta.smtpUser;
smtpPass.value = meta.smtpPass;
}
async function testEmail() {
@@ -115,19 +115,19 @@ async function testEmail() {
function save() {
os.apiWithDialog('admin/update-meta', {
enableEmail,
email,
smtpSecure,
smtpHost,
smtpPort,
smtpUser,
smtpPass,
enableEmail: enableEmail.value,
email: email.value,
smtpSecure: smtpSecure.value,
smtpHost: smtpHost.value,
smtpPort: smtpPort.value,
smtpUser: smtpUser.value,
smtpPass: smtpPass.value,
}).then(() => {
fetchInstance();
});
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.emailServer,

View File

@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
@@ -46,27 +46,27 @@ import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let deeplAuthKey: string = $ref('');
let deeplIsPro: boolean = $ref(false);
const deeplAuthKey = ref<string>('');
const deeplIsPro = ref<boolean>(false);
async function init() {
const meta = await os.api('admin/meta');
deeplAuthKey = meta.deeplAuthKey;
deeplIsPro = meta.deeplIsPro;
deeplAuthKey.value = meta.deeplAuthKey;
deeplIsPro.value = meta.deeplIsPro;
}
function save() {
os.apiWithDialog('admin/update-meta', {
deeplAuthKey,
deeplIsPro,
deeplAuthKey: deeplAuthKey.value,
deeplIsPro: deeplIsPro.value,
}).then(() => {
fetchInstance();
});
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.externalServices,

View File

@@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, ref } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkSelect from '@/components/MkSelect.vue';
@@ -68,24 +68,24 @@ import FormSplit from '@/components/form/split.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let host = $ref('');
let state = $ref('federating');
let sort = $ref('+pubSub');
const host = ref('');
const state = ref('federating');
const sort = ref('+pubSub');
const pagination = {
endpoint: 'federation/instances' as const,
limit: 10,
offsetMode: true,
params: computed(() => ({
sort: sort,
host: host !== '' ? host : null,
sort: sort.value,
host: host.value !== '' ? host.value : null,
...(
state === 'federating' ? { federating: true } :
state === 'subscribing' ? { subscribing: true } :
state === 'publishing' ? { publishing: true } :
state === 'suspended' ? { suspended: true } :
state === 'blocked' ? { blocked: true } :
state === 'silenced' ? { silenced: true } :
state === 'notResponding' ? { notResponding: true } :
state.value === 'federating' ? { federating: true } :
state.value === 'subscribing' ? { subscribing: true } :
state.value === 'publishing' ? { publishing: true } :
state.value === 'suspended' ? { suspended: true } :
state.value === 'blocked' ? { blocked: true } :
state.value === 'silenced' ? { silenced: true } :
state.value === 'notResponding' ? { notResponding: true } :
{}),
})),
};
@@ -98,9 +98,9 @@ function getStatus(instance) {
return 'Alive';
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => ({
title: i18n.ts.federation,

View File

@@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, ref } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkSelect from '@/components/MkSelect.vue';
@@ -45,19 +45,19 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let origin = $ref('local');
let type = $ref(null);
let searchHost = $ref('');
let userId = $ref('');
let viewMode = $ref('grid');
const origin = ref('local');
const type = ref(null);
const searchHost = ref('');
const userId = ref('');
const viewMode = ref('grid');
const pagination = {
endpoint: 'admin/drive/files' as const,
limit: 10,
params: computed(() => ({
type: (type && type !== '') ? type : null,
userId: (userId && userId !== '') ? userId : null,
origin: origin,
hostname: (searchHost && searchHost !== '') ? searchHost : null,
type: (type.value && type.value !== '') ? type.value : null,
userId: (userId.value && userId.value !== '') ? userId.value : null,
origin: origin.value,
hostname: (searchHost.value && searchHost.value !== '') ? searchHost.value : null,
})),
};
@@ -95,7 +95,7 @@ async function find() {
});
}
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
text: i18n.ts.lookup,
icon: 'ti ti-search',
handler: find,
@@ -105,7 +105,7 @@ const headerActions = $computed(() => [{
handler: clear,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => ({
title: i18n.ts.files,

View File

@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onActivated, onMounted, onUnmounted, provide, watch } from 'vue';
import { onActivated, onMounted, onUnmounted, provide, watch, ref, computed } from 'vue';
import { i18n } from '@/i18n.js';
import MkSuperMenu from '@/components/MkSuperMenu.vue';
import MkInfo from '@/components/MkInfo.vue';
@@ -50,32 +50,32 @@ const indexInfo = {
provide('shouldOmitHeaderTitle', false);
let INFO = $ref(indexInfo);
let childInfo = $ref(null);
let narrow = $ref(false);
let view = $ref(null);
let el = $ref(null);
let pageProps = $ref({});
const INFO = ref(indexInfo);
const childInfo = ref(null);
const narrow = ref(false);
const view = ref(null);
const el = ref(null);
const pageProps = ref({});
let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile;
let noEmailServer = !instance.enableEmail;
let thereIsUnresolvedAbuseReport = $ref(false);
let currentPage = $computed(() => router.currentRef.value.child);
const thereIsUnresolvedAbuseReport = ref(false);
const currentPage = computed(() => router.currentRef.value.child);
os.api('admin/abuse-user-reports', {
state: 'unresolved',
limit: 1,
}).then(reports => {
if (reports.length > 0) thereIsUnresolvedAbuseReport = true;
if (reports.length > 0) thereIsUnresolvedAbuseReport.value = true;
});
const NARROW_THRESHOLD = 600;
const ro = new ResizeObserver((entries, observer) => {
if (entries.length === 0) return;
narrow = entries[0].borderBoxSize[0].inlineSize < NARROW_THRESHOLD;
narrow.value = entries[0].borderBoxSize[0].inlineSize < NARROW_THRESHOLD;
});
const menuDef = $computed(() => [{
const menuDef = computed(() => [{
title: i18n.ts.quickAction,
items: [{
type: 'button',
@@ -94,67 +94,67 @@ const menuDef = $computed(() => [{
icon: 'ti ti-dashboard',
text: i18n.ts.dashboard,
to: '/admin/overview',
active: currentPage?.route.name === 'overview',
active: currentPage.value?.route.name === 'overview',
}, {
icon: 'ti ti-users',
text: i18n.ts.users,
to: '/admin/users',
active: currentPage?.route.name === 'users',
active: currentPage.value?.route.name === 'users',
}, {
icon: 'ti ti-user-plus',
text: i18n.ts.invite,
to: '/admin/invites',
active: currentPage?.route.name === 'invites',
active: currentPage.value?.route.name === 'invites',
}, {
icon: 'ti ti-badges',
text: i18n.ts.roles,
to: '/admin/roles',
active: currentPage?.route.name === 'roles',
active: currentPage.value?.route.name === 'roles',
}, {
icon: 'ti ti-icons',
text: i18n.ts.customEmojis,
to: '/admin/emojis',
active: currentPage?.route.name === 'emojis',
active: currentPage.value?.route.name === 'emojis',
}, {
icon: 'ti ti-sparkles',
text: i18n.ts.avatarDecorations,
to: '/admin/avatar-decorations',
active: currentPage?.route.name === 'avatarDecorations',
active: currentPage.value?.route.name === 'avatarDecorations',
}, {
icon: 'ti ti-whirl',
text: i18n.ts.federation,
to: '/admin/federation',
active: currentPage?.route.name === 'federation',
active: currentPage.value?.route.name === 'federation',
}, {
icon: 'ti ti-clock-play',
text: i18n.ts.jobQueue,
to: '/admin/queue',
active: currentPage?.route.name === 'queue',
active: currentPage.value?.route.name === 'queue',
}, {
icon: 'ti ti-cloud',
text: i18n.ts.files,
to: '/admin/files',
active: currentPage?.route.name === 'files',
active: currentPage.value?.route.name === 'files',
}, {
icon: 'ti ti-speakerphone',
text: i18n.ts.announcements,
to: '/admin/announcements',
active: currentPage?.route.name === 'announcements',
active: currentPage.value?.route.name === 'announcements',
}, {
icon: 'ti ti-ad',
text: i18n.ts.ads,
to: '/admin/ads',
active: currentPage?.route.name === 'ads',
active: currentPage.value?.route.name === 'ads',
}, {
icon: 'ti ti-exclamation-circle',
text: i18n.ts.abuseReports,
to: '/admin/abuses',
active: currentPage?.route.name === 'abuses',
active: currentPage.value?.route.name === 'abuses',
}, {
icon: 'ti ti-list-search',
text: i18n.ts.moderationLogs,
to: '/admin/modlog',
active: currentPage?.route.name === 'modlog',
active: currentPage.value?.route.name === 'modlog',
}],
}, {
title: i18n.ts.settings,
@@ -162,57 +162,57 @@ const menuDef = $computed(() => [{
icon: 'ti ti-settings',
text: i18n.ts.general,
to: '/admin/settings',
active: currentPage?.route.name === 'settings',
active: currentPage.value?.route.name === 'settings',
}, {
icon: 'ti ti-paint',
text: i18n.ts.branding,
to: '/admin/branding',
active: currentPage?.route.name === 'branding',
active: currentPage.value?.route.name === 'branding',
}, {
icon: 'ti ti-shield',
text: i18n.ts.moderation,
to: '/admin/moderation',
active: currentPage?.route.name === 'moderation',
active: currentPage.value?.route.name === 'moderation',
}, {
icon: 'ti ti-mail',
text: i18n.ts.emailServer,
to: '/admin/email-settings',
active: currentPage?.route.name === 'email-settings',
active: currentPage.value?.route.name === 'email-settings',
}, {
icon: 'ti ti-cloud',
text: i18n.ts.objectStorage,
to: '/admin/object-storage',
active: currentPage?.route.name === 'object-storage',
active: currentPage.value?.route.name === 'object-storage',
}, {
icon: 'ti ti-lock',
text: i18n.ts.security,
to: '/admin/security',
active: currentPage?.route.name === 'security',
active: currentPage.value?.route.name === 'security',
}, {
icon: 'ti ti-planet',
text: i18n.ts.relays,
to: '/admin/relays',
active: currentPage?.route.name === 'relays',
active: currentPage.value?.route.name === 'relays',
}, {
icon: 'ti ti-ban',
text: i18n.ts.instanceBlocking,
to: '/admin/instance-block',
active: currentPage?.route.name === 'instance-block',
active: currentPage.value?.route.name === 'instance-block',
}, {
icon: 'ti ti-ghost',
text: i18n.ts.proxyAccount,
to: '/admin/proxy-account',
active: currentPage?.route.name === 'proxy-account',
active: currentPage.value?.route.name === 'proxy-account',
}, {
icon: 'ti ti-link',
text: i18n.ts.externalServices,
to: '/admin/external-services',
active: currentPage?.route.name === 'external-services',
active: currentPage.value?.route.name === 'external-services',
}, {
icon: 'ti ti-adjustments',
text: i18n.ts.other,
to: '/admin/other-settings',
active: currentPage?.route.name === 'other-settings',
active: currentPage.value?.route.name === 'other-settings',
}],
}, {
title: i18n.ts.info,
@@ -220,28 +220,28 @@ const menuDef = $computed(() => [{
icon: 'ti ti-database',
text: i18n.ts.database,
to: '/admin/database',
active: currentPage?.route.name === 'database',
active: currentPage.value?.route.name === 'database',
}],
}]);
watch(narrow, () => {
if (currentPage?.route.name == null && !narrow) {
watch(narrow.value, () => {
if (currentPage.value?.route.name == null && !narrow.value) {
router.push('/admin/overview');
}
});
onMounted(() => {
ro.observe(el);
ro.observe(el.value);
narrow = el.offsetWidth < NARROW_THRESHOLD;
if (currentPage?.route.name == null && !narrow) {
narrow.value = el.value.offsetWidth < NARROW_THRESHOLD;
if (currentPage.value?.route.name == null && !narrow.value) {
router.push('/admin/overview');
}
});
onActivated(() => {
narrow = el.offsetWidth < NARROW_THRESHOLD;
if (currentPage?.route.name == null && !narrow) {
narrow.value = el.value.offsetWidth < NARROW_THRESHOLD;
if (currentPage.value?.route.name == null && !narrow.value) {
router.push('/admin/overview');
}
});
@@ -251,16 +251,16 @@ onUnmounted(() => {
});
watch(router.currentRef, (to) => {
if (to.route.path === '/admin' && to.child?.route.name == null && !narrow) {
if (to.route.path === '/admin' && to.child?.route.name == null && !narrow.value) {
router.replace('/admin/overview');
}
});
provideMetadataReceiver((info) => {
if (info == null) {
childInfo = null;
childInfo.value = null;
} else {
childInfo = info;
childInfo.value = info;
}
});
@@ -312,11 +312,11 @@ function lookup(ev: MouseEvent) {
}], ev.currentTarget ?? ev.target);
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(INFO);
definePageMetadata(INFO.value);
defineExpose({
header: {

View File

@@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkTextarea from '@/components/MkTextarea.vue';
@@ -32,29 +33,29 @@ import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let blockedHosts: string = $ref('');
let silencedHosts: string = $ref('');
let tab = $ref('block');
const blockedHosts = ref<string>('');
const silencedHosts = ref<string>('');
const tab = ref('block');
async function init() {
const meta = await os.api('admin/meta');
blockedHosts = meta.blockedHosts.join('\n');
silencedHosts = meta.silencedHosts.join('\n');
blockedHosts.value = meta.blockedHosts.join('\n');
silencedHosts.value = meta.silencedHosts.join('\n');
}
function save() {
os.apiWithDialog('admin/update-meta', {
blockedHosts: blockedHosts.split('\n') || [],
silencedHosts: silencedHosts.split('\n') || [],
blockedHosts: blockedHosts.value.split('\n') || [],
silencedHosts: silencedHosts.value.split('\n') || [],
}).then(() => {
fetchInstance();
});
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => [{
const headerTabs = computed(() => [{
key: 'block',
title: i18n.ts.block,
icon: 'ti ti-ban',

View File

@@ -70,8 +70,8 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
const pagingComponent = shallowRef<InstanceType<typeof MkPagination>>();
let type = ref('all');
let sort = ref('+createdAt');
const type = ref('all');
const sort = ref('+createdAt');
const pagination: Paging = {
endpoint: 'admin/invite/list' as const,
@@ -109,8 +109,8 @@ function deleted(id: string) {
}
}
const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.invite,

View File

@@ -59,7 +59,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInput from '@/components/MkInput.vue';
@@ -74,40 +74,40 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
import FormLink from '@/components/form/link.vue';
let enableRegistration: boolean = $ref(false);
let emailRequiredForSignup: boolean = $ref(false);
let sensitiveWords: string = $ref('');
let hiddenTags: string = $ref('');
let preservedUsernames: string = $ref('');
let tosUrl: string | null = $ref(null);
let privacyPolicyUrl: string | null = $ref(null);
const enableRegistration = ref<boolean>(false);
const emailRequiredForSignup = ref<boolean>(false);
const sensitiveWords = ref<string>('');
const hiddenTags = ref<string>('');
const preservedUsernames = ref<string>('');
const tosUrl = ref<string | null>(null);
const privacyPolicyUrl = ref<string | null>(null);
async function init() {
const meta = await os.api('admin/meta');
enableRegistration = !meta.disableRegistration;
emailRequiredForSignup = meta.emailRequiredForSignup;
sensitiveWords = meta.sensitiveWords.join('\n');
hiddenTags = meta.hiddenTags.join('\n');
preservedUsernames = meta.preservedUsernames.join('\n');
tosUrl = meta.tosUrl;
privacyPolicyUrl = meta.privacyPolicyUrl;
enableRegistration.value = !meta.disableRegistration;
emailRequiredForSignup.value = meta.emailRequiredForSignup;
sensitiveWords.value = meta.sensitiveWords.join('\n');
hiddenTags.value = meta.hiddenTags.join('\n');
preservedUsernames.value = meta.preservedUsernames.join('\n');
tosUrl.value = meta.tosUrl;
privacyPolicyUrl.value = meta.privacyPolicyUrl;
}
function save() {
os.apiWithDialog('admin/update-meta', {
disableRegistration: !enableRegistration,
emailRequiredForSignup,
tosUrl,
privacyPolicyUrl,
sensitiveWords: sensitiveWords.split('\n'),
hiddenTags: hiddenTags.split('\n'),
preservedUsernames: preservedUsernames.split('\n'),
disableRegistration: !enableRegistration.value,
emailRequiredForSignup: emailRequiredForSignup.value,
tosUrl: tosUrl.value,
privacyPolicyUrl: privacyPolicyUrl.value,
sensitiveWords: sensitiveWords.value.split('\n'),
hiddenTags: hiddenTags.value.split('\n'),
preservedUsernames: preservedUsernames.value.split('\n'),
}).then(() => {
fetchInstance();
});
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.moderation,

View File

@@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, shallowRef, ref } from 'vue';
import * as Misskey from 'misskey-js';
import XHeader from './_header_.vue';
import XModLog from './modlog.ModLog.vue';
@@ -40,25 +40,25 @@ import MkPagination from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let logs = $shallowRef<InstanceType<typeof MkPagination>>();
const logs = shallowRef<InstanceType<typeof MkPagination>>();
let type = $ref(null);
let moderatorId = $ref('');
const type = ref(null);
const moderatorId = ref('');
const pagination = {
endpoint: 'admin/show-moderation-logs' as const,
limit: 30,
params: computed(() => ({
type,
userId: moderatorId === '' ? null : moderatorId,
type: type.value,
userId: moderatorId.value === '' ? null : moderatorId.value,
})),
};
console.log(Misskey);
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.moderationLogs,

View File

@@ -83,7 +83,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInput from '@/components/MkInput.vue';
@@ -95,58 +95,58 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
let useObjectStorage: boolean = $ref(false);
let objectStorageBaseUrl: string | null = $ref(null);
let objectStorageBucket: string | null = $ref(null);
let objectStoragePrefix: string | null = $ref(null);
let objectStorageEndpoint: string | null = $ref(null);
let objectStorageRegion: string | null = $ref(null);
let objectStoragePort: number | null = $ref(null);
let objectStorageAccessKey: string | null = $ref(null);
let objectStorageSecretKey: string | null = $ref(null);
let objectStorageUseSSL: boolean = $ref(false);
let objectStorageUseProxy: boolean = $ref(false);
let objectStorageSetPublicRead: boolean = $ref(false);
let objectStorageS3ForcePathStyle: boolean = $ref(true);
const useObjectStorage = ref<boolean>(false);
const objectStorageBaseUrl = ref<string | null>(null);
const objectStorageBucket = ref<string | null>(null);
const objectStoragePrefix = ref<string | null>(null);
const objectStorageEndpoint = ref<string | null>(null);
const objectStorageRegion = ref<string | null>(null);
const objectStoragePort = ref<number | null>(null);
const objectStorageAccessKey = ref<string | null>(null);
const objectStorageSecretKey = ref<string | null>(null);
const objectStorageUseSSL = ref<boolean>(false);
const objectStorageUseProxy = ref<boolean>(false);
const objectStorageSetPublicRead = ref<boolean>(false);
const objectStorageS3ForcePathStyle = ref<boolean>(true);
async function init() {
const meta = await os.api('admin/meta');
useObjectStorage = meta.useObjectStorage;
objectStorageBaseUrl = meta.objectStorageBaseUrl;
objectStorageBucket = meta.objectStorageBucket;
objectStoragePrefix = meta.objectStoragePrefix;
objectStorageEndpoint = meta.objectStorageEndpoint;
objectStorageRegion = meta.objectStorageRegion;
objectStoragePort = meta.objectStoragePort;
objectStorageAccessKey = meta.objectStorageAccessKey;
objectStorageSecretKey = meta.objectStorageSecretKey;
objectStorageUseSSL = meta.objectStorageUseSSL;
objectStorageUseProxy = meta.objectStorageUseProxy;
objectStorageSetPublicRead = meta.objectStorageSetPublicRead;
objectStorageS3ForcePathStyle = meta.objectStorageS3ForcePathStyle;
useObjectStorage.value = meta.useObjectStorage;
objectStorageBaseUrl.value = meta.objectStorageBaseUrl;
objectStorageBucket.value = meta.objectStorageBucket;
objectStoragePrefix.value = meta.objectStoragePrefix;
objectStorageEndpoint.value = meta.objectStorageEndpoint;
objectStorageRegion.value = meta.objectStorageRegion;
objectStoragePort.value = meta.objectStoragePort;
objectStorageAccessKey.value = meta.objectStorageAccessKey;
objectStorageSecretKey.value = meta.objectStorageSecretKey;
objectStorageUseSSL.value = meta.objectStorageUseSSL;
objectStorageUseProxy.value = meta.objectStorageUseProxy;
objectStorageSetPublicRead.value = meta.objectStorageSetPublicRead;
objectStorageS3ForcePathStyle.value = meta.objectStorageS3ForcePathStyle;
}
function save() {
os.apiWithDialog('admin/update-meta', {
useObjectStorage,
objectStorageBaseUrl,
objectStorageBucket,
objectStoragePrefix,
objectStorageEndpoint,
objectStorageRegion,
objectStoragePort,
objectStorageAccessKey,
objectStorageSecretKey,
objectStorageUseSSL,
objectStorageUseProxy,
objectStorageSetPublicRead,
objectStorageS3ForcePathStyle,
useObjectStorage: useObjectStorage.value,
objectStorageBaseUrl: objectStorageBaseUrl.value,
objectStorageBucket: objectStorageBucket.value,
objectStoragePrefix: objectStoragePrefix.value,
objectStorageEndpoint: objectStorageEndpoint.value,
objectStorageRegion: objectStorageRegion.value,
objectStoragePort: objectStoragePort.value,
objectStorageAccessKey: objectStorageAccessKey.value,
objectStorageSecretKey: objectStorageSecretKey.value,
objectStorageUseSSL: objectStorageUseSSL.value,
objectStorageUseProxy: objectStorageUseProxy.value,
objectStorageSetPublicRead: objectStorageSetPublicRead.value,
objectStorageS3ForcePathStyle: objectStorageS3ForcePathStyle.value,
}).then(() => {
fetchInstance();
});
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.objectStorage,

View File

@@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import FormSuspense from '@/components/form/suspense.vue';
import * as os from '@/os.js';
@@ -52,38 +52,38 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkSwitch from '@/components/MkSwitch.vue';
let enableServerMachineStats: boolean = $ref(false);
let enableIdenticonGeneration: boolean = $ref(false);
let enableChartsForRemoteUser: boolean = $ref(false);
let enableChartsForFederatedInstances: boolean = $ref(false);
const enableServerMachineStats = ref<boolean>(false);
const enableIdenticonGeneration = ref<boolean>(false);
const enableChartsForRemoteUser = ref<boolean>(false);
const enableChartsForFederatedInstances = ref<boolean>(false);
async function init() {
const meta = await os.api('admin/meta');
enableServerMachineStats = meta.enableServerMachineStats;
enableIdenticonGeneration = meta.enableIdenticonGeneration;
enableChartsForRemoteUser = meta.enableChartsForRemoteUser;
enableChartsForFederatedInstances = meta.enableChartsForFederatedInstances;
enableServerMachineStats.value = meta.enableServerMachineStats;
enableIdenticonGeneration.value = meta.enableIdenticonGeneration;
enableChartsForRemoteUser.value = meta.enableChartsForRemoteUser;
enableChartsForFederatedInstances.value = meta.enableChartsForFederatedInstances;
}
function save() {
os.apiWithDialog('admin/update-meta', {
enableServerMachineStats,
enableIdenticonGeneration,
enableChartsForRemoteUser,
enableChartsForFederatedInstances,
enableServerMachineStats: enableServerMachineStats.value,
enableIdenticonGeneration: enableIdenticonGeneration.value,
enableChartsForRemoteUser: enableChartsForRemoteUser.value,
enableChartsForFederatedInstances: enableChartsForFederatedInstances.value,
}).then(() => {
fetchInstance();
});
}
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
asFullButton: true,
icon: 'ti ti-check',
text: i18n.ts.save,
handler: save,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.other,

View File

@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, shallowRef, ref } from 'vue';
import { Chart } from 'chart.js';
import gradient from 'chartjs-plugin-gradient';
import * as os from '@/os.js';
@@ -24,11 +24,11 @@ import { initChart } from '@/scripts/init-chart.js';
initChart();
const chartEl = $shallowRef<HTMLCanvasElement>(null);
const chartEl = shallowRef<HTMLCanvasElement>(null);
const now = new Date();
let chartInstance: Chart = null;
const chartLimit = 7;
let fetching = $ref(true);
const fetching = ref(true);
const { handler: externalTooltipHandler } = useChartTooltip();
@@ -61,7 +61,7 @@ async function renderChart() {
const max = Math.max(...raw.read);
chartInstance = new Chart(chartEl, {
chartInstance = new Chart(chartEl.value, {
type: 'bar',
data: {
datasets: [{
@@ -155,7 +155,7 @@ async function renderChart() {
plugins: [chartVLine(vLineColor)],
});
fetching = false;
fetching.value = false;
}
onMounted(async () => {

View File

@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, shallowRef, ref } from 'vue';
import { Chart } from 'chart.js';
import gradient from 'chartjs-plugin-gradient';
import * as os from '@/os.js';
@@ -33,9 +33,9 @@ import { initChart } from '@/scripts/init-chart.js';
initChart();
const chartLimit = 50;
const chartEl = $shallowRef<HTMLCanvasElement>();
const chartEl2 = $shallowRef<HTMLCanvasElement>();
let fetching = $ref(true);
const chartEl = shallowRef<HTMLCanvasElement>();
const chartEl2 = shallowRef<HTMLCanvasElement>();
const fetching = ref(true);
const { handler: externalTooltipHandler } = useChartTooltip();
const { handler: externalTooltipHandler2 } = useChartTooltip();
@@ -74,7 +74,7 @@ onMounted(async () => {
const succMax = Math.max(...raw.deliverSucceeded);
const failMax = Math.max(...raw.deliverFailed);
new Chart(chartEl, {
new Chart(chartEl.value, {
type: 'line',
data: {
datasets: [{
@@ -178,7 +178,7 @@ onMounted(async () => {
plugins: [chartVLine(vLineColor)],
});
new Chart(chartEl2, {
new Chart(chartEl2.value, {
type: 'bar',
data: {
datasets: [{
@@ -265,7 +265,7 @@ onMounted(async () => {
plugins: [chartVLine(vLineColor)],
});
fetching = false;
fetching.value = false;
});
</script>

View File

@@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, ref } from 'vue';
import XPie from './overview.pie.vue';
import * as os from '@/os.js';
import number from '@/filters/number.js';
@@ -54,25 +54,25 @@ import MkNumberDiff from '@/components/MkNumberDiff.vue';
import { i18n } from '@/i18n.js';
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
let topSubInstancesForPie: any = $ref(null);
let topPubInstancesForPie: any = $ref(null);
let federationPubActive = $ref<number | null>(null);
let federationPubActiveDiff = $ref<number | null>(null);
let federationSubActive = $ref<number | null>(null);
let federationSubActiveDiff = $ref<number | null>(null);
let fetching = $ref(true);
const topSubInstancesForPie = ref<any>(null);
const topPubInstancesForPie = ref<any>(null);
const federationPubActive = ref<number | null>(null);
const federationPubActiveDiff = ref<number | null>(null);
const federationSubActive = ref<number | null>(null);
const federationSubActiveDiff = ref<number | null>(null);
const fetching = ref(true);
const { handler: externalTooltipHandler } = useChartTooltip();
onMounted(async () => {
const chart = await os.apiGet('charts/federation', { limit: 2, span: 'day' });
federationPubActive = chart.pubActive[0];
federationPubActiveDiff = chart.pubActive[0] - chart.pubActive[1];
federationSubActive = chart.subActive[0];
federationSubActiveDiff = chart.subActive[0] - chart.subActive[1];
federationPubActive.value = chart.pubActive[0];
federationPubActiveDiff.value = chart.pubActive[0] - chart.pubActive[1];
federationSubActive.value = chart.subActive[0];
federationSubActiveDiff.value = chart.subActive[0] - chart.subActive[1];
os.apiGet('federation/stats', { limit: 10 }).then(res => {
topSubInstancesForPie = res.topSubInstances.map(x => ({
topSubInstancesForPie.value = res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
@@ -80,7 +80,7 @@ onMounted(async () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowersCount }]);
topPubInstancesForPie = res.topPubInstances.map(x => ({
topPubInstancesForPie.value = res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
@@ -90,7 +90,7 @@ onMounted(async () => {
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowingCount }]);
});
fetching = false;
fetching.value = false;
});
</script>

View File

@@ -17,10 +17,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import MkHeatmap from '@/components/MkHeatmap.vue';
import MkSelect from '@/components/MkSelect.vue';
let src = $ref('active-users');
const src = ref('active-users');
</script>
<style lang="scss" module>

View File

@@ -17,21 +17,21 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, ref } from 'vue';
import * as os from '@/os.js';
import { defaultStore } from '@/store.js';
let moderators: any = $ref(null);
let fetching = $ref(true);
const moderators = ref<any>(null);
const fetching = ref(true);
onMounted(async () => {
moderators = await os.api('admin/show-users', {
moderators.value = await os.api('admin/show-users', {
sort: '+lastActiveDate',
state: 'adminOrModerator',
limit: 30,
});
fetching = false;
fetching.value = false;
});
</script>

View File

@@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { markRaw, onMounted, onUnmounted, ref } from 'vue';
import { markRaw, onMounted, onUnmounted, ref, shallowRef } from 'vue';
import XChart from './overview.queue.chart.vue';
import number from '@/filters/number.js';
import { useStream } from '@/stream.js';
@@ -46,10 +46,10 @@ const activeSincePrevTick = ref(0);
const active = ref(0);
const delayed = ref(0);
const waiting = ref(0);
let chartProcess = $shallowRef<InstanceType<typeof XChart>>();
let chartActive = $shallowRef<InstanceType<typeof XChart>>();
let chartDelayed = $shallowRef<InstanceType<typeof XChart>>();
let chartWaiting = $shallowRef<InstanceType<typeof XChart>>();
const chartProcess = shallowRef<InstanceType<typeof XChart>>();
const chartActive = shallowRef<InstanceType<typeof XChart>>();
const chartDelayed = shallowRef<InstanceType<typeof XChart>>();
const chartWaiting = shallowRef<InstanceType<typeof XChart>>();
const props = defineProps<{
domain: string;
@@ -61,10 +61,10 @@ const onStats = (stats) => {
delayed.value = stats[props.domain].delayed;
waiting.value = stats[props.domain].waiting;
chartProcess.pushData(stats[props.domain].activeSincePrevTick);
chartActive.pushData(stats[props.domain].active);
chartDelayed.pushData(stats[props.domain].delayed);
chartWaiting.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);
};
const onStatsLog = (statsLog) => {
@@ -80,10 +80,10 @@ const onStatsLog = (statsLog) => {
dataWaiting.push(stats[props.domain].waiting);
}
chartProcess.setData(dataProcess);
chartActive.setData(dataActive);
chartDelayed.setData(dataDelayed);
chartWaiting.setData(dataWaiting);
chartProcess.value.setData(dataProcess);
chartActive.value.setData(dataActive);
chartDelayed.value.setData(dataDelayed);
chartWaiting.value.setData(dataWaiting);
};
onMounted(() => {

View File

@@ -61,7 +61,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, ref } from 'vue';
import * as os from '@/os.js';
import MkNumberDiff from '@/components/MkNumberDiff.vue';
import MkNumber from '@/components/MkNumber.vue';
@@ -69,29 +69,29 @@ import { i18n } from '@/i18n.js';
import { customEmojis } from '@/custom-emojis.js';
import { defaultStore } from '@/store.js';
let stats: any = $ref(null);
let usersComparedToThePrevDay = $ref<number>();
let notesComparedToThePrevDay = $ref<number>();
let onlineUsersCount = $ref(0);
let fetching = $ref(true);
const stats = ref<any>(null);
const usersComparedToThePrevDay = ref<number>();
const notesComparedToThePrevDay = ref<number>();
const onlineUsersCount = ref(0);
const fetching = ref(true);
onMounted(async () => {
const [_stats, _onlineUsersCount] = await Promise.all([
os.api('stats', {}),
os.apiGet('get-online-users-count').then(res => res.count),
]);
stats = _stats;
onlineUsersCount = _onlineUsersCount;
stats.value = _stats;
onlineUsersCount.value = _onlineUsersCount;
os.apiGet('charts/users', { limit: 2, span: 'day' }).then(chart => {
usersComparedToThePrevDay = stats.originalUsersCount - chart.local.total[1];
usersComparedToThePrevDay.value = stats.value.originalUsersCount - chart.local.total[1];
});
os.apiGet('charts/notes', { limit: 2, span: 'day' }).then(chart => {
notesComparedToThePrevDay = stats.originalNotesCount - chart.local.total[1];
notesComparedToThePrevDay.value = stats.value.originalNotesCount - chart.local.total[1];
});
fetching = false;
fetching.value = false;
});
</script>

View File

@@ -17,13 +17,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import * as os from '@/os.js';
import { useInterval } from '@/scripts/use-interval.js';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import { defaultStore } from '@/store.js';
let newUsers = $ref(null);
let fetching = $ref(true);
const newUsers = ref(null);
const fetching = ref(true);
const fetch = async () => {
const _newUsers = await os.api('admin/show-users', {
@@ -31,8 +32,8 @@ const fetch = async () => {
sort: '+createdAt',
origin: 'local',
});
newUsers = _newUsers;
fetching = false;
newUsers.value = _newUsers;
fetching.value = false;
};
useInterval(fetch, 1000 * 60, {

View File

@@ -65,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { markRaw, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { markRaw, onMounted, onBeforeUnmount, nextTick, shallowRef, ref, computed } from 'vue';
import XFederation from './overview.federation.vue';
import XInstances from './overview.instances.vue';
import XQueue from './overview.queue.vue';
@@ -82,16 +82,16 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
const rootEl = $shallowRef<HTMLElement>();
let serverInfo: any = $ref(null);
let topSubInstancesForPie: any = $ref(null);
let topPubInstancesForPie: any = $ref(null);
let federationPubActive = $ref<number | null>(null);
let federationPubActiveDiff = $ref<number | null>(null);
let federationSubActive = $ref<number | null>(null);
let federationSubActiveDiff = $ref<number | null>(null);
let newUsers = $ref(null);
let activeInstances = $shallowRef(null);
const rootEl = shallowRef<HTMLElement>();
const serverInfo = ref<any>(null);
const topSubInstancesForPie = ref<any>(null);
const topPubInstancesForPie = ref<any>(null);
const federationPubActive = ref<number | null>(null);
const federationPubActiveDiff = ref<number | null>(null);
const federationSubActive = ref<number | null>(null);
const federationSubActiveDiff = ref<number | null>(null);
const newUsers = ref(null);
const activeInstances = shallowRef(null);
const queueStatsConnection = markRaw(useStream().useChannel('queueStats'));
const now = new Date();
const filesPagination = {
@@ -116,14 +116,14 @@ onMounted(async () => {
*/
os.apiGet('charts/federation', { limit: 2, span: 'day' }).then(chart => {
federationPubActive = chart.pubActive[0];
federationPubActiveDiff = chart.pubActive[0] - chart.pubActive[1];
federationSubActive = chart.subActive[0];
federationSubActiveDiff = chart.subActive[0] - chart.subActive[1];
federationPubActive.value = chart.pubActive[0];
federationPubActiveDiff.value = chart.pubActive[0] - chart.pubActive[1];
federationSubActive.value = chart.subActive[0];
federationSubActiveDiff.value = chart.subActive[0] - chart.subActive[1];
});
os.apiGet('federation/stats', { limit: 10 }).then(res => {
topSubInstancesForPie = res.topSubInstances.map(x => ({
topSubInstancesForPie.value = res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
@@ -131,7 +131,7 @@ onMounted(async () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowersCount }]);
topPubInstancesForPie = res.topPubInstances.map(x => ({
topPubInstancesForPie.value = res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
@@ -142,21 +142,21 @@ onMounted(async () => {
});
os.api('admin/server-info').then(serverInfoResponse => {
serverInfo = serverInfoResponse;
serverInfo.value = serverInfoResponse;
});
os.api('admin/show-users', {
limit: 5,
sort: '+createdAt',
}).then(res => {
newUsers = res;
newUsers.value = res;
});
os.api('federation/instances', {
sort: '+latestRequestReceivedAt',
limit: 25,
}).then(res => {
activeInstances = res;
activeInstances.value = res;
});
nextTick(() => {
@@ -171,9 +171,9 @@ onBeforeUnmount(() => {
queueStatsConnection.dispose();
});
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.dashboard,

View File

@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import MkKeyValue from '@/components/MkKeyValue.vue';
import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue';
@@ -31,36 +31,36 @@ import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let proxyAccount: any = $ref(null);
let proxyAccountId: any = $ref(null);
const proxyAccount = ref<any>(null);
const proxyAccountId = ref<any>(null);
async function init() {
const meta = await os.api('admin/meta');
proxyAccountId = meta.proxyAccountId;
if (proxyAccountId) {
proxyAccount = await os.api('users/show', { userId: proxyAccountId });
proxyAccountId.value = meta.proxyAccountId;
if (proxyAccountId.value) {
proxyAccount.value = await os.api('users/show', { userId: proxyAccountId.value });
}
}
function chooseProxyAccount() {
os.selectUser().then(user => {
proxyAccount = user;
proxyAccountId = user.id;
proxyAccount.value = user;
proxyAccountId.value = user.id;
save();
});
}
function save() {
os.apiWithDialog('admin/update-meta', {
proxyAccountId: proxyAccountId,
proxyAccountId: proxyAccountId.value,
}).then(() => {
fetchInstance();
});
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.proxyAccount,

View File

@@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { markRaw, onMounted, onUnmounted, ref } from 'vue';
import { markRaw, onMounted, onUnmounted, ref, shallowRef } from 'vue';
import XChart from './queue.chart.chart.vue';
import number from '@/filters/number.js';
import * as os from '@/os.js';
@@ -63,10 +63,10 @@ const active = ref(0);
const delayed = ref(0);
const waiting = ref(0);
const jobs = ref([]);
let chartProcess = $shallowRef<InstanceType<typeof XChart>>();
let chartActive = $shallowRef<InstanceType<typeof XChart>>();
let chartDelayed = $shallowRef<InstanceType<typeof XChart>>();
let chartWaiting = $shallowRef<InstanceType<typeof XChart>>();
const chartProcess = shallowRef<InstanceType<typeof XChart>>();
const chartActive = shallowRef<InstanceType<typeof XChart>>();
const chartDelayed = shallowRef<InstanceType<typeof XChart>>();
const chartWaiting = shallowRef<InstanceType<typeof XChart>>();
const props = defineProps<{
domain: string;
@@ -78,10 +78,10 @@ const onStats = (stats) => {
delayed.value = stats[props.domain].delayed;
waiting.value = stats[props.domain].waiting;
chartProcess.pushData(stats[props.domain].activeSincePrevTick);
chartActive.pushData(stats[props.domain].active);
chartDelayed.pushData(stats[props.domain].delayed);
chartWaiting.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);
};
const onStatsLog = (statsLog) => {
@@ -97,10 +97,10 @@ const onStatsLog = (statsLog) => {
dataWaiting.push(stats[props.domain].waiting);
}
chartProcess.setData(dataProcess);
chartActive.setData(dataActive);
chartDelayed.setData(dataDelayed);
chartWaiting.setData(dataWaiting);
chartProcess.value.setData(dataProcess);
chartActive.value.setData(dataActive);
chartDelayed.value.setData(dataDelayed);
chartWaiting.value.setData(dataWaiting);
};
onMounted(() => {

View File

@@ -16,6 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import XQueue from './queue.chart.vue';
import XHeader from './_header_.vue';
import * as os from '@/os.js';
@@ -24,7 +25,7 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
let tab = $ref('deliver');
const tab = ref('deliver');
function clear() {
os.confirm({
@@ -46,11 +47,11 @@ function promoteAllQueues() {
}).then(({ canceled }) => {
if (canceled) return;
os.apiWithDialog('admin/queue/promote', { type: tab });
os.apiWithDialog('admin/queue/promote', { type: tab.value });
});
}
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
asFullButton: true,
icon: 'ti ti-external-link',
text: i18n.ts.dashboard,
@@ -59,7 +60,7 @@ const headerActions = $computed(() => [{
},
}]);
const headerTabs = $computed(() => [{
const headerTabs = computed(() => [{
key: 'deliver',
title: 'Deliver',
}, {

View File

@@ -24,14 +24,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let relays: any[] = $ref([]);
const relays = ref<any[]>([]);
async function addRelay() {
const { canceled, result: inbox } = await os.inputText({
@@ -67,20 +67,20 @@ function remove(inbox: string) {
function refresh() {
os.api('admin/relays/list').then((relayList: any) => {
relays = relayList;
relays.value = relayList;
});
}
refresh();
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
asFullButton: true,
icon: 'ti ti-plus',
text: i18n.ts.addRelay,
handler: addRelay,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.relays,

View File

@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { v4 as uuid } from 'uuid';
import XHeader from './_header_.vue';
import XEditor from './roles.editor.vue';
@@ -39,17 +39,17 @@ const props = defineProps<{
id?: string;
}>();
let role = $ref(null);
let data = $ref(null);
const role = ref(null);
const data = ref(null);
if (props.id) {
role = await os.api('admin/roles/show', {
role.value = await os.api('admin/roles/show', {
roleId: props.id,
});
data = role;
data.value = role.value;
} else {
data = {
data.value = {
name: 'New Role',
description: '',
isAdministrator: false,
@@ -69,24 +69,24 @@ if (props.id) {
async function save() {
rolesCache.delete();
if (role) {
if (role.value) {
os.apiWithDialog('admin/roles/update', {
roleId: role.id,
...data,
roleId: role.value.id,
...data.value,
});
router.push('/admin/roles/' + role.id);
router.push('/admin/roles/' + role.value.id);
} else {
const created = await os.apiWithDialog('admin/roles/create', {
...data,
...data.value,
});
router.push('/admin/roles/' + created.id);
}
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => role ? {
title: i18n.ts._role.edit + ': ' + role.name,
definePageMetadata(computed(() => role.value ? {
title: i18n.ts._role.edit + ': ' + role.value.name,
icon: 'ti ti-badge',
} : {
title: i18n.ts._role.new,

View File

@@ -278,7 +278,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkRange>
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canSearchNotes, 'canSearchNotes'])">
<template #label>{{ i18n.ts._role._options.canSearchNotes }}</template>
<template #suffix>
@@ -537,7 +537,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { watch } from 'vue';
import { watch, ref, computed } from 'vue';
import { throttle } from 'throttle-debounce';
import RolesEditorFormula from './RolesEditorFormula.vue';
import MkInput from '@/components/MkInput.vue';
@@ -562,12 +562,12 @@ const props = defineProps<{
readonly?: boolean;
}>();
let role = $ref(deepClone(props.modelValue));
const role = ref(deepClone(props.modelValue));
// fill missing policy
for (const ROLE_POLICY of ROLE_POLICIES) {
if (role.policies[ROLE_POLICY] == null) {
role.policies[ROLE_POLICY] = {
if (role.value.policies[ROLE_POLICY] == null) {
role.value.policies[ROLE_POLICY] = {
useDefault: true,
priority: 0,
value: instance.policies[ROLE_POLICY],
@@ -575,15 +575,15 @@ for (const ROLE_POLICY of ROLE_POLICIES) {
}
}
let rolePermission = $computed({
get: () => role.isAdministrator ? 'administrator' : role.isModerator ? 'moderator' : 'normal',
const rolePermission = computed({
get: () => role.value.isAdministrator ? 'administrator' : role.value.isModerator ? 'moderator' : 'normal',
set: (val) => {
role.isAdministrator = val === 'administrator';
role.isModerator = val === 'moderator';
role.value.isAdministrator = val === 'administrator';
role.value.isModerator = val === 'moderator';
},
});
let q = $ref('');
const q = ref('');
function getPriorityIcon(option) {
if (option.priority === 2) return 'ti ti-arrows-up';
@@ -592,32 +592,32 @@ function getPriorityIcon(option) {
}
function matchQuery(keywords: string[]): boolean {
if (q.trim().length === 0) return true;
return keywords.some(keyword => keyword.toLowerCase().includes(q.toLowerCase()));
if (q.value.trim().length === 0) return true;
return keywords.some(keyword => keyword.toLowerCase().includes(q.value.toLowerCase()));
}
const save = throttle(100, () => {
const data = {
name: role.name,
description: role.description,
color: role.color === '' ? null : role.color,
iconUrl: role.iconUrl === '' ? null : role.iconUrl,
displayOrder: role.displayOrder,
target: role.target,
condFormula: role.condFormula,
isAdministrator: role.isAdministrator,
isModerator: role.isModerator,
isPublic: role.isPublic,
isExplorable: role.isExplorable,
asBadge: role.asBadge,
canEditMembersByModerator: role.canEditMembersByModerator,
policies: role.policies,
name: role.value.name,
description: role.value.description,
color: role.value.color === '' ? null : role.value.color,
iconUrl: role.value.iconUrl === '' ? null : role.value.iconUrl,
displayOrder: role.value.displayOrder,
target: role.value.target,
condFormula: role.value.condFormula,
isAdministrator: role.value.isAdministrator,
isModerator: role.value.isModerator,
isPublic: role.value.isPublic,
isExplorable: role.value.isExplorable,
asBadge: role.value.asBadge,
canEditMembersByModerator: role.value.canEditMembersByModerator,
policies: role.value.policies,
};
emit('update:modelValue', data);
});
watch($$(role), save, { deep: true });
watch(role, save, { deep: true });
</script>
<style lang="scss" module>

View File

@@ -62,7 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed, reactive } from 'vue';
import { computed, reactive, ref } from 'vue';
import XHeader from './_header_.vue';
import XEditor from './roles.editor.vue';
import MkFolder from '@/components/MkFolder.vue';
@@ -90,7 +90,7 @@ const usersPagination = {
})),
};
let expandedItems = $ref([]);
const expandedItems = ref([]);
const role = reactive(await os.api('admin/roles/show', {
roleId: props.id,
@@ -160,16 +160,16 @@ async function unassign(user, ev) {
}
async function toggleItem(item) {
if (expandedItems.includes(item.id)) {
expandedItems = expandedItems.filter(x => x !== item.id);
if (expandedItems.value.includes(item.id)) {
expandedItems.value = expandedItems.value.filter(x => x !== item.id);
} else {
expandedItems.push(item.id);
expandedItems.value.push(item.id);
}
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => ({
title: i18n.ts.role + ': ' + role.name,

View File

@@ -258,9 +258,9 @@ function create() {
router.push('/admin/roles/new');
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => ({
title: i18n.ts.roles,

View File

@@ -114,7 +114,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XBotProtection from './bot-protection.vue';
import XHeader from './_header_.vue';
import MkFolder from '@/components/MkFolder.vue';
@@ -129,65 +129,65 @@ import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
let summalyProxy: string = $ref('');
let enableHcaptcha: boolean = $ref(false);
let enableRecaptcha: boolean = $ref(false);
let enableTurnstile: boolean = $ref(false);
let sensitiveMediaDetection: string = $ref('none');
let sensitiveMediaDetectionSensitivity: number = $ref(0);
let setSensitiveFlagAutomatically: boolean = $ref(false);
let enableSensitiveMediaDetectionForVideos: boolean = $ref(false);
let enableIpLogging: boolean = $ref(false);
let enableActiveEmailValidation: boolean = $ref(false);
let enableVerifymailApi: boolean = $ref(false);
let verifymailAuthKey: string | null = $ref(null);
const summalyProxy = ref<string>('');
const enableHcaptcha = ref<boolean>(false);
const enableRecaptcha = ref<boolean>(false);
const enableTurnstile = ref<boolean>(false);
const sensitiveMediaDetection = ref<string>('none');
const sensitiveMediaDetectionSensitivity = ref<number>(0);
const setSensitiveFlagAutomatically = ref<boolean>(false);
const enableSensitiveMediaDetectionForVideos = ref<boolean>(false);
const enableIpLogging = ref<boolean>(false);
const enableActiveEmailValidation = ref<boolean>(false);
const enableVerifymailApi = ref<boolean>(false);
const verifymailAuthKey = ref<string | null>(null);
async function init() {
const meta = await os.api('admin/meta');
summalyProxy = meta.summalyProxy;
enableHcaptcha = meta.enableHcaptcha;
enableRecaptcha = meta.enableRecaptcha;
enableTurnstile = meta.enableTurnstile;
sensitiveMediaDetection = meta.sensitiveMediaDetection;
sensitiveMediaDetectionSensitivity =
summalyProxy.value = meta.summalyProxy;
enableHcaptcha.value = meta.enableHcaptcha;
enableRecaptcha.value = meta.enableRecaptcha;
enableTurnstile.value = meta.enableTurnstile;
sensitiveMediaDetection.value = meta.sensitiveMediaDetection;
sensitiveMediaDetectionSensitivity.value =
meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0 :
meta.sensitiveMediaDetectionSensitivity === 'low' ? 1 :
meta.sensitiveMediaDetectionSensitivity === 'medium' ? 2 :
meta.sensitiveMediaDetectionSensitivity === 'high' ? 3 :
meta.sensitiveMediaDetectionSensitivity === 'veryHigh' ? 4 : 0;
setSensitiveFlagAutomatically = meta.setSensitiveFlagAutomatically;
enableSensitiveMediaDetectionForVideos = meta.enableSensitiveMediaDetectionForVideos;
enableIpLogging = meta.enableIpLogging;
enableActiveEmailValidation = meta.enableActiveEmailValidation;
enableVerifymailApi = meta.enableVerifymailApi;
verifymailAuthKey = meta.verifymailAuthKey;
setSensitiveFlagAutomatically.value = meta.setSensitiveFlagAutomatically;
enableSensitiveMediaDetectionForVideos.value = meta.enableSensitiveMediaDetectionForVideos;
enableIpLogging.value = meta.enableIpLogging;
enableActiveEmailValidation.value = meta.enableActiveEmailValidation;
enableVerifymailApi.value = meta.enableVerifymailApi;
verifymailAuthKey.value = meta.verifymailAuthKey;
}
function save() {
os.apiWithDialog('admin/update-meta', {
summalyProxy,
sensitiveMediaDetection,
summalyProxy: summalyProxy.value,
sensitiveMediaDetection: sensitiveMediaDetection.value,
sensitiveMediaDetectionSensitivity:
sensitiveMediaDetectionSensitivity === 0 ? 'veryLow' :
sensitiveMediaDetectionSensitivity === 1 ? 'low' :
sensitiveMediaDetectionSensitivity === 2 ? 'medium' :
sensitiveMediaDetectionSensitivity === 3 ? 'high' :
sensitiveMediaDetectionSensitivity === 4 ? 'veryHigh' :
sensitiveMediaDetectionSensitivity.value === 0 ? 'veryLow' :
sensitiveMediaDetectionSensitivity.value === 1 ? 'low' :
sensitiveMediaDetectionSensitivity.value === 2 ? 'medium' :
sensitiveMediaDetectionSensitivity.value === 3 ? 'high' :
sensitiveMediaDetectionSensitivity.value === 4 ? 'veryHigh' :
0,
setSensitiveFlagAutomatically,
enableSensitiveMediaDetectionForVideos,
enableIpLogging,
enableActiveEmailValidation,
enableVerifymailApi,
verifymailAuthKey,
setSensitiveFlagAutomatically: setSensitiveFlagAutomatically.value,
enableSensitiveMediaDetectionForVideos: enableSensitiveMediaDetectionForVideos.value,
enableIpLogging: enableIpLogging.value,
enableActiveEmailValidation: enableActiveEmailValidation.value,
enableVerifymailApi: enableVerifymailApi.value,
verifymailAuthKey: verifymailAuthKey.value,
}).then(() => {
fetchInstance();
});
}
const headerActions = $computed(() => []);
const headerActions = computed(() => []);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.security,

View File

@@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue';
import { defineAsyncComponent, ref, computed } from 'vue';
import XHeader from './_header_.vue';
import * as os from '@/os.js';
import { fetchInstance, instance } from '@/instance.js';
@@ -52,20 +52,20 @@ import MkInput from '@/components/MkInput.vue';
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
let serverRules: string[] = $ref(instance.serverRules);
const serverRules = ref<string[]>(instance.serverRules);
const save = async () => {
await os.apiWithDialog('admin/update-meta', {
serverRules,
serverRules: serverRules.value,
});
fetchInstance();
};
const remove = (index: number): void => {
serverRules.splice(index, 1);
serverRules.value.splice(index, 1);
};
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.serverRules,

View File

@@ -148,7 +148,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInput from '@/components/MkInput.vue';
@@ -163,76 +163,76 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
let name: string | null = $ref(null);
let shortName: string | null = $ref(null);
let description: string | null = $ref(null);
let maintainerName: string | null = $ref(null);
let maintainerEmail: string | null = $ref(null);
let impressumUrl: string | null = $ref(null);
let pinnedUsers: string = $ref('');
let cacheRemoteFiles: boolean = $ref(false);
let cacheRemoteSensitiveFiles: boolean = $ref(false);
let enableServiceWorker: boolean = $ref(false);
let swPublicKey: any = $ref(null);
let swPrivateKey: any = $ref(null);
let enableFanoutTimeline: boolean = $ref(false);
let enableFanoutTimelineDbFallback: boolean = $ref(false);
let perLocalUserUserTimelineCacheMax: number = $ref(0);
let perRemoteUserUserTimelineCacheMax: number = $ref(0);
let perUserHomeTimelineCacheMax: number = $ref(0);
let perUserListTimelineCacheMax: number = $ref(0);
let notesPerOneAd: number = $ref(0);
const name = ref<string | null>(null);
const shortName = ref<string | null>(null);
const description = ref<string | null>(null);
const maintainerName = ref<string | null>(null);
const maintainerEmail = ref<string | null>(null);
const impressumUrl = ref<string | null>(null);
const pinnedUsers = ref<string>('');
const cacheRemoteFiles = ref<boolean>(false);
const cacheRemoteSensitiveFiles = ref<boolean>(false);
const enableServiceWorker = ref<boolean>(false);
const swPublicKey = ref<any>(null);
const swPrivateKey = ref<any>(null);
const enableFanoutTimeline = ref<boolean>(false);
const enableFanoutTimelineDbFallback = ref<boolean>(false);
const perLocalUserUserTimelineCacheMax = ref<number>(0);
const perRemoteUserUserTimelineCacheMax = ref<number>(0);
const perUserHomeTimelineCacheMax = ref<number>(0);
const perUserListTimelineCacheMax = ref<number>(0);
const notesPerOneAd = ref<number>(0);
async function init(): Promise<void> {
const meta = await os.api('admin/meta');
name = meta.name;
shortName = meta.shortName;
description = meta.description;
maintainerName = meta.maintainerName;
maintainerEmail = meta.maintainerEmail;
impressumUrl = meta.impressumUrl;
pinnedUsers = meta.pinnedUsers.join('\n');
cacheRemoteFiles = meta.cacheRemoteFiles;
cacheRemoteSensitiveFiles = meta.cacheRemoteSensitiveFiles;
enableServiceWorker = meta.enableServiceWorker;
swPublicKey = meta.swPublickey;
swPrivateKey = meta.swPrivateKey;
enableFanoutTimeline = meta.enableFanoutTimeline;
enableFanoutTimelineDbFallback = meta.enableFanoutTimelineDbFallback;
perLocalUserUserTimelineCacheMax = meta.perLocalUserUserTimelineCacheMax;
perRemoteUserUserTimelineCacheMax = meta.perRemoteUserUserTimelineCacheMax;
perUserHomeTimelineCacheMax = meta.perUserHomeTimelineCacheMax;
perUserListTimelineCacheMax = meta.perUserListTimelineCacheMax;
notesPerOneAd = meta.notesPerOneAd;
name.value = meta.name;
shortName.value = meta.shortName;
description.value = meta.description;
maintainerName.value = meta.maintainerName;
maintainerEmail.value = meta.maintainerEmail;
impressumUrl.value = meta.impressumUrl;
pinnedUsers.value = meta.pinnedUsers.join('\n');
cacheRemoteFiles.value = meta.cacheRemoteFiles;
cacheRemoteSensitiveFiles.value = meta.cacheRemoteSensitiveFiles;
enableServiceWorker.value = meta.enableServiceWorker;
swPublicKey.value = meta.swPublickey;
swPrivateKey.value = meta.swPrivateKey;
enableFanoutTimeline.value = meta.enableFanoutTimeline;
enableFanoutTimelineDbFallback.value = meta.enableFanoutTimelineDbFallback;
perLocalUserUserTimelineCacheMax.value = meta.perLocalUserUserTimelineCacheMax;
perRemoteUserUserTimelineCacheMax.value = meta.perRemoteUserUserTimelineCacheMax;
perUserHomeTimelineCacheMax.value = meta.perUserHomeTimelineCacheMax;
perUserListTimelineCacheMax.value = meta.perUserListTimelineCacheMax;
notesPerOneAd.value = meta.notesPerOneAd;
}
async function save(): void {
await os.apiWithDialog('admin/update-meta', {
name,
shortName: shortName === '' ? null : shortName,
description,
maintainerName,
maintainerEmail,
impressumUrl,
pinnedUsers: pinnedUsers.split('\n'),
cacheRemoteFiles,
cacheRemoteSensitiveFiles,
enableServiceWorker,
swPublicKey,
swPrivateKey,
enableFanoutTimeline,
enableFanoutTimelineDbFallback,
perLocalUserUserTimelineCacheMax,
perRemoteUserUserTimelineCacheMax,
perUserHomeTimelineCacheMax,
perUserListTimelineCacheMax,
notesPerOneAd,
name: name.value,
shortName: shortName.value === '' ? null : shortName.value,
description: description.value,
maintainerName: maintainerName.value,
maintainerEmail: maintainerEmail.value,
impressumUrl: impressumUrl.value,
pinnedUsers: pinnedUsers.value.split('\n'),
cacheRemoteFiles: cacheRemoteFiles.value,
cacheRemoteSensitiveFiles: cacheRemoteSensitiveFiles.value,
enableServiceWorker: enableServiceWorker.value,
swPublicKey: swPublicKey.value,
swPrivateKey: swPrivateKey.value,
enableFanoutTimeline: enableFanoutTimeline.value,
enableFanoutTimelineDbFallback: enableFanoutTimelineDbFallback.value,
perLocalUserUserTimelineCacheMax: perLocalUserUserTimelineCacheMax.value,
perRemoteUserUserTimelineCacheMax: perRemoteUserUserTimelineCacheMax.value,
perUserHomeTimelineCacheMax: perUserHomeTimelineCacheMax.value,
perUserListTimelineCacheMax: perUserListTimelineCacheMax.value,
notesPerOneAd: notesPerOneAd.value,
});
fetchInstance();
}
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata({
title: i18n.ts.general,

View File

@@ -57,7 +57,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, shallowRef, ref } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkSelect from '@/components/MkSelect.vue';
@@ -69,22 +69,22 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import { dateString } from '@/filters/date.js';
let paginationComponent = $shallowRef<InstanceType<typeof MkPagination>>();
const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
let sort = $ref('+createdAt');
let state = $ref('all');
let origin = $ref('local');
let searchUsername = $ref('');
let searchHost = $ref('');
const sort = ref('+createdAt');
const state = ref('all');
const origin = ref('local');
const searchUsername = ref('');
const searchHost = ref('');
const pagination = {
endpoint: 'admin/show-users' as const,
limit: 10,
params: computed(() => ({
sort: sort,
state: state,
origin: origin,
username: searchUsername,
hostname: searchHost,
sort: sort.value,
state: state.value,
origin: origin.value,
username: searchUsername.value,
hostname: searchHost.value,
})),
offsetMode: true,
};
@@ -111,7 +111,7 @@ async function addUser() {
username: username,
password: password,
}).then(res => {
paginationComponent.reload();
paginationComponent.value.reload();
});
}
@@ -119,7 +119,7 @@ function show(user) {
os.pageWindow(`/admin/user/${user.id}`);
}
const headerActions = $computed(() => [{
const headerActions = computed(() => [{
icon: 'ti ti-search',
text: i18n.ts.search,
handler: searchUser,
@@ -135,7 +135,7 @@ const headerActions = $computed(() => [{
handler: lookupUser,
}]);
const headerTabs = $computed(() => []);
const headerTabs = computed(() => []);
definePageMetadata(computed(() => ({
title: i18n.ts.users,