diff --git a/src/pages/Article/ArticleListPage/index.tsx b/src/pages/Article/ArticleListPage/index.tsx
index 118ecbc..46bda00 100644
--- a/src/pages/Article/ArticleListPage/index.tsx
+++ b/src/pages/Article/ArticleListPage/index.tsx
@@ -1,7 +1,7 @@
import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { ruRU } from "@mui/x-data-grid/locales";
-import { authStore, articlesStore, languageStore } from "@shared";
-import { useEffect, useState } from "react";
+import { authStore, articlesStore, languageStore, SearchInput } from "@shared";
+import { useEffect, useState, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { Trash2, Eye, Minus } from "lucide-react";
import { useNavigate } from "react-router-dom";
@@ -22,6 +22,7 @@ export const ArticleListPage = observer(() => {
pageSize: 50,
});
const canWriteArticles = authStore.canWrite("sights");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchArticles = async () => {
@@ -72,11 +73,16 @@ export const ArticleListPage = observer(() => {
},
];
- const rows = articleList[language].data.map((article) => ({
- id: article.id,
- heading: article.heading,
- body: article.body,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return articleList[language].data
+ .filter((article) => !query || (article.heading ?? "").toLowerCase().includes(query))
+ .map((article) => ({
+ id: article.id,
+ heading: article.heading,
+ body: article.body,
+ }));
+ }, [articleList[language].data, searchQuery]);
return (
<>
@@ -99,6 +105,8 @@ export const ArticleListPage = observer(() => {
)}
+
+
{
});
const { language } = languageStore;
const canReadCities = authStore.canRead("cities");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchData = async () => {
@@ -119,16 +120,23 @@ export const CarrierListPage = observer(() => {
const canWriteCarriers = authStore.canWrite("carriers");
- const rows = carriers[language].data
- ?.filter((carrier) =>
- !allowedCityIds || allowedCityIds.includes(carrier.city_id),
- )
- .map((carrier) => ({
- id: carrier.id,
- full_name: carrier.full_name,
- short_name: carrier.short_name,
- city_id: carrier.city_id,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return (carriers[language].data ?? [])
+ .filter((carrier) => !allowedCityIds || allowedCityIds.includes(carrier.city_id))
+ .filter(
+ (carrier) =>
+ !query ||
+ (carrier.full_name ?? "").toLowerCase().includes(query) ||
+ (carrier.short_name ?? "").toLowerCase().includes(query)
+ )
+ .map((carrier) => ({
+ id: carrier.id,
+ full_name: carrier.full_name,
+ short_name: carrier.short_name,
+ city_id: carrier.city_id,
+ }));
+ }, [carriers[language].data, searchQuery, allowedCityIds]);
return (
<>
@@ -153,6 +161,8 @@ export const CarrierListPage = observer(() => {
)}
+
+
{
});
const { language } = languageStore;
const canWriteCities = authStore.canWrite("cities");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchData = async () => {
@@ -57,6 +58,18 @@ export const CityListPage = observer(() => {
setRows(newRows2 || []);
}, [cities, countryStore.countries, language, isLoading]);
+ const filteredRows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ if (!query) return rows;
+ return rows.filter((row) => {
+ const cityName = (row.name ?? "").toLowerCase();
+ const countryName = (
+ countryStore.countries[language]?.data?.find((c) => c.code === row.country)?.name ?? ""
+ ).toLowerCase();
+ return cityName.includes(query) || countryName.includes(query);
+ });
+ }, [rows, searchQuery, countryStore.countries, language]);
+
const columns: GridColDef[] = [
{
field: "country",
@@ -142,8 +155,10 @@ export const CityListPage = observer(() => {
)}
+
+
{
});
const { language } = languageStore;
const canWriteCountries = authStore.canWrite("countries");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchCountries = async () => {
@@ -72,11 +73,16 @@ export const CountryListPage = observer(() => {
}] : []),
];
- const rows = countries[language]?.data.map((country) => ({
- id: country.code,
- code: country.code,
- name: country.name,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return (countries[language]?.data ?? [])
+ .filter((country) => !query || (country.name ?? "").toLowerCase().includes(query))
+ .map((country) => ({
+ id: country.code,
+ code: country.code,
+ name: country.name,
+ }));
+ }, [countries[language]?.data, searchQuery]);
return (
<>
@@ -102,8 +108,10 @@ export const CountryListPage = observer(() => {
)}
+
+
{
});
const { language } = languageStore;
const canWriteMedia = authStore.canWrite("sights");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchMedia = async () => {
@@ -95,15 +96,22 @@ export const MediaListPage = observer(() => {
},
];
- const rows = media.map((media) => ({
- id: media.id,
- media_name: media.media_name,
- media_type: media.media_type,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return media
+ .filter((item) => !query || (item.media_name ?? "").toLowerCase().includes(query))
+ .map((item) => ({
+ id: item.id,
+ media_name: item.media_name,
+ media_type: item.media_type,
+ }));
+ }, [media, searchQuery]);
return (
<>
+
+
{canWriteMedia && ids.length > 0 && (
)}
+
+
{
});
const { language } = languageStore;
const canReadCities = authStore.canRead("cities");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchSights = async () => {
@@ -120,13 +122,16 @@ export const SightListPage = observer(() => {
});
}, [sights, selectedCityStore.selectedCityId, canReadCities, authStore.meCities]);
- const canWriteSights = authStore.canWrite("sights");
+ const query = searchQuery.toLowerCase();
+ const rows = filteredSights
+ .filter((sight: any) => !query || (sight.name ?? "").toLowerCase().includes(query))
+ .map((sight) => ({
+ id: sight.id,
+ name: sight.name,
+ city_id: sight.city_id,
+ }));
- const rows = filteredSights.map((sight) => ({
- id: sight.id,
- name: sight.name,
- city_id: sight.city_id,
- }));
+ const canWriteSights = authStore.canWrite("sights");
return (
<>
@@ -155,6 +160,8 @@ export const SightListPage = observer(() => {
)}
+
+
{
const { language } = languageStore;
const [isRestoreModalOpen, setIsRestoreModalOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
+ const [searchQuery, setSearchQuery] = useState("");
const [paginationModel, setPaginationModel] = useState({
page: 0,
pageSize: 50,
@@ -89,22 +90,35 @@ export const SnapshotListPage = observer(() => {
}] : []),
];
- const rows = snapshots.map((snapshot) => ({
- id: snapshot.ID,
- name: snapshot.Name,
- parent: snapshots.find((s) => s.ID === snapshot.ParentID)?.Name,
- created_at: formatCreationTime(snapshot.CreationTime),
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return snapshots
+ .filter(
+ (snapshot) =>
+ !query ||
+ (snapshot.Name ?? "").toLowerCase().includes(query) ||
+ (snapshots.find((s) => s.ID === snapshot.ParentID)?.Name ?? "").toLowerCase().includes(query)
+ )
+ .map((snapshot) => ({
+ id: snapshot.ID,
+ name: snapshot.Name,
+ parent: snapshots.find((s) => s.ID === snapshot.ParentID)?.Name,
+ created_at: formatCreationTime(snapshot.CreationTime),
+ }));
+ }, [snapshots, searchQuery]);
return (
<>
Экспорт Медиа
+
{canCreateSnapshot && (
)}
+
+
{
});
const { language } = languageStore;
const canWriteStations = authStore.canWrite("stations");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchStations = async () => {
@@ -121,21 +123,23 @@ export const StationListPage = observer(() => {
},
];
- const filteredStations = () => {
+ const rows = useMemo(() => {
const { selectedCityId } = selectedCityStore;
- if (!selectedCityId) {
- return stationLists[language].data;
- }
- return stationLists[language].data.filter(
- (station: any) => station.city_id === selectedCityId
- );
- };
-
- const rows = filteredStations().map((station: any) => ({
- id: station.id,
- name: station.name,
- description: station.description,
- }));
+ const query = searchQuery.toLowerCase();
+ return stationLists[language].data
+ .filter((station: any) => !selectedCityId || station.city_id === selectedCityId)
+ .filter(
+ (station: any) =>
+ !query ||
+ (station.name ?? "").toLowerCase().includes(query) ||
+ (station.description ?? "").toLowerCase().includes(query)
+ )
+ .map((station: any) => ({
+ id: station.id,
+ name: station.name,
+ description: station.description,
+ }));
+ }, [stationLists[language].data, selectedCityStore.selectedCityId, searchQuery]);
return (
<>
@@ -161,6 +165,8 @@ export const StationListPage = observer(() => {
)}
+
+
{
pageSize: 50,
});
const canWriteUsers = authStore.canWrite("users");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchUsers = async () => {
@@ -107,12 +108,21 @@ export const UserListPage = observer(() => {
}] : []),
];
- const rows = users.data?.map((user) => ({
- id: user.id,
- email: user.email,
- is_admin: user.is_admin || (user.roles ?? []).includes("admin"),
- name: user.name,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return (users.data ?? [])
+ .filter((user) =>
+ !query ||
+ (user.name ?? "").toLowerCase().includes(query) ||
+ (user.email ?? "").toLowerCase().includes(query)
+ )
+ .map((user) => ({
+ id: user.id,
+ email: user.email,
+ is_admin: user.is_admin || (user.roles ?? []).includes("admin"),
+ name: user.name,
+ }));
+ }, [users.data, searchQuery]);
return (
<>
@@ -136,6 +146,8 @@ export const UserListPage = observer(() => {
)}
+
+
{
});
const { language } = languageStore;
const canWriteVehicles = authStore.canWrite("devices");
+ const [searchQuery, setSearchQuery] = useState("");
useEffect(() => {
const fetchData = async () => {
@@ -136,27 +137,40 @@ export const VehicleListPage = observer(() => {
},
];
- const rows = vehicles.data?.map((vehicle) => ({
- id: vehicle.vehicle.id,
- tail_number: vehicle.vehicle.tail_number,
- type: vehicle.vehicle.type,
- carrier: vehicle.vehicle.carrier,
- city: carriers[language].data?.find(
- (carrier) => carrier.id === vehicle.vehicle.carrier_id
- )?.city,
- }));
+ const rows = useMemo(() => {
+ const query = searchQuery.toLowerCase();
+ return (vehicles.data ?? [])
+ .filter(
+ (vehicle) =>
+ !query ||
+ (vehicle.vehicle.tail_number ?? "").toLowerCase().includes(query) ||
+ (vehicle.vehicle.carrier ?? "").toLowerCase().includes(query)
+ )
+ .map((vehicle) => ({
+ id: vehicle.vehicle.id,
+ tail_number: vehicle.vehicle.tail_number,
+ type: vehicle.vehicle.type,
+ carrier: vehicle.vehicle.carrier,
+ city: carriers[language].data?.find(
+ (carrier) => carrier.id === vehicle.vehicle.carrier_id
+ )?.city,
+ }));
+ }, [vehicles.data, carriers[language].data, searchQuery]);
return (
<>
Транспортные средства
+
+
+
{canWriteVehicles && ids.length > 0 && (