Skip to content

Commit

Permalink
Merge pull request #62 from shariquerik/datetime-in-filter
Browse files Browse the repository at this point in the history
fix: Allow more fieldtypes in filter
  • Loading branch information
shariquerik authored Jan 28, 2024
2 parents ffe24b9 + d783b02 commit 6ffb2e8
Show file tree
Hide file tree
Showing 5 changed files with 794 additions and 30 deletions.
6 changes: 6 additions & 0 deletions crm/api/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ def get_filterable_fields(doctype: str):
"Data",
"Float",
"Int",
"Currency",
"Link",
"Long Text",
"Select",
"Small Text",
"Text Editor",
"Text",
"Duration",
"Date",
"Datetime",
]

c = get_controller(doctype)
Expand Down Expand Up @@ -84,6 +88,8 @@ def get_filterable_fields(doctype: str):
{"fieldname": "_liked_by", "fieldtype": "Data", "label": "Liked By"},
{"fieldname": "_comments", "fieldtype": "Text", "label": "Comments"},
{"fieldname": "_assign", "fieldtype": "Text", "label": "Assigned To"},
{"fieldname": "creation", "fieldtype": "Datetime", "label": "Created On"},
{"fieldname": "modified", "fieldtype": "Datetime", "label": "Last Updated On"},
]
for field in standard_fields:
if (
Expand Down
8 changes: 3 additions & 5 deletions crm/fcrm/doctype/crm_lead/crm_lead.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,13 @@
"fieldname": "no_of_employees",
"fieldtype": "Select",
"label": "No. of Employees",
"options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+",
"read_only": 1
"options": "1-10\n11-50\n51-200\n201-500\n501-1000\n1000+"
},
{
"fetch_from": "organization.annual_revenue",
"fieldname": "annual_revenue",
"fieldtype": "Currency",
"label": "Annual Revenue",
"read_only": 1
"label": "Annual Revenue"
},
{
"fieldname": "lead_owner",
Expand Down Expand Up @@ -294,7 +292,7 @@
"image_field": "image",
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-01-22 14:33:21.980634",
"modified": "2024-01-28 18:35:02.604536",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Lead",
Expand Down
265 changes: 265 additions & 0 deletions frontend/src/components/Controls/DatePicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
<template>
<Popover
@open="selectCurrentMonthYear"
class="flex w-full [&>div:first-child]:w-full"
>
<template #target="{ togglePopover }">
<input
readonly
type="text"
:placeholder="placeholder"
:value="value && formatter ? formatter(value) : value"
@focus="!readonly ? togglePopover() : null"
:class="[
'form-input block h-7 w-full cursor-pointer select-none rounded border-gray-400 text-sm placeholder-gray-500',
inputClass,
]"
/>
</template>
<template #body="{ togglePopover }">
<div
class="my-2 w-fit select-none space-y-3 rounded border border-gray-50 bg-white p-3 text-base shadow"
>
<div class="flex items-center text-gray-700">
<div
class="flex h-6 w-6 cursor-pointer items-center justify-center rounded hover:bg-gray-100"
>
<FeatherIcon
@click="prevMonth"
name="chevron-left"
class="h-5 w-5"
/>
</div>
<div class="flex-1 text-center text-lg font-medium text-blue-500">
{{ formatMonth }}
</div>
<div
class="flex h-6 w-6 cursor-pointer items-center justify-center rounded hover:bg-gray-100"
>
<FeatherIcon
@click="nextMonth"
name="chevron-right"
class="h-5 w-5"
/>
</div>
</div>
<div class="flex space-x-2">
<Input
type="text"
:value="value"
@change="selectDate(getDate($event)) || togglePopover()"
></Input>
<Button class="h-7" @click="selectDate(getDate()) || togglePopover()">
Today
</Button>
</div>
<div class="mt-2 flex flex-col items-center justify-center text-base">
<div class="flex w-full items-center space-x-1 text-gray-600">
<div
class="flex h-[30px] w-[30px] items-center justify-center text-center"
v-for="(d, i) in ['S', 'M', 'T', 'W', 'T', 'F', 'S']"
:key="i"
>
{{ d }}
</div>
</div>
<div v-for="(week, i) in datesAsWeeks" :key="i" class="mt-1">
<div class="flex w-full items-center">
<div
v-for="date in week"
:key="toValue(date)"
class="mr-1 flex h-[30px] w-[30px] cursor-pointer items-center justify-center rounded last:mr-0 hover:bg-blue-50 hover:text-blue-500"
:class="{
'text-gray-600': date.getMonth() !== currentMonth - 1,
'text-blue-500': toValue(date) === toValue(today),
'bg-blue-50 font-semibold text-blue-500':
toValue(date) === value,
}"
@click="
() => {
selectDate(date)
togglePopover()
}
"
>
{{ date.getDate() }}
</div>
</div>
</div>
</div>

