Pārlūkot izejas kodu

feat: :sparkles: adicionar filtro de cargo e setor em gestao associados

Refs: 868kf24hh
joykepler 1 nedēļu atpakaļ
vecāks
revīzija
32595fd65f

+ 14 - 4
src/api/user.js

@@ -54,11 +54,21 @@ export const getParceiros = async () => {
   return users.filter((u) => u.type === "parceiro");
 };
 
-export const getUsersPaginated = async ({ page = 1, perPage = 10, filter, type, status } = {}) => {
+export const getUsersPaginated = async ({
+  page = 1,
+  perPage = 10,
+  filter,
+  type,
+  status,
+  position_id,
+  sector_id,
+} = {}) => {
   const params = { page, per_page: perPage };
-  if (type)   params.type   = type;
-  if (status) params.status = status;
-  if (filter) params.search = filter;
+  if (type)        params.type        = type;
+  if (status)      params.status      = status;
+  if (filter)      params.search      = filter;
+  if (position_id) params.position_id = position_id;
+  if (sector_id)   params.sector_id   = sector_id;
   const { data } = await api.get("/user/paginated", { params });
   return { data: { result: data.payload } };
 };

+ 21 - 5
src/components/defaults/DefaultTableServerSide.vue

@@ -19,9 +19,7 @@
     @row-click="onRowClick"
   >
     <template v-if="!semTableTop" #top>
-      <div
-        class="flex full-width justify-between items-center"
-      >
+      <div class="row full-width items-end q-gutter-sm">
         <DefaultInput
           v-if="showSearchField"
           v-model="pagination.filter"
@@ -32,16 +30,18 @@
           clearable
           autofocus
           color="violet-normal"
+          class="col-xs-12 col-md"
         >
           <template #prepend>
             <q-icon name="mdi-magnify" />
           </template>
         </DefaultInput>
 
+        <slot name="filters" />
+
         <DefaultSelect
           v-if="showColumnsSelect"
           v-model="visibleColumns"
-          class="q-ml-md"
           multiple
           dense
           outlined
@@ -157,6 +157,7 @@ const {
   hideNoDataLabel,
   deleteFunction,
   semTableTop,
+  extraFilters,
 } = defineProps({
   columns: {
     type: Array,
@@ -218,6 +219,10 @@ const {
     type: Boolean,
     default: false,
   },
+  extraFilters: {
+    type: Object,
+    default: () => ({}),
+  },
 });
 
 const { t } = useI18n();
@@ -310,6 +315,7 @@ const onRequest = async () => {
       page: pagination.value.page,
       perPage: pagination.value.rowsPerPage,
       filter: pagination.value.filter,
+      ...extraFilters,
     });
 
     rows.value = response.data.result.data;
@@ -351,12 +357,22 @@ watch(
   },
 );
 
+watch(
+  () => extraFilters,
+  () => {
+    if (loading.value) return;
+    pagination.value.page = 1;
+    onRequest();
+  },
+  { deep: true },
+);
+
 onMounted(async () => {
   await onRequest();
 });
 
 const usableSlots = (slots) => {
-  const handled = ["top", "body-cell-actions", "no-data", "bottom", "loading"];
+  const handled = ["top", "filters", "body-cell-actions", "no-data", "bottom", "loading"];
   return Object.keys(slots).filter((s) => !handled.includes(s));
 };
 

+ 31 - 0
src/pages/gestao-associados/GestaoAssociadosPage.vue

@@ -52,9 +52,31 @@
       :columns="columns"
       :api-call="getAssociadosPaginated"
       :add-item="false"
+      :extra-filters="extraFilters"
       open-item
       @on-row-click="onRowClick"
     >
+      <template #filters>
+        <PositionSelect
+          v-model="selectedPosition"
+          clearable
+          dense
+          outlined
+          color="violet-normal"
+          class="col-xs-12 col-sm-6 col-md-auto"
+          style="min-width: 180px"
+        />
+        <SectorSelect
+          v-model="selectedSector"
+          clearable
+          dense
+          outlined
+          color="violet-normal"
+          class="col-xs-12 col-sm-6 col-md-auto"
+          style="min-width: 180px"
+        />
+      </template>
+
       <template #body-cell-actions="{ row }">
         <div class="row no-wrap items-center" style="gap: 4px">
           <q-btn flat round dense color="violet-normal" icon="mdi-pencil" @click.stop="onRowClick({ row })" />
@@ -97,6 +119,8 @@ import { getStatusColor, getStatusI18nKey } from "src/helpers/utils";
 import { useImportPoller } from "src/composables/useImportPoller";
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
 import DefaultTableServerSide from "src/components/defaults/DefaultTableServerSide.vue";
+import PositionSelect from "src/components/selects/PositionSelect.vue";
+import SectorSelect from "src/components/selects/SectorSelect.vue";
 import AccessLogsTable from "./components/AccessLogsTable.vue";
 
 const AddEditAssociadoDialog = defineAsyncComponent(
@@ -113,6 +137,13 @@ const tableRef = ref(null);
 const importFileInput = useTemplateRef("importFileInput");
 const { polling: importing, start: startPolling } = useImportPoller();
 
+const selectedPosition = ref(null);
+const selectedSector = ref(null);
+const extraFilters = computed(() => ({
+  position_id: selectedPosition.value?.value,
+  sector_id: selectedSector.value?.value,
+}));
+
 const columns = computed(() => [
   {
     name: "registration",