From 871027fa0cd2bd92411108f069eec0b188cc19ae Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 20 Jul 2023 10:54:41 +0900 Subject: [PATCH] =?UTF-8?q?enhance:=20=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC?= =?UTF-8?q?=E3=81=AB=E3=83=AD=E3=83=BC=E3=83=AB=E3=81=8C=E6=9C=9F=E9=99=90?= =?UTF-8?q?=E4=BB=98=E3=81=8D=E3=81=A7=E3=82=A2=E3=82=B5=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=80=81=E3=81=9D=E3=81=AE=E6=9C=9F=E9=99=90=E3=82=92=E3=83=A6?= =?UTF-8?q?=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E3=83=A2=E3=83=87=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=81=A7=E7=A2=BA=E8=AA=8D=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #11059 --- CHANGELOG.md | 5 +-- packages/backend/src/core/RoleService.ts | 11 ++++-- .../server/api/endpoints/admin/show-user.ts | 6 ++++ .../frontend/src/pages/admin/roles.role.vue | 2 +- .../src/pages/settings/mute-block.vue | 4 +-- packages/frontend/src/pages/user-info.vue | 34 +++++++++++++++++-- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d5fad2a..9055b35cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,13 @@ ## 13.x.x (unreleased) ### General -- identicon生成を無効にしてパフォーマンスを向上させることができるようになりました -- サーバーのマシン情報の公開を無効にしてパフォーマンスを向上させることができるようになりました - 招待機能を改善しました * 過去に発行した招待コードを確認できるようになりました * ロールごとに招待コードの発行数制限と制限対象期間、有効期限を設定できるようになりました * 招待コードを作成したユーザーと使用したユーザーを確認できるようになりました +- ユーザーにロールが期限付きでアサインされている場合、その期限をユーザーのモデレーションページで確認できるようになりました +- identicon生成を無効にしてパフォーマンスを向上させることができるようになりました +- サーバーのマシン情報の公開を無効にしてパフォーマンスを向上させることができるようになりました ### Client - deck UIのカラムのメニューからアンテナとリストの編集画面を開けるように diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 3b501cf8d..d065b460c 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -220,14 +220,19 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserRoles(userId: User['id']) { + public async getUserAssigns(userId: User['id']) { const now = Date.now(); let assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId })); // 期限切れのロールを除外 assigns = assigns.filter(a => a.expiresAt == null || (a.expiresAt.getTime() > now)); - const assignedRoleIds = assigns.map(x => x.roleId); + return assigns; + } + + @bindThis + public async getUserRoles(userId: User['id']) { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); - const assignedRoles = roles.filter(r => assignedRoleIds.includes(r.id)); + const assigns = await this.getUserAssigns(userId); + const assignedRoles = roles.filter(r => assigns.map(x => x.roleId).includes(r.id)); const user = roles.some(r => r.target === 'conditional') ? await this.cacheService.findUserById(userId) : null; const matchedCondRoles = roles.filter(r => r.target === 'conditional' && this.evalCond(user!, r.condFormula)); return [...assignedRoles, ...matchedCondRoles]; diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index f49d2a096..6f805b6b4 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -61,6 +61,7 @@ export default class extends Endpoint { const signins = await this.signinsRepository.findBy({ userId: user.id }); + const roleAssigns = await this.roleService.getUserAssigns(user.id); const roles = await this.roleService.getUserRoles(user.id); return { @@ -85,6 +86,11 @@ export default class extends Endpoint { signins, policies: await this.roleService.getUserPolicies(user.id), roles: await this.roleEntityService.packMany(roles, me), + roleAssigns: roleAssigns.map(a => ({ + createdAt: a.createdAt.toISOString(), + expiresAt: a.expiresAt ? a.expiresAt.toISOString() : null, + roleId: a.roleId, + })), }; }); } diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue index 6cbe7ae65..789c9da27 100644 --- a/packages/frontend/src/pages/admin/roles.role.vue +++ b/packages/frontend/src/pages/admin/roles.role.vue @@ -40,7 +40,7 @@
Assigned:
-
Period: {{ item.expiresAt.toLocaleString() }}
+
Period: {{ new Date(item.expiresAt).toLocaleString() }}
Period: {{ i18n.ts.indefinitely }}
diff --git a/packages/frontend/src/pages/settings/mute-block.vue b/packages/frontend/src/pages/settings/mute-block.vue index e0785ab9f..e1f3c6bed 100644 --- a/packages/frontend/src/pages/settings/mute-block.vue +++ b/packages/frontend/src/pages/settings/mute-block.vue @@ -55,7 +55,7 @@
Muted at:
-
Period: {{ item.expiresAt.toLocaleString() }}
+
Period: {{ new Date(item.expiresAt).toLocaleString() }}
Period: {{ i18n.ts.indefinitely }}
@@ -85,7 +85,7 @@
Blocked at:
-
Period: {{ item.expiresAt.toLocaleString() }}
+
Period: {{ new Date(item.expiresAt).toLocaleString() }}
Period: {{ i18n.ts.indefinitely }}
diff --git a/packages/frontend/src/pages/user-info.vue b/packages/frontend/src/pages/user-info.vue index 56e8737e1..f7650285c 100644 --- a/packages/frontend/src/pages/user-info.vue +++ b/packages/frontend/src/pages/user-info.vue @@ -112,9 +112,17 @@ {{ i18n.ts.assign }}
- - - +
+ + + + +
+
+
Assigned:
+
Period: {{ new Date(info.roleAssigns.find(a => a.roleId === role.id).expiresAt).toLocaleString() }}
+
Period: {{ i18n.ts.indefinitely }}
+
@@ -220,6 +228,7 @@ const filesPagination = { userId: props.userId, })), }; +let expandedRoles = $ref([]); function createFetcher() { if (iAmModerator) { @@ -384,6 +393,14 @@ async function unassignRole(role, ev) { }], ev.currentTarget ?? ev.target); } +function toggleRoleItem(role) { + if (expandedRoles.includes(role.id)) { + expandedRoles = expandedRoles.filter(x => x !== role.id); + } else { + expandedRoles.push(role.id); + } +} + watch(() => props.userId, () => { init = createFetcher(); }, { @@ -523,11 +540,22 @@ definePageMetadata(computed(() => ({ } .roleItem { +} + +.roleItemMain { display: flex; } .role { flex: 1; + min-width: 0; + margin-right: 8px; +} + +.roleItemSub { + padding: 6px 12px; + font-size: 85%; + color: var(--fgTransparentWeak); } .roleUnassign {