From 00222670729ddb200d664cf6c177a48d48cd7a61 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Mon, 16 Jan 2023 05:19:26 +0900
Subject: [PATCH] =?UTF-8?q?enhance(client):=20=E3=83=AD=E3=83=BC=E3=83=AB?=
 =?UTF-8?q?=E3=81=AE=E3=83=9D=E3=83=AA=E3=82=B7=E3=83=BC=E3=82=92=E7=B5=9E?=
 =?UTF-8?q?=E3=82=8A=E8=BE=BC=E3=82=81=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../frontend/src/pages/admin/roles.editor.vue | 40 ++++++++++++-------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index d0be0a8c39..0f2f297a5b 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -38,7 +38,11 @@
 	<FormSlot>
 		<template #label>{{ i18n.ts._role.policies }}</template>
 		<div class="_gaps_s">
-			<MkFolder>
+			<MkInput v-model="q" type="search">
+				<template #prefix><i class="ti ti-search"></i></template>
+			</MkInput>
+
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.rateLimitFactor, 'rateLimitFactor'])">
 				<template #label>{{ i18n.ts._role._options.rateLimitFactor }}</template>
 				<template #suffix>{{ policies.rateLimitFactor.useDefault ? i18n.ts._role.useBaseValue : `${Math.floor(policies.rateLimitFactor.value * 100)}%` }} <i :class="getPriorityIcon(policies.rateLimitFactor)"></i></template>
 				<div class="_gaps">
@@ -55,7 +59,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.gtlAvailable, 'gtlAvailable'])">
 				<template #label>{{ i18n.ts._role._options.gtlAvailable }}</template>
 				<template #suffix>{{ policies.gtlAvailable.useDefault ? i18n.ts._role.useBaseValue : (policies.gtlAvailable.value ? i18n.ts.yes : i18n.ts.no) }} <i :class="getPriorityIcon(policies.gtlAvailable)"></i></template>
 				<div class="_gaps">
@@ -71,7 +75,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.ltlAvailable, 'ltlAvailable'])">
 				<template #label>{{ i18n.ts._role._options.ltlAvailable }}</template>
 				<template #suffix>{{ policies.ltlAvailable.useDefault ? i18n.ts._role.useBaseValue : (policies.ltlAvailable.value ? i18n.ts.yes : i18n.ts.no) }} <i :class="getPriorityIcon(policies.ltlAvailable)"></i></template>
 				<div class="_gaps">
@@ -87,7 +91,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.canPublicNote, 'canPublicNote'])">
 				<template #label>{{ i18n.ts._role._options.canPublicNote }}</template>
 				<template #suffix>{{ policies.canPublicNote.useDefault ? i18n.ts._role.useBaseValue : (policies.canPublicNote.value ? i18n.ts.yes : i18n.ts.no) }} <i :class="getPriorityIcon(policies.canPublicNote)"></i></template>
 				<div class="_gaps">
@@ -103,7 +107,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
 				<template #label>{{ i18n.ts._role._options.canInvite }}</template>
 				<template #suffix>{{ policies.canInvite.useDefault ? i18n.ts._role.useBaseValue : (policies.canInvite.value ? i18n.ts.yes : i18n.ts.no) }} <i :class="getPriorityIcon(policies.canInvite)"></i></template>
 				<div class="_gaps">
@@ -119,7 +123,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.canManageCustomEmojis, 'canManageCustomEmojis'])">
 				<template #label>{{ i18n.ts._role._options.canManageCustomEmojis }}</template>
 				<template #suffix>{{ policies.canManageCustomEmojis.useDefault ? i18n.ts._role.useBaseValue : (policies.canManageCustomEmojis.value ? i18n.ts.yes : i18n.ts.no) }} <i :class="getPriorityIcon(policies.canManageCustomEmojis)"></i></template>
 				<div class="_gaps">
