From bfe6d9b3fb9faad227d36b58f1d4d6d7c5caaae0 Mon Sep 17 00:00:00 2001 From: Natsumi Date: Sat, 15 Jun 2024 20:44:24 +1200 Subject: [PATCH] Fix group audit logs and add filters --- html/src/app.js | 64 ++++++++++++++++++++++++++++++-- html/src/index.pug | 13 ++++++- html/src/localization/en/en.json | 3 ++ html/src/vr.pug | 8 ++-- 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/html/src/app.js b/html/src/app.js index 4fd63ee7..29a7c190 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -5726,7 +5726,7 @@ speechSynthesis.getVoices(); if (this.branch === 'Stable') { this.nextAppUpdateCheck = 14400; // 2hours } else { - this.nextAppUpdateCheck = 1800; // 15mins + this.nextAppUpdateCheck = 7200; // 1hour } if (this.autoUpdateVRCX !== 'Off') { this.checkForVRCXUpdate(); @@ -6685,6 +6685,9 @@ speechSynthesis.getVoices(); return ''; }) .then((args) => { + if (!args.json) { + return ''; + } if ( this.displayVRCPlusIconsAsAvatar && args.json.userIcon @@ -29433,6 +29436,10 @@ speechSynthesis.getVoices(); n: 100, offset: 0 }; + if (this.groupMemberModeration.selectedAuditLogTypes.length) { + params.eventTypes = + this.groupMemberModeration.selectedAuditLogTypes; + } var count = 50; // 5000 max this.isGroupMembersLoading = true; try { @@ -29460,9 +29467,44 @@ speechSynthesis.getVoices(); * @param {{ groupId: string }} params * @return { Promise<{json: any, params}> } */ + API.getGroupAuditLogTypes = function (params) { + return this.call(`groups/${params.groupId}/auditLogTypes`, { + method: 'GET' + }).then((json) => { + var args = { + json, + params + }; + this.$emit('GROUP:AUDITLOGTYPES', args); + return args; + }); + }; + API.$on('GROUP:AUDITLOGTYPES', function (args) { + if ($app.groupMemberModeration.id !== args.params.groupId) { + return; + } + + $app.groupMemberModeration.auditLogTypes = args.json; + }); + + $app.methods.getAuditLogTypeName = function (auditLogType) { + if (!auditLogType) { + return ''; + } + return auditLogType + .replace('group.', '') + .replace(/\./g, ' ') + .replace(/\b\w/g, (l) => l.toUpperCase()); + }; + + /** + * @param {{ groupId: string, eventTypes: array }} params + * @return { Promise<{json: any, params}> } + */ API.getGroupLogs = function (params) { return this.call(`groups/${params.groupId}/auditLogs`, { - method: 'GET' + method: 'GET', + params }).then((json) => { var args = { json, @@ -29479,7 +29521,12 @@ speechSynthesis.getVoices(); } for (var json of args.json.results) { - $app.groupLogsModerationTable.data.push(json); + const existsInData = $app.groupLogsModerationTable.data.some( + (dataItem) => dataItem.id === json.id + ); + if (!existsInData) { + $app.groupLogsModerationTable.data.push(json); + } } }); @@ -31698,6 +31745,8 @@ speechSynthesis.getVoices(); loading: false, id: '', groupRef: {}, + auditLogTypes: [], + selectedAuditLogTypes: [], note: '', selectedUsers: new Map(), selectedUsersArray: [], @@ -31743,6 +31792,12 @@ speechSynthesis.getVoices(); $app.data.groupLogsModerationTable = { data: [], + filters: [ + { + prop: ['description'], + value: '' + } + ], tableProps: { stripe: true, size: 'mini' @@ -31827,9 +31882,12 @@ speechSynthesis.getVoices(); D.selectedUsersArray = []; D.selectedRoles = []; D.groupRef = {}; + D.auditLogTypes = []; + D.selectedAuditLogTypes = []; API.getCachedGroup({ groupId }).then((args) => { D.groupRef = args.ref; }); + API.getGroupAuditLogTypes({ groupId }); this.groupMemberModerationTableForceUpdate = 0; D.visible = true; this.setGroupMemberModerationTable(this.groupDialog.members); diff --git a/html/src/index.pug b/html/src/index.pug index 931106bd..ae38d12e 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -3195,6 +3195,13 @@ html el-button(type="default" @click="getAllGroupLogs(groupMemberModeration.id)" size="mini" icon="el-icon-refresh" :loading="isGroupMembersLoading" circle) span(style="font-size:14px;margin-left:5px;margin-right:5px") {{ groupLogsModerationTable.data.length }} br + el-select(v-model="groupMemberModeration.selectedAuditLogTypes" multiple collapse-tags :placeholder="$t('dialog.group_member_moderation.filter_type')") + el-option-group(:label="$t('dialog.group_member_moderation.select_type')") + el-option.x-friend-item(v-for="type in groupMemberModeration.auditLogTypes" :key="type" :label="getAuditLogTypeName(type)" :value="type") + .detail + span.name(v-text="getAuditLogTypeName(type)") + el-input(v-model="groupLogsModerationTable.filters[0].value" :placeholder="$t('dialog.group_member_moderation.search_placeholder')" style="display:inline-block;width:150px;margin:10px") + br data-tables(v-bind="groupLogsModerationTable" style="margin-top:10px") el-table-column(:label="$t('dialog.group_member_moderation.created_at')" width="170" prop="created_at" sortable) template(v-once #default="scope") @@ -3213,11 +3220,13 @@ html template(v-once #default="scope") span(v-if="Object.keys(scope.row.data).length" v-text="JSON.stringify(scope.row.data)") br + br span.name {{ $t('dialog.group_member_moderation.user_id') }} br el-input(v-model="groupMemberModeration.selectUserId" size="mini" style="margin-top:5px;width:340px" :placeholder="$t('dialog.group_member_moderation.user_id_placeholder')" clearable) el-button(size="small" @click="selectGroupMemberUserId" :disabled="!groupMemberModeration.selectUserId") {{ $t('dialog.group_member_moderation.select_user') }} br + br span.name {{ $t('dialog.group_member_moderation.selected_users') }} el-button(type="default" @click="clearSelectedGroupMembers" size="mini" icon="el-icon-delete" circle style="margin-left:5px") br @@ -3226,7 +3235,8 @@ html br br span.name {{ $t('dialog.group_member_moderation.notes') }} - el-input.extra(v-model="groupMemberModeration.note" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" :placeholder="$t('dialog.group_member_moderation.note_placeholder')" size="mini" resize="none") + el-input.extra(v-model="groupMemberModeration.note" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" :placeholder="$t('dialog.group_member_moderation.note_placeholder')" size="mini" resize="none" style="margin-top:5px") + br br span.name {{ $t('dialog.group_member_moderation.selected_roles') }} br @@ -3236,6 +3246,7 @@ html .detail span.name(v-text="role.name") br + br span.name {{ $t('dialog.group_member_moderation.actions') }} br el-button(@click="groupMembersAddRoles" :disabled="!groupMemberModeration.selectedRoles.length || groupMemberModeration.progressCurrent || !hasGroupPermission(groupDialog.ref, 'group-roles-assign')") {{ $t('dialog.group_member_moderation.add_roles') }} diff --git a/html/src/localization/en/en.json b/html/src/localization/en/en.json index c747e1c3..235f1da9 100644 --- a/html/src/localization/en/en.json +++ b/html/src/localization/en/en.json @@ -1312,6 +1312,9 @@ }, "group_member_moderation": { "header": "Group Member Moderation", + "filter_type": "Filter Type", + "select_type": "Select Type", + "search_placeholder": "Search", "members": "Members", "bans": "Bans", "invites": "Invites", diff --git a/html/src/vr.pug b/html/src/vr.pug index f57b11ee..bfc9967c 100644 --- a/html/src/vr.pug +++ b/html/src/vr.pug @@ -123,12 +123,12 @@ html .detail span.extra span.time {{ feed.created_at | formatDate }} - | 👉 #[span.name(v-text="feed.message")] + | 👉 #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.message")] div(v-else-if="feed.type === 'groupChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate }} - | 🏷️ #[span.name(v-text="feed.senderUsername")] #[span.name(v-text="feed.message")] + | 🏷️ #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.message")] div(v-else-if="feed.type === 'group.announcement'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra @@ -353,12 +353,12 @@ html .detail span.extra span.time {{ feed.created_at | formatDate }} - | #[span.name(v-text="feed.message")] + | #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.message")] div(v-else-if="feed.type === 'groupChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra span.time {{ feed.created_at | formatDate }} - | #[span.name(v-text="feed.senderUsername")] #[span.name(v-text="feed.message")] + | #[span.name(v-text="feed.senderUsername")] #[span(v-text="feed.message")] div(v-else-if="feed.type === 'group.announcement'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") .detail span.extra