Skip to content
Snippets Groups Projects
AdminUsersView.vue 4.17 KiB
<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>