@@ -135,7 +139,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.driveCapacity, 'driveCapacityMb'])">
 				<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
 				<template #suffix>{{ policies.driveCapacityMb.useDefault ? i18n.ts._role.useBaseValue : (policies.driveCapacityMb.value + 'MB') }} <i :class="getPriorityIcon(policies.driveCapacityMb)"></i></template>
 				<div class="_gaps">
@@ -151,7 +155,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.pinMax, 'pinLimit'])">
 				<template #label>{{ i18n.ts._role._options.pinMax }}</template>
 				<template #suffix>{{ policies.pinLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.pinLimit.value) }} <i :class="getPriorityIcon(policies.pinLimit)"></i></template>
 				<div class="_gaps">
@@ -166,7 +170,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.antennaMax, 'antennaLimit'])">
 				<template #label>{{ i18n.ts._role._options.antennaMax }}</template>
 				<template #suffix>{{ policies.antennaLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.antennaLimit.value) }} <i :class="getPriorityIcon(policies.antennaLimit)"></i></template>
 				<div class="_gaps">
@@ -181,7 +185,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.wordMuteMax, 'wordMuteLimit'])">
 				<template #label>{{ i18n.ts._role._options.wordMuteMax }}</template>
 				<template #suffix>{{ policies.wordMuteLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.wordMuteLimit.value) }} <i :class="getPriorityIcon(policies.wordMuteLimit)"></i></template>
 				<div class="_gaps">
@@ -197,7 +201,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.webhookMax, 'webhookLimit'])">
 				<template #label>{{ i18n.ts._role._options.webhookMax }}</template>
 				<template #suffix>{{ policies.webhookLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.webhookLimit.value) }} <i :class="getPriorityIcon(policies.webhookLimit)"></i></template>
 				<div class="_gaps">
@@ -212,7 +216,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.clipMax, 'clipLimit'])">
 				<template #label>{{ i18n.ts._role._options.clipMax }}</template>
 				<template #suffix>{{ policies.clipLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.clipLimit.value) }} <i :class="getPriorityIcon(policies.clipLimit)"></i></template>
 				<div class="_gaps">
@@ -227,7 +231,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.noteEachClipsMax, 'noteEachClipsLimit'])">
 				<template #label>{{ i18n.ts._role._options.noteEachClipsMax }}</template>
 				<template #suffix>{{ policies.noteEachClipsLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.noteEachClipsLimit.value) }} <i :class="getPriorityIcon(policies.noteEachClipsLimit)"></i></template>
 				<div class="_gaps">
@@ -242,7 +246,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.userListMax, 'userListLimit'])">
 				<template #label>{{ i18n.ts._role._options.userListMax }}</template>
 				<template #suffix>{{ policies.userListLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.userListLimit.value) }} <i :class="getPriorityIcon(policies.userListLimit)"></i></template>
 				<div class="_gaps">
@@ -257,7 +261,7 @@
 				</div>
 			</MkFolder>
 
-			<MkFolder>
+			<MkFolder v-if="matchQuery([i18n.ts._role._options.userEachUserListsMax, 'userEachUserListsLimit'])">
 				<template #label>{{ i18n.ts._role._options.userEachUserListsMax }}</template>
 				<template #suffix>{{ policies.userEachUserListsLimit.useDefault ? i18n.ts._role.useBaseValue : (policies.userEachUserListsLimit.value) }} <i :class="getPriorityIcon(policies.userEachUserListsLimit)"></i></template>
 				<div class="_gaps">
@@ -335,6 +339,7 @@ const props = defineProps<{
 }>();
 
 const role = props.role;
+let q = $ref('');
 
 let name = $ref(role?.name ?? 'New Role');
 let description = $ref(role?.description ?? '');
@@ -367,6 +372,11 @@ function getPriorityIcon(option) {
 	return 'ti ti-point';
 }
 
+function matchQuery(keywords: string[]): boolean {
+	if (q.trim().length === 0) return true;
+	return keywords.some(keyword => keyword.toLowerCase().includes(q.toLowerCase()));
+}
+
 async function save() {
 	if (props.readonly) return;
 	if (role) {