Skip to content

Commit

Permalink
fix: add quick filter in view controls for list view
Browse files Browse the repository at this point in the history
  • Loading branch information
RitvikSardana committed Dec 3, 2024
1 parent f9a6bca commit ec0f12b
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 16 deletions.
5 changes: 1 addition & 4 deletions desk/src/components/view-controls/Filter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ import FilterIcon from "@/components/icons/FilterIcon.vue";
import {
FormControl,
createResource,
Tooltip,
DatePicker,
DateTimePicker,
Expand All @@ -169,7 +168,7 @@ import {
} from "frappe-ui";
import { AutocompleteNew } from "@/components";
import { h, computed, onMounted } from "vue";
import { h, computed } from "vue";
import { inject } from "vue";
import { useScreenSize } from "@/composables/screen";
Expand All @@ -189,8 +188,6 @@ const props = defineProps({
},
});
const emit = defineEmits(["update"]);
const listViewData = inject("listViewData");
const listViewActions = inject("listViewActions");
const { list, filterableFields } = listViewData;
Expand Down
67 changes: 67 additions & 0 deletions desk/src/components/view-controls/QuickFilterField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<FormControl
v-if="filter.type == 'Check'"
:label="filter.label"
type="checkbox"
v-model="filter.value"
@change.stop="updateFilter(filter, $event.target.checked)"
/>
<FormControl
v-else-if="filter.type === 'Select'"
class="form-control cursor-pointer [&_select]:cursor-pointer"
type="select"
v-model="filter.value"
:options="filter.options"
:placeholder="filter.label"
@change.stop="updateFilter(filter, $event.target.value)"
/>
<Link
v-else-if="filter.type === 'Link'"
:value="filter.value"
:doctype="filter.options"
:placeholder="filter.label"
@change="(data) => updateFilter(filter, data)"
/>
<component
v-else-if="['Date', 'Datetime'].includes(filter.type)"
class="border-none"
:is="filter.type === 'Date' ? DatePicker : DateTimePicker"
:value="filter.value"
@change="(v) => updateFilter(filter, v)"
:placeholder="filter.label"
/>
<TextInput
v-else
v-model="filter.value"
type="text"
:placeholder="filter.label"
@input.stop="debouncedFn(filter, $event.target.value)"
/>
</template>
<script setup>
import {
TextInput,
FormControl,
DatePicker,
DateTimePicker,
Link,
} from "frappe-ui";
import { useDebounceFn } from "@vueuse/core";
const props = defineProps({
filter: {
type: Object,
required: true,
},
});
const emit = defineEmits(["applyQuickFilter"]);
const debouncedFn = useDebounceFn((f, value) => {
emit("applyQuickFilter", f, value);
}, 500);
function updateFilter(f, value) {
emit("applyQuickFilter", f, value);
}
</script>
52 changes: 52 additions & 0 deletions desk/src/components/view-controls/QuickFilters.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<div
v-if="!quickFilters.loading"
class="flex items-center justify-between gap-2 px-5 py-4"
>
<FadedScrollableDiv
class="flex flex-1 items-center overflow-x-auto -ml-1"
orientation="horizontal"
>
<div
v-for="filter in quickFilters.data"
:key="filter.name"
class="m-1 min-w-36"
>
<QuickFilterField
:filter="filter"
@applyQuickFilter="(f, v) => applyQuickFilter(f, v)"
/>
</div>
</FadedScrollableDiv>
</div>
</template>

<script setup>
import { inject } from "vue";
import { FadedScrollableDiv } from "@/components";
import QuickFilterField from "./QuickFilterField.vue";
const listViewData = inject("listViewData");
const listViewActions = inject("listViewActions");
const { list, quickFilters } = listViewData;
function applyQuickFilter(filter, value) {
let filters = { ...list.params.filters };
let field = filter.name;
if (value) {
if (["Check", "Select", "Link", "Date", "Datetime"].includes(filter.type)) {
filters[field] = value;
} else {
filters[field] = ["LIKE", `%${value}%`];
}
filter["value"] = value;
} else {
delete filters[field];
filter["value"] = "";
}
listViewActions.applyFilters(filters);
}
</script>

