From 66b34d7f29fe35f4d63a84bac60229e183fa4857 Mon Sep 17 00:00:00 2001 From: Sockenklaus Date: Mon, 18 Oct 2021 23:29:46 +0200 Subject: [PATCH] Added simpleSearch functionality to EmployeesController, solves #2 --- app/Controllers/Http/EmployeesController.ts | 177 ++++++++++++-------- 1 file changed, 106 insertions(+), 71 deletions(-) diff --git a/app/Controllers/Http/EmployeesController.ts b/app/Controllers/Http/EmployeesController.ts index ab9ec26..4397eba 100644 --- a/app/Controllers/Http/EmployeesController.ts +++ b/app/Controllers/Http/EmployeesController.ts @@ -4,101 +4,136 @@ import UpdateEmployeeValidator from 'App/Validators/UpdateEmployeeValidator' import CreateEmployeeValidator from 'App/Validators/CreateEmployeeValidator' import Database from '@ioc:Adonis/Lucid/Database' -import Logger from '@ioc:Adonis/Core/Logger' // TODO: #1 Implement paginator for Employee-Index export default class EmployeesController { - public async index ({bouncer, request}: HttpContextContract) { - await bouncer.authorize('employees.index') + public async index ({bouncer, request}: HttpContextContract) { + await bouncer.authorize('employees.index') - const limit: number = request.qs().limit ?? 10 - const page: number = request.qs().page ?? 1 - const sort_by = await this.sort_by(request.qs().sort_by) + const limit: number = request.qs().limit ?? 10 + const page: number = request.qs().page ?? 1 + const sortBy = await this.sortBy(request.qs().sort_by) + + const simpleSearch = await this.simpleSearch(request.qs().simple_search) - const employees = await Database.from('employees').orderBy(sort_by).paginate(page, limit) + const employees = Database.query() + employees.from('employees') - return employees - } + if(simpleSearch) { + simpleSearch.columns.forEach(column => { + employees.orWhere(column, 'like', `%${simpleSearch.query}%`) + }) + } - public async store ({request}: HttpContextContract) { - try { - const payload = await request.validate(CreateEmployeeValidator) + employees.orderBy(sortBy) - return await Employee.create({ - firstName: payload.firstName, - lastName: payload.lastName, - shorthand: payload.shorthand, - email: payload.email, - phone: payload.phone, - mobile: payload.mobile, - contractHours: payload.contractHours, - }) + return employees.paginate(page, limit) + } - } catch (error) { - return error - } + public async store ({request}: HttpContextContract) { + try { + const payload = await request.validate(CreateEmployeeValidator) - } + return await Employee.create({ + firstName: payload.firstName, + lastName: payload.lastName, + shorthand: payload.shorthand, + email: payload.email, + phone: payload.phone, + mobile: payload.mobile, + contractHours: payload.contractHours, + }) - public async show ({params, bouncer}: HttpContextContract) { - const emp = await Employee.findOrFail(params.id) + } catch (error) { + return error + } - await bouncer.authorize('employees.show', emp) + } - return emp - } + public async show ({params, bouncer}: HttpContextContract) { + const emp = await Employee.findOrFail(params.id) - public async update ({params, bouncer, response, request}: HttpContextContract) { + await bouncer.authorize('employees.show', emp) - const employee : Employee = await Employee.findOrFail(params.id) - const editContractHours : boolean = employee.contractHours !== request.input('contractHours') + return emp + } - await bouncer.authorize('employees.update', editContractHours, employee) + public async update ({params, bouncer, response, request}: HttpContextContract) { - const payload = await request.validate(UpdateEmployeeValidator) - - if (editContractHours){ - employee.contractHours = payload.contractHours ?? 0 - } + const employee : Employee = await Employee.findOrFail(params.id) + const editContractHours : boolean = employee.contractHours !== request.input('contractHours') - employee.firstName = payload.firstName - employee.lastName = payload.lastName ?? '' - employee.shorthand = payload.shorthand - employee.email = payload.email ?? '' - employee.phone = payload.phone ?? '' - employee.mobile = payload.mobile ?? '' + await bouncer.authorize('employees.update', editContractHours, employee) - await employee.save() - - return response.ok({ - status: 200, - message: "Employee updated successfully" - }) - } + const payload = await request.validate(UpdateEmployeeValidator) + + if (editContractHours){ + employee.contractHours = payload.contractHours ?? 0 + } - public async destroy ({params, bouncer}: HttpContextContract) { - await bouncer.authorize('employees.destroy') + employee.firstName = payload.firstName + employee.lastName = payload.lastName ?? '' + employee.shorthand = payload.shorthand + employee.email = payload.email ?? '' + employee.phone = payload.phone ?? '' + employee.mobile = payload.mobile ?? '' - return await Database.from('employees').where('id', params.id).delete() - } + await employee.save() + + return response.ok({ + status: 200, + message: "Employee updated successfully" + }) + } - private async sort_by(qs: string): Promise<{column : string, order?: 'asc' | 'desc' | undefined}[]> { - const regex : RegExp = /(asc|desc)\((\w+)\)/gi - const client = Database.connection() - let result: { - column: string, - order?: 'asc' | 'desc' | undefined - }[] = [] + public async destroy ({params, bouncer}: HttpContextContract) { + await bouncer.authorize('employees.destroy') - const columns = await client.columnsInfo('employees') - const match = qs?.matchAll(regex) ?? [] + return await Database.from('employees').where('id', params.id).delete() + } + + private async sortBy(qs: string): Promise<{column : string, order?: 'asc' | 'desc' | undefined}[]> { + const regex : RegExp = /(asc|desc)\((\w+)\)/gi + const client = Database.connection() + let result: { + column: string, + order?: 'asc' | 'desc' | undefined + }[] = [] + + const columns = await client.columnsInfo('employees') + const match = qs?.matchAll(regex) ?? [] - for (const item of match) { - if( columns.hasOwnProperty(item[2]) && (item[1] === 'asc' || item[1] === 'desc')) result.push({column: item[2], order: item[1]}) - } + for (const item of match) { + if( columns.hasOwnProperty(item[2]) && (item[1] === 'asc' || item[1] === 'desc')) result.push({column: item[2], order: item[1]}) + } - if(result.length === 0) result.push({column: 'last_name'}) + if(result.length === 0) result.push({column: 'last_name'}) - return result - } + return result + } + + private async simpleSearch(qs : string): Promise<{query: string, columns: string[]} | false>{ + if (!qs) return false + + const regex = /([\w@.]+)(?:\((\w+(?:,\w+)*)\))*/i + const columns = await Database.connection().columnsInfo('employees') + + const match = qs.match(regex) ?? [] + + let result: { + query: string, + columns: string[] + } = { + query: match[1] ?? '', + columns: [] + } + + match[2]?.split(',').filter(elem => columns.hasOwnProperty(elem.trim())).forEach((col) => { + result.columns.push(col.trim()) + }) + + if(result.columns.length < 1) result.columns = ['first_name', 'last_name'] + + return result + } }