Add address search to table; filter table on 2nd tab

dev
Platon Yasev 3 years ago
parent 04a31955d1
commit acd67f8d3a

@ -2,7 +2,7 @@ import { AutoComplete, Input } from "antd";
import { useQuery } from "@tanstack/react-query";
import { SearchOutlined } from "@ant-design/icons";
import { api } from "../api";
import { useEffect, useMemo, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useMap } from "react-map-gl";
import parse from "wellknown";
import { usePopup } from "../stores/usePopup.js";
@ -20,12 +20,15 @@ function useDebounce(value, delay) {
return debouncedValue;
}
export const AddressSearch = () => {
const renderLabel = (address) => <div>{address}</div>;
export const AddressSearch = ({ autoFocus = false }) => {
const { map } = useMap();
const [value, setValue] = useState("");
const debouncedValue = useDebounce(value);
const { setPopup } = usePopup();
const { setClickedPointConfig } = useClickedPointConfig();
const inputRef = useRef();
const { data } = useQuery(["address", debouncedValue], async () => {
const result = await api.get(
@ -39,7 +42,7 @@ export const AddressSearch = () => {
if (!data) return [];
return data.results.map((item) => ({
label: item.address,
label: renderLabel(item.address),
value: `${item.address}$${item.id}`,
item: item,
}));
@ -69,6 +72,12 @@ export const AddressSearch = () => {
setClickedPointConfig(feature.properties.id, false);
};
useEffect(() => {
if (autoFocus && inputRef?.current) {
inputRef.current.focus();
}
}, [autoFocus]);
return (
<div>
<AutoComplete
@ -81,11 +90,14 @@ export const AddressSearch = () => {
onSelect={handleSelect}
allowClear={true}
onClear={() => setValue("")}
autoFocus={autoFocus}
popupClassName={"overflow-visible"}
>
<Input
prefix={<SearchOutlined />}
placeholder="Введите адрес точки"
className="text-ellipsis"
ref={inputRef}
/>
</AutoComplete>
</div>

@ -16,7 +16,7 @@ export const PENDING_COLOR = {
export const CANCELLED_COLOR = "#CC2222";
export const APPROVE_COLOR = "#ff7d00";
export const WORKING_COLOR = "#006e01";
export const UNMATCHED_COLOR = "#b4b4b4";
export const UNMATCHED_COLOR = "rgba(196,195,195,0.6)";
export const PVZ_COLOR = "#3f5be8";
export const OTHER_POSTAMATES_COLOR = "#26a2a2";

@ -8,7 +8,6 @@ import {
PVZ_COLOR,
WORKING_COLOR,
} from "./Layers/layers-config";
import { Title } from "../components/Title";
const LegendPointItem = ({ color, name }) => {
return (
@ -47,44 +46,58 @@ export function Legend() {
return (
<div className="absolute bottom-[20px] left-[20px] text-xs text-grey z-10 bg-white-background rounded-xl p-3 space-y-3">
{mode !== MODES.WORKING && (
<div>
<Title text={"Статус локации"} className="text-center" />
<div className="space-y-1">
{mode === MODES.PENDING && (
<>
<LegendColorRampItem
colors={pendingColors}
name="К рассмотрению"
/>
<LegendPointItem name="Работает" color={WORKING_COLOR} />
<LegendPointItem name="Отменен" color={CANCELLED_COLOR} />
</>
)}
{mode === MODES.ON_APPROVAL && (
<>
<LegendPointItem
name="Согласование-установка"
color={APPROVE_COLOR}
/>
<LegendPointItem name="Работает" color={WORKING_COLOR} />
<LegendPointItem name="Отменен" color={CANCELLED_COLOR} />
</>
)}
</div>
</div>
)}
<div>
<Title text={"Прочее"} className="text-center" />
<div className="space-y-1">
<LegendPointItem name="ПВЗ" color={PVZ_COLOR} />
<LegendPointItem
name="Постаматы прочих сетей"
color={OTHER_POSTAMATES_COLOR}
/>
{mode === MODES.PENDING && (
<>
<LegendColorRampItem
colors={pendingColors}
name="Локации к рассмотрению"
/>
<LegendPointItem
name="Работающие постаматы"
color={WORKING_COLOR}
/>
<LegendPointItem
name="Отмененные локации"
color={CANCELLED_COLOR}
/>
</>
)}
{mode === MODES.ON_APPROVAL && (
<>
<LegendPointItem
name="Согласование-установка"
color={APPROVE_COLOR}
/>
<LegendPointItem
name="Работающие постаматы"
color={WORKING_COLOR}
/>
<LegendPointItem
name="Отмененные локации"
color={CANCELLED_COLOR}
/>
</>
)}
{mode === MODES.WORKING && (
<>
<LegendPointItem
name="Работающие постаматы"
color={WORKING_COLOR}
/>
</>
)}
</div>
</div>
<div className="space-y-1">
<LegendPointItem name="ПВЗ" color={PVZ_COLOR} />
<LegendPointItem
name="Постаматы прочих сетей"
color={OTHER_POSTAMATES_COLOR}
/>
</div>
</div>
);
}

@ -28,7 +28,7 @@ export const FeatureProperties = ({ feature, dynamicStatus, postamatId }) => {
return isWorking ? [...config, ...workingPointFields] : config;
};
const getValue = ({ field, render, empty, type }) => {
const getValue = ({ field, render, empty, type, fallbackField }) => {
let value = feature.properties[field];
if (field === "status" && dynamicStatus) {
@ -40,6 +40,7 @@ export const FeatureProperties = ({ feature, dynamicStatus, postamatId }) => {
}
if (type === "region") {
value = value ? value : feature.properties[fallbackField];
value = render(value, data?.normalized);
} else {
value = render ? render(value) : value;

@ -11,12 +11,14 @@ export const commonPopupConfig = [
{
name: "Район",
field: "area_id",
fallbackField: "area",
render: getRegionNameById,
type: "region",
},
{
name: "Округ",
field: "district_id",
fallbackField: "district",
render: getRegionNameById,
type: "region",
},

@ -61,6 +61,12 @@
padding: 8px;
}
.ant-select-item-option-content {
overflow: initial;
white-space: initial;
text-overflow: initial;
}
.generate-button {
color: #fff;
border-color: #cc2222ff !important;

@ -8,7 +8,9 @@ import { useMergeTableData } from "../useMergeTableData";
import { Header } from "./Header";
import { useOnApprovalPointsFilters } from "../../../stores/useOnApprovalPointsFilters";
import { MakeWorkingModal } from "./MakeWorkingTable/MakeWorkingModal";
import { useColumns } from "../useColumns.js";
import { useColumns } from "../useColumns.jsx";
import { useLayersVisibility } from "../../../stores/useLayersVisibility.js";
import { LAYER_IDS } from "../../../Map/Layers/constants.js";
const extraCols = [
{
@ -30,16 +32,31 @@ export const OnApprovalTable = ({ fullWidth }) => {
const [isMakeWorkingModalOpened, setIsMakeWorkingModalOpened] =
useState(false);
const columns = useColumns(extraCols);
const { isVisible } = useLayersVisibility();
const clearSelected = () => setSelectedIds([]);
const { data, isInitialLoading } = useQuery(
["on-approval-points", page, region],
["on-approval-points", page, region, isVisible],
async () => {
const statuses = [];
if (isVisible[LAYER_IDS.approve]) {
statuses.push(STATUSES.onApproval);
}
if (isVisible[LAYER_IDS.working]) {
statuses.push(STATUSES.working);
}
if (isVisible[LAYER_IDS.cancelled]) {
statuses.push(STATUSES.cancelled);
}
const params = new URLSearchParams({
page,
page_size: pageSize,
"status[]": [STATUSES.onApproval, STATUSES.working, STATUSES.cancelled],
"status[]": statuses,
});
return await getPoints(params, region);

@ -6,7 +6,7 @@ import { usePendingTableData } from "./usePendingTableData";
import { HeaderWrapper } from "../HeaderWrapper";
import { useExportPendingData } from "./useExportPendingData";
import { useCanEdit } from "../../../api";
import { useColumns } from "../useColumns.js";
import { useColumns } from "../useColumns.jsx";
export const PendingTable = ({ fullWidth }) => {
const { selection, include, exclude } = usePointSelection();

@ -8,7 +8,7 @@ import { Table } from "../Table";
import { HeaderWrapper } from "../HeaderWrapper";
import { useExportWorkingData } from "./useExportWorkingData";
import { useWorkingPointsFilters } from "../../../stores/useWorkingPointsFilters";
import { useColumns } from "./columns.js";
import { useColumns } from "./useColumns.jsx";
export const WorkingTable = ({ fullWidth }) => {
const [pageSize, setPageSize] = useState(PAGE_SIZE);

@ -1,6 +1,9 @@
import { useGetRegions } from "../../../components/RegionSelect.jsx";
import { useMemo } from "react";
import { getRegionNameById } from "../../../Map/Popup/mode-popup/config.js";
import { SearchOutlined } from "@ant-design/icons";
import { Button, Popover } from "antd";
import { AddressSearch } from "../../../Map/AddressSearch.jsx";
export const useColumns = () => {
const { data: regions } = useGetRegions();
@ -8,7 +11,20 @@ export const useColumns = () => {
return useMemo(() => {
return [
{
title: "Адрес",
title: (
<div className="flex items-center justify-between">
<span>Адрес</span>
<Popover
content={<AddressSearch autoFocus={true} />}
trigger="click"
placement={"right"}
>
<Button>
<SearchOutlined />
</Button>
</Popover>
</div>
),
dataIndex: "address",
key: "address",
width: 200,
@ -47,6 +63,13 @@ export const useColumns = () => {
width: "120px",
ellipsis: true,
},
{
title: "Прогнозный трафик",
dataIndex: "prediction_current",
key: "prediction_current",
width: "120px",
ellipsis: true,
},
{
title: "Факт",
dataIndex: "fact",
@ -68,6 +91,13 @@ export const useColumns = () => {
width: "120px",
ellipsis: true,
},
{
title: "Id постамата",
dataIndex: "postamat_id",
key: "postamat_id",
width: "70px",
ellipsis: true,
},
];
}, [regions?.normalized]);
};

@ -2,6 +2,9 @@ import { STATUS_LABEL_MAPPER } from "../../config";
import { useMemo } from "react";
import { useGetRegions } from "../../components/RegionSelect.jsx";
import { getRegionNameById } from "../../Map/Popup/mode-popup/config.js";
import { Button, Popover } from "antd";
import { AddressSearch } from "../../Map/AddressSearch.jsx";
import { SearchOutlined } from "@ant-design/icons";
export const useColumns = (fields = []) => {
const { data: regions } = useGetRegions();
@ -9,13 +12,20 @@ export const useColumns = (fields = []) => {
return useMemo(() => {
return [
{
title: "id",
dataIndex: "id",
key: "id",
width: 50,
},
{
title: "Адрес",
title: (
<div className="flex items-center justify-between">
<span>Адрес</span>
<Popover
content={<AddressSearch autoFocus={true} />}
trigger="click"
placement={"right"}
>
<Button>
<SearchOutlined />
</Button>
</Popover>
</div>
),
dataIndex: "address",
key: "address",
width: 200,
Loading…
Cancel
Save