fixed prices, but still working on filters
This commit is contained in:
@ -63,6 +63,7 @@ const FiltersPanelMobile: React.FC<FiltersPanelMobileProps> = ({
|
|||||||
setLocalFilterValues({});
|
setLocalFilterValues({});
|
||||||
onSearchChange('');
|
onSearchChange('');
|
||||||
// Сбрасываем фильтры в родительском компоненте
|
// Сбрасываем фильтры в родительском компоненте
|
||||||
|
// Используем пустые массивы для правильной очистки
|
||||||
Object.keys(filterValues).forEach(key => {
|
Object.keys(filterValues).forEach(key => {
|
||||||
onFilterChange?.(key, []);
|
onFilterChange?.(key, []);
|
||||||
});
|
});
|
||||||
|
@ -56,6 +56,36 @@ export default function Catalog() {
|
|||||||
const [showSortMobile, setShowSortMobile] = useState(false);
|
const [showSortMobile, setShowSortMobile] = useState(false);
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
const [selectedFilters, setSelectedFilters] = useState<{[key: string]: string[]}>({});
|
const [selectedFilters, setSelectedFilters] = useState<{[key: string]: string[]}>({});
|
||||||
|
|
||||||
|
// Инициализация фильтров из URL при загрузке
|
||||||
|
useEffect(() => {
|
||||||
|
if (router.isReady) {
|
||||||
|
const urlFilters: {[key: string]: string[]} = {};
|
||||||
|
const urlSearchQuery = router.query.q as string || '';
|
||||||
|
|
||||||
|
// Восстанавливаем фильтры из URL
|
||||||
|
Object.keys(router.query).forEach(key => {
|
||||||
|
if (key.startsWith('filter_')) {
|
||||||
|
const filterName = key.replace('filter_', '');
|
||||||
|
const filterValue = router.query[key];
|
||||||
|
if (typeof filterValue === 'string') {
|
||||||
|
urlFilters[filterName] = [filterValue];
|
||||||
|
} else if (Array.isArray(filterValue)) {
|
||||||
|
urlFilters[filterName] = filterValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🔗 Восстанавливаем фильтры из URL:', { urlFilters, urlSearchQuery });
|
||||||
|
|
||||||
|
if (Object.keys(urlFilters).length > 0) {
|
||||||
|
setSelectedFilters(urlFilters);
|
||||||
|
}
|
||||||
|
if (urlSearchQuery) {
|
||||||
|
setSearchQuery(urlSearchQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [router.isReady]);
|
||||||
const [visibleArticles, setVisibleArticles] = useState<PartsAPIArticle[]>([]);
|
const [visibleArticles, setVisibleArticles] = useState<PartsAPIArticle[]>([]);
|
||||||
const [visibleEntities, setVisibleEntities] = useState<PartsIndexEntity[]>([]);
|
const [visibleEntities, setVisibleEntities] = useState<PartsIndexEntity[]>([]);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -80,6 +110,7 @@ export default function Catalog() {
|
|||||||
const [isAutoLoading, setIsAutoLoading] = useState(false); // Автоматическая подгрузка в процессе
|
const [isAutoLoading, setIsAutoLoading] = useState(false); // Автоматическая подгрузка в процессе
|
||||||
const [currentUserPage, setCurrentUserPage] = useState(1); // Текущая пользовательская страница
|
const [currentUserPage, setCurrentUserPage] = useState(1); // Текущая пользовательская страница
|
||||||
const [entitiesCache, setEntitiesCache] = useState<Map<number, PartsIndexEntity[]>>(new Map()); // Кэш страниц
|
const [entitiesCache, setEntitiesCache] = useState<Map<number, PartsIndexEntity[]>>(new Map()); // Кэш страниц
|
||||||
|
const [isFilterChanging, setIsFilterChanging] = useState(false); // Флаг изменения фильтров
|
||||||
|
|
||||||
// Карта видимости товаров по индексу
|
// Карта видимости товаров по индексу
|
||||||
const [visibilityMap, setVisibilityMap] = useState<Map<number, boolean>>(new Map());
|
const [visibilityMap, setVisibilityMap] = useState<Map<number, boolean>>(new Map());
|
||||||
@ -209,9 +240,16 @@ export default function Catalog() {
|
|||||||
console.log('📊 Обновляем entitiesData:', {
|
console.log('📊 Обновляем entitiesData:', {
|
||||||
listLength: entitiesData.partsIndexCatalogEntities.list.length,
|
listLength: entitiesData.partsIndexCatalogEntities.list.length,
|
||||||
pagination: entitiesData.partsIndexCatalogEntities.pagination,
|
pagination: entitiesData.partsIndexCatalogEntities.pagination,
|
||||||
currentPage: entitiesData.partsIndexCatalogEntities.pagination?.page?.current || 1
|
currentPage: entitiesData.partsIndexCatalogEntities.pagination?.page?.current || 1,
|
||||||
|
isFilterChanging
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Если изменяются фильтры, сбрасываем флаг после получения новых данных
|
||||||
|
if (isFilterChanging) {
|
||||||
|
setIsFilterChanging(false);
|
||||||
|
console.log('🔄 Сброшен флаг isFilterChanging - получены новые отфильтрованные данные');
|
||||||
|
}
|
||||||
|
|
||||||
const newEntities = entitiesData.partsIndexCatalogEntities.list;
|
const newEntities = entitiesData.partsIndexCatalogEntities.list;
|
||||||
const pagination = entitiesData.partsIndexCatalogEntities.pagination;
|
const pagination = entitiesData.partsIndexCatalogEntities.pagination;
|
||||||
|
|
||||||
@ -229,9 +267,13 @@ export default function Catalog() {
|
|||||||
// Если это первая страница или сброс, заменяем накопленные товары
|
// Если это первая страница или сброс, заменяем накопленные товары
|
||||||
if (currentPage === 1) {
|
if (currentPage === 1) {
|
||||||
setAccumulatedEntities(newEntities);
|
setAccumulatedEntities(newEntities);
|
||||||
// Устанавливаем visibleEntities сразу, не дожидаясь проверки цен
|
// Устанавливаем visibleEntities сразу, только если не идет изменение фильтров
|
||||||
setVisibleEntities(newEntities);
|
if (!isFilterChanging) {
|
||||||
console.log('✅ Установлены visibleEntities для первой страницы:', newEntities.length);
|
setVisibleEntities(newEntities);
|
||||||
|
console.log('✅ Установлены visibleEntities для первой страницы:', newEntities.length);
|
||||||
|
} else {
|
||||||
|
console.log('🔄 Пропускаем установку visibleEntities - фильтры изменяются');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Добавляем к накопленным товарам
|
// Добавляем к накопленным товарам
|
||||||
setAccumulatedEntities(prev => [...prev, ...newEntities]);
|
setAccumulatedEntities(prev => [...prev, ...newEntities]);
|
||||||
@ -246,7 +288,7 @@ export default function Catalog() {
|
|||||||
|
|
||||||
console.log('✅ Пагинация обновлена:', { currentPage, hasNext, hasPrev });
|
console.log('✅ Пагинация обновлена:', { currentPage, hasNext, hasPrev });
|
||||||
}
|
}
|
||||||
}, [entitiesData]);
|
}, [entitiesData, isFilterChanging]);
|
||||||
|
|
||||||
// Преобразование выбранных фильтров в формат PartsIndex API
|
// Преобразование выбранных фильтров в формат PartsIndex API
|
||||||
const convertFiltersToPartsIndexParams = useMemo((): Record<string, any> => {
|
const convertFiltersToPartsIndexParams = useMemo((): Record<string, any> => {
|
||||||
@ -444,13 +486,20 @@ export default function Catalog() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Если фильтры изменяются, не обновляем отображение старых данных
|
||||||
|
if (isFilterChanging) {
|
||||||
|
console.log('🔄 Пропускаем обновление entitiesWithOffers - фильтры изменяются');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Все товары уже отфильтрованы на сервере - показываем все накопленные
|
// Все товары уже отфильтрованы на сервере - показываем все накопленные
|
||||||
const entitiesWithOffers = accumulatedEntities;
|
const entitiesWithOffers = accumulatedEntities;
|
||||||
|
|
||||||
console.log('📊 Обновляем entitiesWithOffers (серверная фильтрация):', {
|
console.log('📊 Обновляем entitiesWithOffers (серверная фильтрация):', {
|
||||||
накопленоТоваров: accumulatedEntities.length,
|
накопленоТоваров: accumulatedEntities.length,
|
||||||
отображаемыхТоваров: entitiesWithOffers.length,
|
отображаемыхТоваров: entitiesWithOffers.length,
|
||||||
целевоеКоличество: ITEMS_PER_PAGE
|
целевоеКоличество: ITEMS_PER_PAGE,
|
||||||
|
isFilterChanging
|
||||||
});
|
});
|
||||||
|
|
||||||
setEntitiesWithOffers(entitiesWithOffers);
|
setEntitiesWithOffers(entitiesWithOffers);
|
||||||
@ -470,7 +519,7 @@ export default function Catalog() {
|
|||||||
|
|
||||||
setVisibleEntities(visibleForCurrentPage);
|
setVisibleEntities(visibleForCurrentPage);
|
||||||
|
|
||||||
}, [isPartsIndexMode, accumulatedEntities, currentUserPage]);
|
}, [isPartsIndexMode, accumulatedEntities, currentUserPage, isFilterChanging]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -559,27 +608,94 @@ export default function Catalog() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Функция для обновления URL с фильтрами
|
||||||
|
const updateUrlWithFilters = useCallback((filters: {[key: string]: string[]}, search: string) => {
|
||||||
|
const query: any = { ...router.query };
|
||||||
|
|
||||||
|
// Удаляем старые фильтры из URL
|
||||||
|
Object.keys(query).forEach(key => {
|
||||||
|
if (key.startsWith('filter_') || key === 'q') {
|
||||||
|
delete query[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем новые фильтры
|
||||||
|
Object.entries(filters).forEach(([filterName, values]) => {
|
||||||
|
if (values.length > 0) {
|
||||||
|
query[`filter_${filterName}`] = values.length === 1 ? values[0] : values;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем поисковый запрос
|
||||||
|
if (search.trim()) {
|
||||||
|
query.q = search;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем URL без перезагрузки страницы
|
||||||
|
router.push({
|
||||||
|
pathname: router.pathname,
|
||||||
|
query
|
||||||
|
}, undefined, { shallow: true });
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
const handleDesktopFilterChange = (filterTitle: string, value: string | string[]) => {
|
const handleDesktopFilterChange = (filterTitle: string, value: string | string[]) => {
|
||||||
setSelectedFilters(prev => ({
|
setSelectedFilters(prev => {
|
||||||
...prev,
|
const newFilters = { ...prev };
|
||||||
[filterTitle]: Array.isArray(value) ? value : [value]
|
|
||||||
}));
|
// Если значение пустое (пустой массив или пустая строка), удаляем фильтр
|
||||||
|
if (Array.isArray(value) && value.length === 0) {
|
||||||
|
delete newFilters[filterTitle];
|
||||||
|
} else if (!value || (typeof value === 'string' && value.trim() === '')) {
|
||||||
|
delete newFilters[filterTitle];
|
||||||
|
} else {
|
||||||
|
// Иначе устанавливаем значение
|
||||||
|
newFilters[filterTitle] = Array.isArray(value) ? value : [value];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем URL
|
||||||
|
updateUrlWithFilters(newFilters, searchQuery);
|
||||||
|
|
||||||
|
return newFilters;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMobileFilterChange = (type: string, value: any) => {
|
const handleMobileFilterChange = (type: string, value: any) => {
|
||||||
setSelectedFilters(prev => ({
|
setSelectedFilters(prev => {
|
||||||
...prev,
|
const newFilters = { ...prev };
|
||||||
[type]: Array.isArray(value) ? value : [value]
|
|
||||||
}));
|
// Если значение пустое (пустой массив или пустая строка), удаляем фильтр
|
||||||
|
if (Array.isArray(value) && value.length === 0) {
|
||||||
|
delete newFilters[type];
|
||||||
|
} else if (!value || (typeof value === 'string' && value.trim() === '')) {
|
||||||
|
delete newFilters[type];
|
||||||
|
} else {
|
||||||
|
// Иначе устанавливаем значение
|
||||||
|
newFilters[type] = Array.isArray(value) ? value : [value];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем URL
|
||||||
|
updateUrlWithFilters(newFilters, searchQuery);
|
||||||
|
|
||||||
|
return newFilters;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Обработчик изменения поискового запроса
|
||||||
|
const handleSearchChange = useCallback((value: string) => {
|
||||||
|
setSearchQuery(value);
|
||||||
|
updateUrlWithFilters(selectedFilters, value);
|
||||||
|
}, [selectedFilters, updateUrlWithFilters]);
|
||||||
|
|
||||||
// Функция для сброса всех фильтров
|
// Функция для сброса всех фильтров
|
||||||
const handleResetFilters = useCallback(() => {
|
const handleResetFilters = useCallback(() => {
|
||||||
setSearchQuery('');
|
setSearchQuery('');
|
||||||
setSelectedFilters({});
|
setSelectedFilters({});
|
||||||
setShowAllBrands(false);
|
setShowAllBrands(false);
|
||||||
setPartsIndexPage(1); // Сбрасываем страницу PartsIndex на первую
|
setPartsIndexPage(1); // Сбрасываем страницу PartsIndex на первую
|
||||||
}, []);
|
|
||||||
|
// Очищаем URL от фильтров
|
||||||
|
updateUrlWithFilters({}, '');
|
||||||
|
}, [updateUrlWithFilters]);
|
||||||
|
|
||||||
// Фильтрация по поиску и фильтрам для PartsAPI
|
// Фильтрация по поиску и фильтрам для PartsAPI
|
||||||
const filteredArticles = useMemo(() => {
|
const filteredArticles = useMemo(() => {
|
||||||
@ -636,6 +752,10 @@ export default function Catalog() {
|
|||||||
// Если изменился поисковый запрос или фильтры, нужно перезагрузить данные с сервера
|
// Если изменился поисковый запрос или фильтры, нужно перезагрузить данные с сервера
|
||||||
if (searchQuery.trim() || Object.keys(selectedFilters).length > 0) {
|
if (searchQuery.trim() || Object.keys(selectedFilters).length > 0) {
|
||||||
console.log('🔍 Поисковый запрос или фильтры изменились, сбрасываем пагинацию');
|
console.log('🔍 Поисковый запрос или фильтры изменились, сбрасываем пагинацию');
|
||||||
|
|
||||||
|
// Устанавливаем флаг изменения фильтров
|
||||||
|
setIsFilterChanging(true);
|
||||||
|
|
||||||
setPartsIndexPage(1);
|
setPartsIndexPage(1);
|
||||||
setCurrentUserPage(1);
|
setCurrentUserPage(1);
|
||||||
setHasMoreEntities(true);
|
setHasMoreEntities(true);
|
||||||
@ -643,10 +763,36 @@ export default function Catalog() {
|
|||||||
setEntitiesWithOffers([]);
|
setEntitiesWithOffers([]);
|
||||||
setEntitiesCache(new Map());
|
setEntitiesCache(new Map());
|
||||||
|
|
||||||
// Перезагружаем данные с новыми параметрами фильтрации
|
// Вычисляем параметры фильтрации прямо здесь, чтобы избежать зависимости от useMemo
|
||||||
const apiParams = convertFiltersToPartsIndexParams;
|
let apiParams: Record<string, any> = {};
|
||||||
|
if (paramsData?.partsIndexCatalogParams?.list && Object.keys(selectedFilters).length > 0) {
|
||||||
|
paramsData.partsIndexCatalogParams.list.forEach((param: any) => {
|
||||||
|
const selectedValues = selectedFilters[param.name];
|
||||||
|
if (selectedValues && selectedValues.length > 0) {
|
||||||
|
// Находим соответствующие значения из API данных
|
||||||
|
const matchingValues = param.values.filter((value: any) =>
|
||||||
|
selectedValues.includes(value.title || value.value)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (matchingValues.length > 0) {
|
||||||
|
// Используем ID параметра из API и значения
|
||||||
|
apiParams[param.id] = matchingValues.map((v: any) => v.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const paramsString = Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
|
const paramsString = Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
|
||||||
|
|
||||||
|
console.log('🔄 Запуск refetch с новыми фильтрами:', {
|
||||||
|
searchQuery,
|
||||||
|
selectedFilters,
|
||||||
|
apiParams,
|
||||||
|
paramsString,
|
||||||
|
catalogId,
|
||||||
|
groupId
|
||||||
|
});
|
||||||
|
|
||||||
// Также обновляем параметры фильтрации
|
// Также обновляем параметры фильтрации
|
||||||
refetchParams({
|
refetchParams({
|
||||||
catalogId: catalogId as string,
|
catalogId: catalogId as string,
|
||||||
@ -654,6 +800,10 @@ export default function Catalog() {
|
|||||||
lang: 'ru',
|
lang: 'ru',
|
||||||
q: searchQuery || undefined,
|
q: searchQuery || undefined,
|
||||||
params: paramsString
|
params: paramsString
|
||||||
|
}).then(result => {
|
||||||
|
console.log('✅ refetchParams результат:', result);
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('❌ refetchParams ошибка:', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
refetchEntities({
|
refetchEntities({
|
||||||
@ -664,11 +814,20 @@ export default function Catalog() {
|
|||||||
page: 1,
|
page: 1,
|
||||||
q: searchQuery || undefined,
|
q: searchQuery || undefined,
|
||||||
params: paramsString
|
params: paramsString
|
||||||
|
}).then(result => {
|
||||||
|
console.log('✅ refetchEntities результат:', result.data?.partsIndexCatalogEntities?.list?.length || 0, 'товаров');
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('❌ refetchEntities ошибка:', error);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Если нет активных фильтров, сбрасываем флаг
|
||||||
|
if (isFilterChanging) {
|
||||||
|
setIsFilterChanging(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isPartsIndexMode, searchQuery, JSON.stringify(selectedFilters), refetchEntities, refetchParams, convertFiltersToPartsIndexParams]);
|
}, [isPartsIndexMode, searchQuery, JSON.stringify(selectedFilters), paramsData]);
|
||||||
|
|
||||||
// Управляем показом пустого состояния с задержкой
|
// Управляем показом пустого состояния с задержкой
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -854,7 +1013,7 @@ export default function Catalog() {
|
|||||||
onFilterChange={handleDesktopFilterChange}
|
onFilterChange={handleDesktopFilterChange}
|
||||||
filterValues={selectedFilters}
|
filterValues={selectedFilters}
|
||||||
searchQuery={searchQuery}
|
searchQuery={searchQuery}
|
||||||
onSearchChange={setSearchQuery}
|
onSearchChange={handleSearchChange}
|
||||||
isLoading={filtersGenerating}
|
isLoading={filtersGenerating}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -865,7 +1024,7 @@ export default function Catalog() {
|
|||||||
onFilterChange={handleDesktopFilterChange}
|
onFilterChange={handleDesktopFilterChange}
|
||||||
filterValues={selectedFilters}
|
filterValues={selectedFilters}
|
||||||
searchQuery={searchQuery}
|
searchQuery={searchQuery}
|
||||||
onSearchChange={setSearchQuery}
|
onSearchChange={handleSearchChange}
|
||||||
isLoading={filtersLoading}
|
isLoading={filtersLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -876,7 +1035,7 @@ export default function Catalog() {
|
|||||||
onFilterChange={handleDesktopFilterChange}
|
onFilterChange={handleDesktopFilterChange}
|
||||||
filterValues={selectedFilters}
|
filterValues={selectedFilters}
|
||||||
searchQuery={searchQuery}
|
searchQuery={searchQuery}
|
||||||
onSearchChange={setSearchQuery}
|
onSearchChange={handleSearchChange}
|
||||||
isLoading={filtersLoading}
|
isLoading={filtersLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -886,7 +1045,7 @@ export default function Catalog() {
|
|||||||
onClose={() => setShowFiltersMobile(false)}
|
onClose={() => setShowFiltersMobile(false)}
|
||||||
filters={isPartsAPIMode ? dynamicFilters : catalogFilters}
|
filters={isPartsAPIMode ? dynamicFilters : catalogFilters}
|
||||||
searchQuery={searchQuery}
|
searchQuery={searchQuery}
|
||||||
onSearchChange={setSearchQuery}
|
onSearchChange={handleSearchChange}
|
||||||
filterValues={selectedFilters}
|
filterValues={selectedFilters}
|
||||||
onFilterChange={handleMobileFilterChange}
|
onFilterChange={handleMobileFilterChange}
|
||||||
/>
|
/>
|
||||||
@ -957,12 +1116,21 @@ export default function Catalog() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Показываем индикатор загрузки при изменении фильтров */}
|
||||||
|
{isPartsIndexMode && isFilterChanging && (
|
||||||
|
<div className="flex flex-col items-center justify-center py-12">
|
||||||
|
<LoadingSpinner />
|
||||||
|
<div className="text-gray-500 text-lg mt-4">Применяем фильтры...</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Отображение товаров PartsIndex */}
|
{/* Отображение товаров PartsIndex */}
|
||||||
{isPartsIndexMode && (() => {
|
{isPartsIndexMode && !isFilterChanging && (() => {
|
||||||
console.log('🎯 Проверяем отображение PartsIndex товаров:', {
|
console.log('🎯 Проверяем отображение PartsIndex товаров:', {
|
||||||
isPartsIndexMode,
|
isPartsIndexMode,
|
||||||
visibleEntitiesLength: visibleEntities.length,
|
visibleEntitiesLength: visibleEntities.length,
|
||||||
visibleEntities: visibleEntities.map(e => ({ id: e.id, code: e.code, brand: e.brand.name }))
|
visibleEntities: visibleEntities.map(e => ({ id: e.id, code: e.code, brand: e.brand.name })),
|
||||||
|
isFilterChanging
|
||||||
});
|
});
|
||||||
return visibleEntities.length > 0;
|
return visibleEntities.length > 0;
|
||||||
})() && (
|
})() && (
|
||||||
|
Reference in New Issue
Block a user