<script setup lang="ts"> import { useAuthStore } from "@/stores/users"; import { reactive } from "vue"; import { RoleEnum, type User } from "@/client/auth"; import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import UserRoleMark from "@/components/admin/UserRoleMark.vue"; const userRepository = useAuthStore(); const userState = reactive<{ loading: boolean; users: User[]; searchString: string; userRoles: RoleEnum[]; inspectUser?: User; searched: boolean; }>({ loading: false, users: [], searchString: "", userRoles: [], inspectUser: undefined, searched: false, }); function searchUsers() { userState.loading = true; userRepository .fetchUsers( userState.searchString ? userState.searchString : undefined, userState.userRoles ? userState.userRoles : undefined, true, ) .then((users) => { userState.users = users; }) .finally(() => { userState.loading = false; userState.searched = true; }); } </script> <template> <div class="row border-bottom mb-4 justify-content-between align-items-center" > <h2>Manage Users</h2> </div> <form @submit.prevent="searchUsers" id="admin-user-search-form"> <div class="d-flex justify-content-evenly align-content-center"> <div class="mx-2"> <label for="admin-user-state-select" class="form-label" >User Roles</label > <select v-model="userState.userRoles" multiple class="form-select mb-4 w-fit" id="admin-user-state-select" > <option v-for="role in Object.values(RoleEnum)" :key="role"> {{ role }} </option> </select> </div> <div class="flex-fill mx-2"> <label for="admin-user-name-search" class="form-label" >Name of a user</label > <div class="input-group"> <div class="input-group-text"> <font-awesome-icon icon="fa-solid fa-search" /> </div> <input id="admin-user-name-search" type="text" class="form-control" maxlength="32" minlength="3" v-model="userState.searchString" placeholder="Search for user name" /> </div> </div> </div> <button type="submit" class="btn btn-primary w-fit" :disabled="userState.loading" > Search </button> </form> <table class="table table-striped align-middle caption-top" v-if="userState.users" > <caption> Displaying {{ userState.users.length }} Users </caption> <thead> <tr> <th scope="col"><b>Name</b></th> <th scope="col">UID</th> <th scope="col" class="text-center">Approved User</th> <th scope="col" class="text-center">Developer</th> <th scope="col" class="text-center">Resource Maintainer</th> <th scope="col" class="text-center">Reviewer</th> <th scope="col" class="text-center">Admin</th> </tr> </thead> <tbody v-if="userState.users.length === 0"> <tr> <td colspan="7" class="text-center fst-italic fw-light"> <template v-if="userState.searched" >No Users found with specified filters </template> <template v-else>Select a filter and search for Users</template> </td> </tr> </tbody> <tbody v-else> <tr v-for="user in userState.users" :key="user.uid"> <th scope="row">{{ user.display_name }}</th> <td>{{ user.uid }}</td> <td class="text-center"> <user-role-mark :role="RoleEnum.USER" :user="user" /> </td> <td class="text-center"> <user-role-mark :role="RoleEnum.DEVELOPER" :user="user" /> </td> <td class="text-center"> <user-role-mark :role="RoleEnum.DB_MAINTAINER" :user="user" /> </td> <td class="text-center"> <user-role-mark :role="RoleEnum.REVIEWER" :user="user" /> </td> <td class="text-center"> <user-role-mark :role="RoleEnum.ADMINISTRATOR" :user="user" /> </td> </tr> </tbody> </table> </template> <style scoped></style>