<style lang="scss" scoped></style>
2 changes: 1 addition & 1 deletion desk/src/components/view-controls/SortBy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ const sortSortable = useSortable("#sort-list", sortValues, {
});
function getSortLabel() {
if (!sortValues.size) return "Sort";
if (!sortValues.value.size) return "Sort";
let values = Array.from(sortValues.value);
let label = sortOptions.data?.find(
(option) => option.value === values[0].fieldname
Expand Down
2 changes: 1 addition & 1 deletion desk/src/components/view-controls/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { default as Filter } from "./Filter.vue";
export { default as SortBy } from "./SortBy.vue";
//
export { default as QuickFilters } from "./QuickFilters.vue";
22 changes: 12 additions & 10 deletions desk/src/pages/desk/agent/Agents.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,19 @@
</Button>
</template>
</LayoutHeader>
<div v-if="!filterableFields.loading && !sortableFields.loading">
<div
v-if="
!filterableFields.loading &&
!sortableFields.loading &&
!quickFilters.loading
"
>
<Filter class="w-fit" />
<SortBy class="w-fit" :hide-label="false" :docType="'HD Agent'" />
<QuickFilters class="w-fit" />
</div>
<div>
{{ agents?.data?.data }}
</div>
<AddNewAgentsDialog
:show="isDialogVisible"
Expand All @@ -32,7 +42,7 @@ import { reactive, ref, provide } from "vue";
import { usePageMeta, Avatar, Badge, createResource } from "frappe-ui";
import AddNewAgentsDialog from "@/components/desk/global/AddNewAgentsDialog.vue";
import LayoutHeader from "@/components/LayoutHeader.vue";
import { Filter, SortBy } from "@/components/view-controls";
import { Filter, SortBy, QuickFilters } from "@/components/view-controls";
const isDialogVisible = ref(false);
Expand Down Expand Up @@ -98,28 +108,20 @@ provide("listViewActions", {
applyFilters,
applySort,
addColumn,
applyQuickFilter,
});
function applyFilters(filters) {
console.log("APPLY FILTER", filters);
agents.filters = filters;
agents.submit({ filters });
}
function applySort(sort_by) {
agents.sort_by = sort_by;
agents.submit({ sort_by });
}
function addColumn(field) {
console.log("ADD COLUMN", field);
}
function applyQuickFilter(filter) {
console.log("APPLY QUICK FILTER", filter);
}
usePageMeta(() => {
return {
title: "Agents",
Expand Down
30 changes: 30 additions & 0 deletions helpdesk/api/doc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import frappe
from frappe import _
from frappe.model import no_value_fields
from frappe.model.document import get_controller
from frappe.utils.caching import redis_cache
Expand Down Expand Up @@ -256,6 +257,35 @@ def sort_options(doctype: str, show_customer_portal_fields=False):
return fields


@frappe.whitelist()
def get_quick_filters(doctype: str):
meta = frappe.get_meta(doctype)
fields = [field for field in meta.fields if field.in_standard_filter]
quick_filters = []

if doctype == "HD Agent":
quick_filters.append({"label": "ID", "value": "", "name": "name"})

for field in fields:
if field.fieldtype == "Select":
field.options = field.options.split("\n")
field.options = [
{"label": option, "value": option} for option in field.options
]
field.options.insert(0, {"label": "", "value": ""})

quick_filters.append(
{
"label": _(field.label),
"name": field.fieldname,
"type": field.fieldtype,
"options": field.options,
}
)

return quick_filters


def get_customer_portal_fields(doctype, fields):
visible_custom_fields = get_visible_custom_fields()
customer_portal_fields = [
Expand Down

0 comments on commit ec0f12b

Please sign in to comment.