<template>
  <div class="admin-page-stack">
    <AdminPageHeader
      title="访问申请"
      subtitle="处理用户对客户端应用的访问权限申请。"
      icon="approval"
      accent="amber"
      :metrics="pageMetrics"
    >
      <template #actions>
        <q-btn icon="refresh" round flat :loading="loading" @click="reload" />
      </template>
    </AdminPageHeader>

    <AdminFilterPanel :loading="loading" @search="search" @reset="resetFilters">
      <q-input
        v-model="filters.account"
        class="col-12 col-sm-6 col-md-4"
        outlined
        dense
        clearable
        label="申请用户"
        :disable="loading"
        @keyup.enter="search"
      />
      <q-input
        v-model="filters.clientId"
        class="col-12 col-sm-6 col-md-4"
        outlined
        dense
        clearable
        label="客户端 ID"
        :disable="loading"
        @keyup.enter="search"
      />
    </AdminFilterPanel>

    <AdminDataTable
      :rows="rows"
      :columns="columns"
      :pagination="pagination"
      :loading="loading"
      :error-message="errorMessage"
      :page-count="pageCount"
      :action-busy="actionBusy"
      :actions-for="actionsFor"
      @request="onTableRequest"
      @reload="reload"
      @page="setPage"
      @action="runAction"
    />

    <AdminDangerDialog
      v-model="dialog.open"
      :title="
        dialog.action === 'approve-access-request'
          ? '通过访问申请'
          : '拒绝访问申请'
      "
      message="填写处理备注后将更新申请状态。"
      remark-mode
      :busy="!!actionBusy"
      :icon="
        dialog.action === 'approve-access-request' ? 'check_circle' : 'cancel'
      "
      @confirm="confirmHandle"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive } from "vue";
import type { QTableColumn } from "quasar";
import type { AuthAccessRequestItem } from "../../../models/AuthModels";
import { AdminApiService } from "../../../services/AdminApiService";
import AdminDataTable from "../components/AdminDataTable.vue";
import AdminDangerDialog from "../components/AdminDangerDialog.vue";
import AdminFilterPanel from "../components/AdminFilterPanel.vue";
import AdminPageHeader from "../components/AdminPageHeader.vue";
import { useAdminActions } from "../composables/useAdminActions";
import { usePagedQuery } from "../composables/usePagedQuery";
import type { AdminAction, AdminMetric, AdminRow } from "../types";

const api = new AdminApiService();
const query = usePagedQuery<AuthAccessRequestItem>(
  (values) => api.accessRequests(values),
  20,
);
const {
  rows,
  loading,
  errorMessage,
  filters,
  pagination,
  pageCount,
  metrics,
  reload,
  search,
  resetFilters,
  onTableRequest,
} = query;
const { actionBusy, runWithState } = useAdminActions(reload);
const dialog = reactive<{
  open: boolean;
  action: AdminAction;
  row: AuthAccessRequestItem | null;
}>({ open: false, action: "approve-access-request", row: null });

const columns: QTableColumn<AdminRow>[] = [
  { name: "primary", field: "id", label: "申请", align: "left" },
  { name: "status", field: "id", label: "状态", align: "left" },
  { name: "meta", field: "id", label: "时间", align: "left" },
  { name: "actions", field: "id", label: "操作", align: "right" },
];

const pageMetrics = computed<AdminMetric[]>(() => [
  { label: "申请总数", value: metrics.value.total, icon: "approval" },
  { label: "当前范围", value: metrics.value.range, icon: "view_timeline" },
  { label: "已加载", value: metrics.value.loaded, icon: "data_object" },
  {
    label: "筛选项",
    value: metrics.value.activeFilters,
    icon: "filter_alt",
    tone: "muted",
  },
]);

onMounted(() => {
  void reload();
});

function actionsFor(row: AdminRow) {
  const item = row as AuthAccessRequestItem;
  const disabled = item.status !== 0;
  return disabled
    ? []
    : [
        {
          key: "approve-access-request" as const,
          icon: "check_circle",
          label: "通过",
          color: "positive",
        },
        {
          key: "reject-access-request" as const,
          icon: "cancel",
          label: "拒绝",
          color: "negative",
        },
      ];
}

function runAction(action: AdminAction, row: AdminRow) {
  if (
    action !== "approve-access-request" &&
    action !== "reject-access-request"
  ) {
    return;
  }
  dialog.action = action;
  dialog.row = row as AuthAccessRequestItem;
  dialog.open = true;
}

function confirmHandle(remark: string) {
  if (!dialog.row) {
    return;
  }
  const row = dialog.row;
  const approved = dialog.action === "approve-access-request";
  void runWithState(`${dialog.action}:${row.id}`, () =>
    api.handleAccessRequest(row.id, approved ? 1 : 2, remark),
  ).then((success) => {
    if (success) {
      dialog.open = false;
      dialog.row = null;
    }
  });
}

function setPage(page: number) {
  pagination.value.page = page;
  void reload();
}
</script>
评论加载中...