managed filter fixed + distance calc to table
This commit is contained in:
parent
83b6d1710f
commit
383847e7f3
|
@ -26,15 +26,19 @@ import columnsRaw from "../config/defaultColumnRawDefinition";
|
||||||
import {transformValue} from "../util/tableValueMapper";
|
import {transformValue} from "../util/tableValueMapper";
|
||||||
import {filterUndefOrNull} from "../util/notEmpty";
|
import {filterUndefOrNull} from "../util/notEmpty";
|
||||||
import extendedFilter from "../util/datagrid/extendedFilter";
|
import extendedFilter from "../util/datagrid/extendedFilter";
|
||||||
|
import {haversine_distance, LatLng} from "../util/distance";
|
||||||
|
|
||||||
global.moment = moment
|
global.moment = moment
|
||||||
|
|
||||||
export type HostOfferLookupTableDataType = GetOffersQuery["get_offers"] & GetRwQuery["get_rw"];
|
export type HostOfferLookupTableDataType =
|
||||||
|
Omit<NonNullable<(GetOffersQuery["get_offers"] & GetRwQuery["get_rw"])>[number], '__typename'>
|
||||||
|
& { place_distance?: number };
|
||||||
export type HostOfferLookupTableProps = {
|
export type HostOfferLookupTableProps = {
|
||||||
data_ro?: GetOffersQuery["get_offers"],
|
data_ro?: GetOffersQuery["get_offers"],
|
||||||
data_rw?: GetRwQuery["get_rw"], // TODO
|
data_rw?: GetRwQuery["get_rw"], // TODO
|
||||||
refetch_rw: any,
|
refetch_rw: any,
|
||||||
onFilteredDataChange?: (data: HostOfferLookupTableDataType[]) => void
|
onFilteredDataChange?: (data: HostOfferLookupTableDataType[]) => void
|
||||||
|
center?: LatLng
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterMappings = {
|
const filterMappings = {
|
||||||
|
@ -94,6 +98,12 @@ const findMatchingRenderer = (c: Partial<ColumnRaw>) => {
|
||||||
return customRenderer?.render
|
return customRenderer?.render
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const floor = (v: number | undefined) => v && Math.floor(v);
|
||||||
|
|
||||||
|
const calculateDistance = (r: {place_lat?: number | null, place_lon?: number | null}, {lng, lat}: LatLng) =>
|
||||||
|
r.place_lat && r.place_lon && lng && lat
|
||||||
|
? floor(haversine_distance(lat, lng, r.place_lat, r.place_lon)) : r
|
||||||
|
|
||||||
const columns: TypeColumn[] = defaultColumnRawDefinition
|
const columns: TypeColumn[] = defaultColumnRawDefinition
|
||||||
.map(c => ({
|
.map(c => ({
|
||||||
...c,
|
...c,
|
||||||
|
@ -115,10 +125,12 @@ const defaultFilterValue: TypeFilterValue = columns
|
||||||
|
|
||||||
async function mutate(auth: AuthState, onEditComplete: { value: string, columnId: string, rowId: string }) {
|
async function mutate(auth: AuthState, onEditComplete: { value: string, columnId: string, rowId: string }) {
|
||||||
const type = typeof (onEditComplete.value)
|
const type = typeof (onEditComplete.value)
|
||||||
const onEditCompleteByType = {rowId: onEditComplete.rowId,
|
const onEditCompleteByType = {
|
||||||
|
rowId: onEditComplete.rowId,
|
||||||
columnId: onEditComplete.columnId,
|
columnId: onEditComplete.columnId,
|
||||||
value_boolean: type === 'boolean' && onEditComplete.value || null,
|
value_boolean: type === 'boolean' && onEditComplete.value || null,
|
||||||
value_string: type === 'string' && onEditComplete.value || null}
|
value_string: type === 'string' && onEditComplete.value || null
|
||||||
|
}
|
||||||
const result = await fetcher<any, any>(`mutation WriteRW($auth: Auth!, $onEditCompleteByType: Boolean) {
|
const result = await fetcher<any, any>(`mutation WriteRW($auth: Auth!, $onEditCompleteByType: Boolean) {
|
||||||
write_rw(auth: $auth, onEditCompleteByType: $onEditCompleteByType) }`,
|
write_rw(auth: $auth, onEditCompleteByType: $onEditCompleteByType) }`,
|
||||||
{auth, onEditCompleteByType})()
|
{auth, onEditCompleteByType})()
|
||||||
|
@ -129,26 +141,37 @@ const rw_default = {
|
||||||
rw_contacted: false,
|
rw_contacted: false,
|
||||||
rw_contact_replied: false,
|
rw_contact_replied: false,
|
||||||
rw_offer_occupied: false,
|
rw_offer_occupied: false,
|
||||||
rw_note: ''} // Required for filtering 'Not empty'. TODO: Should be fixed in StringFilter
|
rw_note: ''
|
||||||
|
} // Required for filtering 'Not empty'. TODO: Should be fixed in StringFilter
|
||||||
|
|
||||||
const HostOfferLookupTable = ({data_ro, data_rw, refetch_rw, onFilteredDataChange}: HostOfferLookupTableProps) => {
|
const HostOfferLookupTable = ({
|
||||||
|
data_ro,
|
||||||
|
data_rw,
|
||||||
|
refetch_rw,
|
||||||
|
onFilteredDataChange,
|
||||||
|
center
|
||||||
|
}: HostOfferLookupTableProps) => {
|
||||||
const [dataSource, setDataSource] = useState<HostOfferLookupTableDataType[]>([]);
|
const [dataSource, setDataSource] = useState<HostOfferLookupTableDataType[]>([]);
|
||||||
const [filteredData, setFilteredData] = useState<HostOfferLookupTableDataType[]>([]);
|
const [filteredData, setFilteredData] = useState<HostOfferLookupTableDataType[]>([]);
|
||||||
const [filterValue, setFilterValue] = useState<TypeFilterValue>(defaultFilterValue);
|
const [filterValue, setFilterValue] = useState<TypeFilterValue | undefined>(defaultFilterValue);
|
||||||
|
|
||||||
const filterValueChangeHandler = useCallback((_filterValue?: TypeFilterValue) => {
|
const filterValueChangeHandler = useCallback((_filterValue?: TypeFilterValue) => {
|
||||||
const data = !_filterValue
|
setFilterValue(_filterValue);
|
||||||
? dataSource
|
}, [setFilterValue])
|
||||||
: extendedFilter(
|
|
||||||
dataSource,
|
|
||||||
_filterValue,
|
|
||||||
columnsRaw
|
|
||||||
)
|
|
||||||
_filterValue && setFilterValue(_filterValue);
|
|
||||||
setFilteredData(data)
|
|
||||||
onFilteredDataChange && onFilteredDataChange(data)
|
|
||||||
}, [dataSource])
|
|
||||||
|
|
||||||
|
const filterAndSetData = useCallback(() => {
|
||||||
|
if (!filterValue) {
|
||||||
|
setFilteredData(dataSource)
|
||||||
|
onFilteredDataChange && onFilteredDataChange(dataSource)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const data = extendedFilter(dataSource, filterValue, columnsRaw)
|
||||||
|
setFilteredData(data)
|
||||||
|
}, [dataSource, onFilteredDataChange, setFilteredData, filterValue])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
filterAndSetData()
|
||||||
|
}, [dataSource, filterValue, filterAndSetData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const data = filterUndefOrNull(data_ro
|
const data = filterUndefOrNull(data_ro
|
||||||
|
@ -156,13 +179,13 @@ const HostOfferLookupTable = ({data_ro, data_rw, refetch_rw, onFilteredDataChang
|
||||||
...((data_rw?.find((e_rw) => e_ro.id_tmp === e_rw.id || `rw_${e_ro.id}` === e_rw.id
|
...((data_rw?.find((e_rw) => e_ro.id_tmp === e_rw.id || `rw_${e_ro.id}` === e_rw.id
|
||||||
) || rw_default)),
|
) || rw_default)),
|
||||||
...e_ro
|
...e_ro
|
||||||
}) ) || []).map(v => transformValue(v, columnsRaw))
|
})) || [])
|
||||||
|
.map(v => transformValue(v, columnsRaw))
|
||||||
|
.map(v => center ? {...v, place_distance: calculateDistance(v, center)} : v)
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
data && setDataSource(data)
|
data && setDataSource(data)
|
||||||
filterValueChangeHandler()
|
}, [data_ro, data_rw, center]);
|
||||||
//setDataSource((/*data_rw?.get_rw || */ data_ro?.get_offers || []).map(v => transformValue(v, columnsRaw)))
|
|
||||||
}, [data_ro, data_rw]);
|
|
||||||
|
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,6 @@ import {marker} from "leaflet";
|
||||||
|
|
||||||
type HostOfferLookupWrapperProps = Partial<HostOfferLookupTableProps>
|
type HostOfferLookupWrapperProps = Partial<HostOfferLookupTableProps>
|
||||||
|
|
||||||
function floor(v: number|undefined) {
|
|
||||||
return v && Math.floor(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
//type HostOfferLookupTableDataRowType = NonNullable<HostOfferLookupTableDataType>[number]
|
//type HostOfferLookupTableDataRowType = NonNullable<HostOfferLookupTableDataType>[number]
|
||||||
const makeMarker: (row: { id?: string | null; place_lon?: number | null; place_lat?: number | null }) => Marker | undefined =
|
const makeMarker: (row: { id?: string | null; place_lon?: number | null; place_lat?: number | null }) => Marker | undefined =
|
||||||
({ id, place_lon, place_lat }) => id && place_lon && place_lat && ({
|
({ id, place_lon, place_lat }) => id && place_lon && place_lat && ({
|
||||||
|
@ -39,20 +35,14 @@ const HostOfferLookupWrapper = (props: HostOfferLookupWrapperProps) => {
|
||||||
const {setMarkers, center, setFilteredMarkers} = useLeafletStore()
|
const {setMarkers, center, setFilteredMarkers} = useLeafletStore()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const markers = filterUndefOrNull( data_ro?.get_offers?.map(makeMarker) )
|
const markers = filterUndefOrNull( data_ro?.get_offers?.map(makeMarker) )
|
||||||
|
|
||||||
|
|
||||||
setMarkers(filterUndefOrNull(markers))
|
setMarkers(filterUndefOrNull(markers))
|
||||||
}, [data_ro])
|
}, [data_ro, setMarkers])
|
||||||
|
|
||||||
const data_ro_withDistance = data_ro?.get_offers?.map(r => ({...r,
|
|
||||||
place_distance: floor(haversine_distance(center?.lat, center?.lng, r.place_lat, r.place_lon))}))
|
|
||||||
|
|
||||||
const handleFilteredDataChange = useCallback(
|
const handleFilteredDataChange = useCallback(
|
||||||
(data: HostOfferLookupTableDataType[]) => {
|
(data: HostOfferLookupTableDataType[]) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const _filteredMarkers = filterUndefOrNull( data.map(d => d && makeMarker(d)))
|
const _filteredMarkers = filterUndefOrNull( data.map(d => d && makeMarker(d)))
|
||||||
console.log({_filteredMarkers})
|
setFilteredMarkers(_filteredMarkers)
|
||||||
//setFilteredMarkers(_filteredMarkers)
|
|
||||||
},
|
},
|
||||||
[setFilteredMarkers],
|
[setFilteredMarkers],
|
||||||
);
|
);
|
||||||
|
@ -74,10 +64,11 @@ const HostOfferLookupWrapper = (props: HostOfferLookupWrapperProps) => {
|
||||||
style={{flex: '1 1', height: '100%'}}>
|
style={{flex: '1 1', height: '100%'}}>
|
||||||
<HostOfferLookupTable
|
<HostOfferLookupTable
|
||||||
{...props}
|
{...props}
|
||||||
data_ro={data_ro_withDistance}
|
data_ro={data_ro.get_offers}
|
||||||
data_rw={data_rw?.get_rw}
|
data_rw={data_rw?.get_rw}
|
||||||
refetch_rw={queryResult_rw.refetch}
|
refetch_rw={queryResult_rw.refetch}
|
||||||
onFilteredDataChange={handleFilteredDataChange}
|
onFilteredDataChange={handleFilteredDataChange}
|
||||||
|
center={center || undefined}
|
||||||
/>
|
/>
|
||||||
</div>}
|
</div>}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
export type lon=number|null|undefined
|
export type Lng =number|null|undefined
|
||||||
export type lat=number|null|undefined
|
export type Lat =number|null|undefined
|
||||||
|
|
||||||
|
export type LatLng = {
|
||||||
|
lat: Lat
|
||||||
|
lng: Lng
|
||||||
|
}
|
||||||
|
|
||||||
/** optimization by https://stackoverflow.com/questions/5260423/torad-javascript-function-throwing-error/21623256#21623256 **/
|
/** optimization by https://stackoverflow.com/questions/5260423/torad-javascript-function-throwing-error/21623256#21623256 **/
|
||||||
export function haversine_distance(lat1:lat, lon1: lon, lat2:lat, lon2:lon) {
|
export function haversine_distance(lat1:Lat, lon1: Lng, lat2:Lat, lon2:Lng) {
|
||||||
if(lat1 && lon1 && lat2 && lon2) {
|
if(lat1 && lon1 && lat2 && lon2) {
|
||||||
var R = 6371 // Radius of the earth in km
|
var R = 6371 // Radius of the earth in km
|
||||||
var dLat = (lat2 - lat1) * Math.PI / 180 // deg2rad below
|
var dLat = (lat2 - lat1) * Math.PI / 180 // deg2rad below
|
||||||
|
|
Loading…
Reference in New Issue