<div class="mt-1 flex w-full justify-end">
<div
class="cursor-pointer rounded px-2 py-1 hover:bg-gray-100"
@click="
() => {
selectDate('')
togglePopover()
}
"
>
Clear
</div>
</div>
</div>
</template>
</Popover>
</template>

<script>
import { Popover } from 'frappe-ui'
export default {
name: 'DatePicker',
props: ['value', 'placeholder', 'formatter', 'readonly', 'inputClass'],
emits: ['change'],
components: {
Popover,
},
data() {
return {
currentYear: null,
currentMonth: null,
}
},
created() {
this.selectCurrentMonthYear()
},
computed: {
today() {
return this.getDate()
},
datesAsWeeks() {
let datesAsWeeks = []
let dates = this.dates.slice()
while (dates.length) {
let week = dates.splice(0, 7)
datesAsWeeks.push(week)
}
return datesAsWeeks
},
dates() {
if (!(this.currentYear && this.currentMonth)) {
return []
}
let monthIndex = this.currentMonth - 1
let year = this.currentYear
let firstDayOfMonth = this.getDate(year, monthIndex, 1)
let lastDayOfMonth = this.getDate(year, monthIndex + 1, 0)
let leftPaddingCount = firstDayOfMonth.getDay()
let rightPaddingCount = 6 - lastDayOfMonth.getDay()
let leftPadding = this.getDatesAfter(firstDayOfMonth, -leftPaddingCount)
let rightPadding = this.getDatesAfter(lastDayOfMonth, rightPaddingCount)
let daysInMonth = this.getDaysInMonth(monthIndex, year)
let datesInMonth = this.getDatesAfter(firstDayOfMonth, daysInMonth - 1)
let dates = [
...leftPadding,
firstDayOfMonth,
...datesInMonth,
...rightPadding,
]
if (dates.length < 42) {
const finalPadding = this.getDatesAfter(dates.at(-1), 42 - dates.length)
dates = dates.concat(...finalPadding)
}
return dates
},
formatMonth() {
let date = this.getDate(this.currentYear, this.currentMonth - 1, 1)
return date.toLocaleString('en-US', {
month: 'short',
year: 'numeric',
})
},
},
methods: {
selectDate(date) {
this.$emit('change', this.toValue(date))
},
selectCurrentMonthYear() {
let date = this.value ? this.getDate(this.value) : this.getDate()
if (date === 'Invalid Date') {
date = this.getDate()
}
this.currentYear = date.getFullYear()
this.currentMonth = date.getMonth() + 1
},
prevMonth() {
this.changeMonth(-1)
},
nextMonth() {
this.changeMonth(1)
},
changeMonth(adder) {
this.currentMonth = this.currentMonth + adder
if (this.currentMonth < 1) {
this.currentMonth = 12
this.currentYear = this.currentYear - 1
}
if (this.currentMonth > 12) {
this.currentMonth = 1
this.currentYear = this.currentYear + 1
}
},
getDatesAfter(date, count) {
let incrementer = 1
if (count < 0) {
incrementer = -1
count = Math.abs(count)
}
let dates = []
while (count) {
date = this.getDate(
date.getFullYear(),
date.getMonth(),
date.getDate() + incrementer
)
dates.push(date)
count--
}
if (incrementer === -1) {
return dates.reverse()
}
return dates
},
getDaysInMonth(monthIndex, year) {
let daysInMonthMap = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
let daysInMonth = daysInMonthMap[monthIndex]
if (monthIndex === 1 && this.isLeapYear(year)) {
return 29
}
return daysInMonth
},
isLeapYear(year) {
if (year % 400 === 0) return true
if (year % 100 === 0) return false
if (year % 4 === 0) return true
return false
},
toValue(date) {
if (!date) {
return ''
}
// toISOString is buggy and reduces the day by one
// this is because it considers the UTC timestamp
// in order to circumvent that we need to use luxon/moment
// but that refactor could take some time, so fixing the time difference
// as suggested in this answer.
// https://stackoverflow.com/a/16084846/3541205
date.setHours(0, -date.getTimezoneOffset(), 0, 0)
return date.toISOString().slice(0, 10)
},
getDate(...args) {
let d = new Date(...args)
return d
},
},
}
</script>
Loading

0 comments on commit 6ffb2e8

Please sign in to comment.