Skip to content

Commit

Permalink
Merge pull request #83 from Avanade/78-filter-by-response
Browse files Browse the repository at this point in the history
78 filter by response
  • Loading branch information
iibuan authored Aug 28, 2024
2 parents e600fac + 366d3f5 commit ebca4f4
Show file tree
Hide file tree
Showing 50 changed files with 165 additions and 136 deletions.
132 changes: 70 additions & 62 deletions src/goapp/public/components/list.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,88 @@
const list = ({
enabledSearch = true,
otherState,
callback,
renderItem,
renderItem
}) => {
return {
// FILTER
search : '',
filter : 10,
page : 0,
state: {
// FILTER
search : '',
filter : 10,
page : 0,

// DISPLAY
total : 0,
showStart : 0,
showEnd : 0,
isLoading : false,
// DISPLAY
total : 0,
showStart : 0,
showEnd : 0,
isLoading : false,

items : [],
enabledSearch: true,

other: {},

items : []
},
async init(){
this.state.other = otherState
await this.load();
},
async load(){
this.isLoading = true
this.showStart = 0
this.showEnd = 0
const {data, total} = await callback({
filter : this.filter,
page : this.page,
search : this.search,
})
this.state.enabledSearch = enabledSearch
this.state.isLoading = true
this.state.showStart = 0
this.state.showEnd = 0
const {data, total} = await callback(this.state)

this.items = data
this.total = total
this.state.items = data
this.state.total = total

this.isLoading = false
this.state.isLoading = false

if (this.items == null || this.items.length == 0) return;
if (this.state.items == null || this.state.items.length == 0) return;

this.showStart = this.items.length > 0 ? ((this.page * this.filter) + 1) : 0;
this.showEnd = (this.page * this.filter) + this.items.length;
this.state.showStart = this.state.items.length > 0 ? ((this.state.page * this.state.filter) + 1) : 0;
this.state.showEnd = (this.state.page * this.state.filter) + this.state.items.length;
},
//EVENT HANDLERS
onChangeFilterHandler(e){
this.page = 0,
this.total = 0,
this.filter = parseInt(e.target.value);
this.state.page = 0,
this.state.total = 0,
this.state.filter = parseInt(e.target.value);
this.load()
},
onSearchSubmitHandler(e){
this.page = 0,
this.total = 0,
this.search = e.target.value;
this.state.page = 0,
this.state.total = 0,
this.state.search = e.target.value;
this.load();
},
onNextPageHandler(){
if (!this.nextPageEnabled()) return;

this.page = this.page + 1
this.state.page = this.state.page + 1

this.load()
},
onPreviousPageHandler(){
if (!this.previousPageEnabled()) return;

this.page = this.page - 1
this.state.page = this.state.page - 1

this.load();
},
//FUNCTIONS
nextPageEnabled(){
return this.page < Math.ceil(this.total/this.filter) - 1
return this.state.page < Math.ceil(this.state.total/this.state.filter) - 1
},
previousPageEnabled(){
return this.page > 0
return this.state.page > 0
},
checkItemLenght(){
if (!this.items ){
if (!this.state.items ){
return false
}
if (this.items.length == 0 ){
if (this.state.items.length == 0 ){
return false
}
return true
Expand All @@ -86,29 +92,19 @@ const list = ({
return renderItem(item)
},
template : `<nav class="bg-white flex items-center justify-between" aria-label="header">
<div class="sm:block">
<div>
<label for="filter" class="block text-sm font-medium text-gray-700">Filter</label>
<select @change="onChangeFilterHandler" x-model="filter" id="filter" name="filter" class="mt-1 block w-20 pl-3 pr-10 py-2 text-base text-center border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option>5</option>
<option>10</option>
<option>20</option>
<option>50</option>
<option>100</option>
</select>
</div>
</div>
<div class="flex justify-between sm:justify-end">
<div class="sm:col-span-3">
<label for="search" class="block text-sm font-medium text-gray-700">Search</label>
<div class="mt.-1">
<input @keyup.enter="onSearchSubmitHandler" type="text" name="search" id="search" class="block w-full focus:ring-indigo-500 focus:border-indigo-500 pl-2 sm:text-sm border-gray-300 rounded-md" x-model="search">
<template x-if="state.enabledSearch">
<div class="flex justify-between sm:justify-end">
<div class="sm:col-span-3">
<label for="search" class="block text-sm font-medium text-gray-700">Search</label>
<div class="mt.-1">
<input @keyup.enter="onSearchSubmitHandler" type="text" name="search" id="search" class="block w-full focus:ring-indigo-500 focus:border-indigo-500 pl-2 sm:text-sm border-gray-300 rounded-md" x-model="state.search">
</div>
</div>
</div>
</div>
</template>
</nav>
<div x-show='isLoading' x-transition>
<div x-show='state.isLoading' x-transition>
<svg
role="status"
class="w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-[#FF5800] m-auto my-5"
Expand All @@ -124,13 +120,13 @@ const list = ({
</svg>
</div>
<div x-show="!isLoading" x-transition>
<template x-if="!items">
<div x-show="!state.isLoading" x-transition>
<template x-if="!state.items">
<p class="text-center my-5">NO RESULT FOUND</p>
</template>
<template x-if="checkItemLenght ">
<ul role="list" class="divide-y divide-gray-300 my-3">
<template x-for="item in items">
<template x-for="item in state.items">
<li x-html="render(item)">
</li>
</template>
Expand All @@ -139,14 +135,26 @@ const list = ({
</div>
<nav class="bg-white py-3 flex items-center justify-between border-t border-gray-200" aria-label="Pagination">
<div class="sm:block">
<div class="content-start">
<label for="filter" class="text-sm font-medium text-gray-700">Filter</label>
<select @change="onChangeFilterHandler" x-model="state.filter" id="filter" name="filter" class="mt-1 w-20 pl-3 pr-10 py-2 text-base text-center border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option>5</option>
<option>10</option>
<option>20</option>
<option>50</option>
<option>100</option>
</select>
</div>
</div>
<div class="sm:block">
<p class="text-sm text-gray-700">
Showing
<span class="font-medium" x-text="showStart"></span>
<span class="font-medium" x-text="state.showStart"></span>
to
<span class="font-medium" x-text="showEnd"></span>
<span class="font-medium" x-text="state.showEnd"></span>
of
<span class="font-medium" x-text="total"></span>
<span class="font-medium" x-text="state.total"></span>
results
</p>
</div>
Expand Down
19 changes: 7 additions & 12 deletions src/goapp/routes/apis/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ const (
type ItemStatus int8

const (
Disapproved ItemStatus = iota
Pending ItemStatus = iota
Approved
Pending
AllStatus
Rejected
Closed // Disapproved, Approved
All // Disapproved, Approved, Pending
)

type Item struct {
Expand Down Expand Up @@ -75,13 +76,13 @@ func GetItems(w http.ResponseWriter, r *http.Request) {
}
user := fmt.Sprintf("%s", profile["preferred_username"])

itemType, errItemType := strconv.ParseInt(vars["type"], 10, 64)
itemType, errItemType := strconv.ParseInt(vars["type"], 10, 8)
if errItemType != nil {
http.Error(w, errItemType.Error(), http.StatusInternalServerError)
return
}

itemStatus, errItemStatus := strconv.ParseInt(vars["status"], 10, 64)
itemStatus, errItemStatus := strconv.ParseInt(vars["status"], 10, 8)
if errItemStatus != nil {
http.Error(w, errItemStatus.Error(), http.StatusInternalServerError)
return
Expand Down Expand Up @@ -127,14 +128,8 @@ func GetItemsBy(itemType ItemType, itemStatus ItemStatus, user, search string, o
params["ItemType"] = itemType
params["User"] = user
}
if itemStatus != AllStatus {
if itemStatus == Pending {
params["IsApproved"] = nil
} else {
params["IsApproved"] = itemStatus
}
}

params["IsApproved"] = itemStatus
params["Search"] = search

resultTotal, errResultTotal := db.ExecuteStoredProcedureWithResult("PR_Items_Total", params)
Expand Down
57 changes: 36 additions & 21 deletions src/goapp/templates/myapprovals.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,36 @@
<div x-html="template"></div>
</div>
</div>
<div x-show="activeTab == tabs[1]">
<h2 class="text-lg p-3 text-green-800 border-b">Approved Requests</h2>
<div x-show="activeTab == tabs[1]">
<div class="p-5" x-data="list({
callback: approvedCallback,
renderItem: closedRenderItem
})">
<div x-html="template"></div>
</div>
<h2 class="text-lg p-3 text-red-800 border-b">Rejected Requests</h2>
<div class="p-5" x-data="list({
callback: rejectedCallback,
enabledSearch: false,
otherState: { responseType: 'All'},
callback: closedCallback,
renderItem: closedRenderItem
})">
<nav class="bg-white flex items-center justify-between" aria-label="header">
<div class="sm:block">
<div class="content-start">
<label for="filter" class="block text-sm font-medium text-gray-700">Filter by Response</label>
<select @change="() => {
load()
}"
x-model="state.other.responseType" id="reponseType" name="responseType" class="block mt-1 pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option>All</option>
<option>Rejected</option>
<option>Approved</option>
</select>
</div>
</div>
<div class="flex justify-between sm:justify-end">
<div class="sm:col-span-3">
<label for="search" class="block text-sm font-medium text-gray-700">Search</label>
<div class="mt.-1">
<input @keyup.enter="onSearchSubmitHandler" type="text" name="search" id="search" class="block w-full focus:ring-indigo-500 focus:border-indigo-500 pl-2 sm:text-sm border-gray-300 rounded-md" x-model="state.search">
</div>
</div>
</div>
</nav>
<div x-html="template"></div>
</div>
</div>
Expand Down Expand Up @@ -140,7 +157,7 @@ <h2 class="text-lg p-3 text-red-800 border-b">Rejected Requests</h2>
}

async function pendingCallback(e){
return await getItemsBy(1, 2, e)
return await getItemsBy(1, 0, e.filter, e.page, e.search)
}

//CLOSED REQUEST
Expand Down Expand Up @@ -193,19 +210,17 @@ <h2 class="text-lg p-3 text-red-800 border-b">Rejected Requests</h2>
</div>`
}

async function approvedCallback(e){
return await getItemsBy(1, 1, e)
}

async function rejectedCallback(e){
return await getItemsBy(1, 0, e)
async function closedCallback(e){
const responses = [{name: 'All', value: 3}, {name: 'Rejected', value: 2}, {name: 'Approved', value: 1}]
selectedResponseType = responses.find((obj) => { return obj.name == e.other.responseType}).value
return await getItemsBy(1, selectedResponseType, e.filter, e.page, e.search)
}

async function getItemsBy(type, status, option){
const offset = option.filter * option.page;
const search = encodeURIComponent(option.search)
async function getItemsBy(type, status, filter, page, search){
const offset = filter * page;
search = encodeURIComponent(search)

const res = await fetch(`/api/items/type/${type}/status/${status}?filter=${option.filter}&offset=${offset}&search=${search}`)
const res = await fetch(`/api/items/type/${type}/status/${status}?filter=${filter}&offset=${offset}&search=${search}`)
const data = await res.json()
return data
}
Expand Down
Loading

0 comments on commit ebca4f4

Please sign in to comment.