Advertisement
Chame

Table in Vue3/TS

Jan 28th, 2022
1,140
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <script lang="ts">
  2. import { defineComponent, ref, onMounted } from 'vue'
  3. import { UserType, GetUsers } from '@api/User'
  4.  
  5. import { ElInput, ElTable, ElTableColumn } from 'element-plus'
  6. import { takeLeft } from 'fp-ts/Array'
  7. import * as O from 'fp-ts/Option'
  8.  
  9. export default defineComponent({
  10.   components: {
  11.     ElInput,
  12.     ElTable,
  13.     ElTableColumn,
  14.   },
  15.   setup() {
  16.     const totalUsers = ref<UserType[]>([]) // baseline of all users
  17.     const displayableUsers = ref<UserType[]>([]) // users affected by filter
  18.     const displayedUsers = ref<UserType[]>([]) // users affected by filter, paginated
  19.     const chunks = ref<number>(0)
  20.  
  21.     const inactivityDate = new Date() // limited to defining imperative
  22.     inactivityDate.setMonth(inactivityDate.getMonth() - 3)
  23.  
  24.     const appendChunk = () => {
  25.       chunks.value += 1
  26.       displayedUsers.value = takeLeft(chunks.value * 1)(displayableUsers.value)
  27.     }
  28.  
  29.     const filterUsers = (filter: 'active' | 'inactive' | 'all' = 'all') => {
  30.       chunks.value = 0 // reset chunks
  31.  
  32.       // Update displayableUsers
  33.       switch (filter) {
  34.         case 'active':
  35.           displayableUsers.value = totalUsers.value.filter(
  36.             (x) => new Date(O.toNullable(x.lastAccess)) > inactivityDate
  37.           )
  38.           break
  39.         case 'inactive':
  40.           displayableUsers.value = totalUsers.value.filter(
  41.             (x) => new Date(O.toNullable(x.lastAccess)) < inactivityDate
  42.           )
  43.           break
  44.         default:
  45.           displayableUsers.value = totalUsers.value
  46.       }
  47.  
  48.       appendChunk() // display first chunk
  49.     }
  50.  
  51.     // Search ignores pagination, going through displayableUsers instead of displayedUsers
  52.     function searchDisplayable(search: string) {
  53.       return search
  54.         ? displayableUsers.value.filter(
  55.             (data) =>
  56.               !search || data.email.toLowerCase().includes(search.toLowerCase())
  57.           )
  58.         : displayedUsers.value
  59.     }
  60.  
  61.     onMounted(async () => {
  62.       totalUsers.value = await GetUsers() // baseline of all users
  63.       displayableUsers.value = totalUsers.value // users affected by filter
  64.       appendChunk() // display first chunk
  65.     })
  66.  
  67.     return {
  68.       search: ref<string>(''), // search string, only for template
  69.       searchDisplayable,
  70.       displayedUsers,
  71.       displayableUsers,
  72.       appendChunk,
  73.       filterUsers,
  74.       aestheticFilter: ref<number>(0), // radio display, only for template
  75.       toNullable: O.toNullable,
  76.     }
  77.   },
  78. })
  79. </script>
  80.  
  81. <template>
  82.   <button class="ontario-button--primary mt-0 float-end">
  83.     Create Microservice
  84.   </button>
  85.   <div class="clearfix"></div>
  86.  
  87.   <h2 class="h4 mt-5">All Users</h2>
  88.  
  89.   <router-link :to="{ name: 'usercreate' }" class="a_no_line">
  90.     <button type="button">Create User</button>
  91.   </router-link>
  92.  
  93.   <div>
  94.     <el-input v-model="search" placeholder="Type to search" />
  95.     <input
  96.       id="all"
  97.       v-model="aestheticFilter"
  98.       type="radio"
  99.       value="0"
  100.       @click="filterUsers('all')"
  101.     />
  102.     <label for="all">All users</label>
  103.     <input
  104.       id="active"
  105.       v-model="aestheticFilter"
  106.       type="radio"
  107.       value="1"
  108.       @click="filterUsers('active')"
  109.     />
  110.     <label for="all">Active</label>
  111.     <input
  112.       id="inactive"
  113.       v-model="aestheticFilter"
  114.       type="radio"
  115.       value="2"
  116.       @click="filterUsers('inactive')"
  117.     />
  118.     <label for="all">Inactive</label>
  119.  
  120.     <el-table :data="searchDisplayable(search)" style="width: 100%">
  121.       <el-table-column prop="email" label="User" width="180" sortable>
  122.         <template #default="scope">
  123.           <router-link
  124.             :to="{ name: 'useredit', params: { id: scope.row.id } }"
  125.             class="a_no_line"
  126.             >{{ scope.row.email }}</router-link
  127.           >
  128.         </template>
  129.       </el-table-column>
  130.       <el-table-column label="Last Accessed" width="180" sortable>
  131.         <template #default="scope">
  132.           <p>
  133.             {{
  134.               new Date(toNullable(scope.row.lastAccess))
  135.                 .toJSON()
  136.                 .slice(0, 10)
  137.                 .split('-')
  138.                 .reverse()
  139.                 .join('/')
  140.             }}
  141.           </p>
  142.         </template>
  143.       </el-table-column>
  144.       <el-table-column label="Microservice - Role - Ministry">
  145.         <template #default="scope">
  146.           <template
  147.             v-for="microservice in scope.row.microservices"
  148.             :key="microservice.microserviceName"
  149.           >
  150.             <p>{{ microservice.microserviceName }}</p>
  151.             <template v-for="role in microservice.roles" :key="role.roleName">
  152.               <p>{{ role.roleName }} - {{ role.ministryName.join(', ') }}</p>
  153.             </template>
  154.           </template>
  155.         </template>
  156.       </el-table-column>
  157.       <el-table-column label="Actions">
  158.         <div class="dropdown">
  159.           <button
  160.             :id="`dropdownMenu`"
  161.             class="btn btn-secondary dropdown-toggle"
  162.             type="button"
  163.             data-bs-toggle="dropdown"
  164.             aria-expanded="false"
  165.           >
  166.             Actions
  167.           </button>
  168.           <ul class="dropdown-menu" :aria-labelledby="`dropdownMenu`">
  169.             <li><a class="dropdown-item" href="#">Edit User</a></li>
  170.             <li><a class="dropdown-item" href="#">Reset Password</a></li>
  171.             <li><a class="dropdown-item" href="#">Resend 2FA</a></li>
  172.             <li><a class="dropdown-item" href="#">Reset 2FA</a></li>
  173.             <li><a class="dropdown-item" href="#">Activate/Deactivate</a></li>
  174.           </ul>
  175.         </div>
  176.       </el-table-column>
  177.     </el-table>
  178.     <button
  179.       v-if="!search.length && displayedUsers.length !== displayableUsers.length"
  180.       @click.prevent="appendChunk"
  181.     >
  182.       Load More
  183.     </button>
  184.   </div>
  185. </template>
  186.  
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement