prices optimised
This commit is contained in:
@ -167,7 +167,49 @@ export default function Catalog() {
|
|||||||
|
|
||||||
const allArticles = articlesData?.partsAPIArticles || [];
|
const allArticles = articlesData?.partsAPIArticles || [];
|
||||||
|
|
||||||
// Загружаем товары PartsIndex
|
// Сначала загружаем параметры фильтрации для PartsIndex
|
||||||
|
const { data: paramsData, loading: paramsLoading, error: paramsError } = useQuery<PartsIndexParamsData, PartsIndexParamsVariables>(
|
||||||
|
GET_PARTSINDEX_CATALOG_PARAMS,
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
catalogId: catalogId as string,
|
||||||
|
groupId: groupId as string,
|
||||||
|
lang: 'ru',
|
||||||
|
q: searchQuery || undefined,
|
||||||
|
params: undefined // Параметры для получения самих фильтров
|
||||||
|
},
|
||||||
|
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
|
||||||
|
fetchPolicy: 'cache-first'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Преобразование выбранных фильтров в строку параметров для GraphQL (стабильное мемоизирование)
|
||||||
|
const apiParamsString = useMemo((): string | undefined => {
|
||||||
|
if (!paramsData?.partsIndexCatalogParams?.list || Object.keys(selectedFilters).length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiParams: Record<string, any> = {};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
|
||||||
|
}, [paramsData, selectedFilters]);
|
||||||
|
|
||||||
|
// Теперь загружаем товары PartsIndex с реактивными переменными (включая фильтры)
|
||||||
const { data: entitiesData, loading: entitiesLoading, error: entitiesError, refetch: refetchEntities } = useQuery<PartsIndexEntitiesData, PartsIndexEntitiesVariables>(
|
const { data: entitiesData, loading: entitiesLoading, error: entitiesError, refetch: refetchEntities } = useQuery<PartsIndexEntitiesData, PartsIndexEntitiesVariables>(
|
||||||
GET_PARTSINDEX_CATALOG_ENTITIES,
|
GET_PARTSINDEX_CATALOG_ENTITIES,
|
||||||
{
|
{
|
||||||
@ -178,29 +220,13 @@ export default function Catalog() {
|
|||||||
limit: PARTSINDEX_PAGE_SIZE,
|
limit: PARTSINDEX_PAGE_SIZE,
|
||||||
page: partsIndexPage,
|
page: partsIndexPage,
|
||||||
q: searchQuery || undefined,
|
q: searchQuery || undefined,
|
||||||
params: undefined // Будем обновлять через refetch
|
params: apiParamsString // ✅ Теперь реактивно отслеживает изменения фильтров
|
||||||
},
|
},
|
||||||
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
|
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
|
||||||
fetchPolicy: 'cache-and-network'
|
fetchPolicy: 'cache-and-network'
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Загружаем параметры фильтрации для PartsIndex
|
|
||||||
const { data: paramsData, loading: paramsLoading, error: paramsError, refetch: refetchParams } = useQuery<PartsIndexParamsData, PartsIndexParamsVariables>(
|
|
||||||
GET_PARTSINDEX_CATALOG_PARAMS,
|
|
||||||
{
|
|
||||||
variables: {
|
|
||||||
catalogId: catalogId as string,
|
|
||||||
groupId: groupId as string,
|
|
||||||
lang: 'ru',
|
|
||||||
q: searchQuery || undefined,
|
|
||||||
params: undefined // Будем обновлять через refetch
|
|
||||||
},
|
|
||||||
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
|
|
||||||
fetchPolicy: 'cache-first'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// allEntities больше не используется - используем allLoadedEntities
|
// allEntities больше не используется - используем allLoadedEntities
|
||||||
|
|
||||||
// Хук для загрузки цен товаров PartsIndex
|
// Хук для загрузки цен товаров PartsIndex
|
||||||
@ -290,32 +316,6 @@ export default function Catalog() {
|
|||||||
}
|
}
|
||||||
}, [entitiesData, isFilterChanging]);
|
}, [entitiesData, isFilterChanging]);
|
||||||
|
|
||||||
// Преобразование выбранных фильтров в формат PartsIndex API
|
|
||||||
const convertFiltersToPartsIndexParams = useMemo((): Record<string, any> => {
|
|
||||||
if (!paramsData?.partsIndexCatalogParams?.list || Object.keys(selectedFilters).length === 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiParams: Record<string, any> = {};
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return apiParams;
|
|
||||||
}, [paramsData, selectedFilters]);
|
|
||||||
|
|
||||||
// Функция автоматической подгрузки дополнительных страниц PartsIndex
|
// Функция автоматической подгрузки дополнительных страниц PartsIndex
|
||||||
const autoLoadMoreEntities = useCallback(async () => {
|
const autoLoadMoreEntities = useCallback(async () => {
|
||||||
if (isAutoLoading || !hasMoreEntities || !isPartsIndexMode) {
|
if (isAutoLoading || !hasMoreEntities || !isPartsIndexMode) {
|
||||||
@ -363,10 +363,10 @@ export default function Catalog() {
|
|||||||
setIsAutoLoading(true);
|
setIsAutoLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('🔄 Автоподгрузка: загружаем следующую страницу PartsIndex...');
|
console.log('🔄 Автоподгрузка: загружаем следующую страницу PartsIndex...');
|
||||||
|
|
||||||
const apiParams = convertFiltersToPartsIndexParams;
|
// Используем уже вычисленную строку параметров
|
||||||
const paramsString = Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
|
const paramsString = apiParamsString;
|
||||||
|
|
||||||
const result = await refetchEntities({
|
const result = await refetchEntities({
|
||||||
catalogId: catalogId as string,
|
catalogId: catalogId as string,
|
||||||
@ -743,91 +743,25 @@ export default function Catalog() {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [isPartsAPIMode, searchQuery, JSON.stringify(selectedFilters), filteredArticles.length]);
|
}, [isPartsAPIMode, searchQuery, JSON.stringify(selectedFilters), filteredArticles.length]);
|
||||||
|
|
||||||
// Обновляем видимые товары при изменении поиска или фильтров для PartsIndex
|
// Простая логика сброса при изменении фильтров - убираем сложные refetch
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isPartsIndexMode) {
|
if (isPartsIndexMode) {
|
||||||
// При изменении поиска или фильтров сбрасываем пагинацию
|
console.log('🔄 Фильтры изменились, сбрасываем локальное состояние');
|
||||||
setShowEmptyState(false);
|
|
||||||
|
|
||||||
// Если изменился поисковый запрос или фильтры, нужно перезагрузить данные с сервера
|
// Сбрасываем локальное состояние при изменении фильтров
|
||||||
if (searchQuery.trim() || Object.keys(selectedFilters).length > 0) {
|
setPartsIndexPage(1);
|
||||||
console.log('🔍 Поисковый запрос или фильтры изменились, сбрасываем пагинацию');
|
setCurrentUserPage(1);
|
||||||
|
setAccumulatedEntities([]);
|
||||||
// Устанавливаем флаг изменения фильтров
|
setEntitiesWithOffers([]);
|
||||||
setIsFilterChanging(true);
|
setVisibleEntities([]);
|
||||||
|
setEntitiesCache(new Map());
|
||||||
setPartsIndexPage(1);
|
setShowEmptyState(false);
|
||||||
setCurrentUserPage(1);
|
setIsFilterChanging(true);
|
||||||
setHasMoreEntities(true);
|
|
||||||
setAccumulatedEntities([]);
|
// Apollo автоматически перезагрузит данные при изменении переменных
|
||||||
setEntitiesWithOffers([]);
|
|
||||||
setEntitiesCache(new Map());
|
|
||||||
|
|
||||||
// Вычисляем параметры фильтрации прямо здесь, чтобы избежать зависимости от useMemo
|
|
||||||
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;
|
|
||||||
|
|
||||||
console.log('🔄 Запуск refetch с новыми фильтрами:', {
|
|
||||||
searchQuery,
|
|
||||||
selectedFilters,
|
|
||||||
apiParams,
|
|
||||||
paramsString,
|
|
||||||
catalogId,
|
|
||||||
groupId
|
|
||||||
});
|
|
||||||
|
|
||||||
// Также обновляем параметры фильтрации
|
|
||||||
refetchParams({
|
|
||||||
catalogId: catalogId as string,
|
|
||||||
groupId: groupId as string,
|
|
||||||
lang: 'ru',
|
|
||||||
q: searchQuery || undefined,
|
|
||||||
params: paramsString
|
|
||||||
}).then(result => {
|
|
||||||
console.log('✅ refetchParams результат:', result);
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('❌ refetchParams ошибка:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
refetchEntities({
|
|
||||||
catalogId: catalogId as string,
|
|
||||||
groupId: groupId as string,
|
|
||||||
lang: 'ru',
|
|
||||||
limit: PARTSINDEX_PAGE_SIZE,
|
|
||||||
page: 1,
|
|
||||||
q: searchQuery || undefined,
|
|
||||||
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), paramsData]);
|
}, [isPartsIndexMode, searchQuery, JSON.stringify(selectedFilters)]);
|
||||||
|
|
||||||
// Управляем показом пустого состояния с задержкой
|
// Управляем показом пустого состояния с задержкой
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
Reference in New Issue
Block a user