fix(add property): edit ItemsList component to save auto-populated items immediately and invalidate queries after all operations are complete
This commit is contained in:
parent
90abad12b9
commit
f380397f71
1 changed files with 64 additions and 43 deletions
|
@ -44,17 +44,7 @@ async function loadItemsFromDb(url: string): Promise<ItemsResponse> {
|
||||||
const selectedProperties = await propertiesResponse.json();
|
const selectedProperties = await propertiesResponse.json();
|
||||||
console.log('[DEBUG] Successfully received selected properties');
|
console.log('[DEBUG] Successfully received selected properties');
|
||||||
|
|
||||||
// Filter items to only include selected properties
|
return { items, selectedProperties };
|
||||||
const filteredItems = items.map((item: Item) => ({
|
|
||||||
...item,
|
|
||||||
customProperties: Object.fromEntries(
|
|
||||||
Object.entries(item.customProperties).filter(([key]) =>
|
|
||||||
selectedProperties.includes(key)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
|
|
||||||
return { items: filteredItems, selectedProperties };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveItemToDb(url: string, item: Item): Promise<void> {
|
async function saveItemToDb(url: string, item: Item): Promise<void> {
|
||||||
|
@ -444,13 +434,13 @@ export function ItemsList({ url }: ItemsListProps) {
|
||||||
console.log('Property already visible in UI:', normalizedProperty);
|
console.log('Property already visible in UI:', normalizedProperty);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Proceeding to add property:', normalizedProperty);
|
console.log('Proceeding to add property:', normalizedProperty);
|
||||||
|
|
||||||
// FIRST: Add to selected properties and custom properties (optimistic update)
|
// FIRST: Add to selected properties and custom properties (optimistic update)
|
||||||
setSelectedProperties(prev => ({ ...prev, [normalizedProperty]: true }));
|
setSelectedProperties(prev => ({ ...prev, [normalizedProperty]: true }));
|
||||||
setCustomProperties(prev => [...prev, normalizedProperty]);
|
setCustomProperties(prev => [...prev, normalizedProperty]);
|
||||||
|
|
||||||
// SECOND: Fetch label if not exists
|
// SECOND: Fetch label if not exists
|
||||||
if (!propertyLabels[normalizedProperty]) {
|
if (!propertyLabels[normalizedProperty]) {
|
||||||
try {
|
try {
|
||||||
|
@ -460,35 +450,48 @@ export function ItemsList({ url }: ItemsListProps) {
|
||||||
console.error('Error fetching property labels:', error);
|
console.error('Error fetching property labels:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// THIRD: Add to all items with auto-population from propertyCache
|
// THIRD: Add to all items with auto-population from propertyCache AND save immediately
|
||||||
|
const itemsToSave: Item[] = [];
|
||||||
|
|
||||||
setItems(prev => prev.map(item => {
|
setItems(prev => prev.map(item => {
|
||||||
const existingValue = item.customProperties[normalizedProperty] || '';
|
const existingValue = item.customProperties[normalizedProperty] || '';
|
||||||
let autoPopulatedValue = existingValue;
|
let autoPopulatedValue = existingValue;
|
||||||
|
|
||||||
// If item has Wikidata ID and we have cached properties, use the cached value
|
// If item has Wikidata ID and we have cached properties, use the cached value
|
||||||
if (item.wikidataId && propertyCache[item.wikidataId] && propertyCache[item.wikidataId][normalizedProperty]) {
|
if (item.wikidataId && propertyCache[item.wikidataId] && propertyCache[item.wikidataId][normalizedProperty]) {
|
||||||
autoPopulatedValue = propertyCache[item.wikidataId][normalizedProperty];
|
autoPopulatedValue = propertyCache[item.wikidataId][normalizedProperty];
|
||||||
console.log(`Auto-populating ${normalizedProperty} for ${item.wikidataId} with value:`, autoPopulatedValue);
|
console.log(`Auto-populating ${normalizedProperty} for ${item.wikidataId} with value:`, autoPopulatedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const updatedItem = {
|
||||||
...item,
|
...item,
|
||||||
customProperties: {
|
customProperties: {
|
||||||
...item.customProperties,
|
...item.customProperties,
|
||||||
[normalizedProperty]: autoPopulatedValue
|
[normalizedProperty]: autoPopulatedValue
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}));
|
|
||||||
|
|
||||||
// FOURTH: Save to database and refresh data
|
// If we auto-populated a value, save it immediately
|
||||||
|
if (autoPopulatedValue && autoPopulatedValue !== existingValue) {
|
||||||
|
itemsToSave.push(updatedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedItem;
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Save all auto-populated items immediately
|
||||||
|
const cachePopulationPromises = itemsToSave.map(item => saveItemToDb(url, item));
|
||||||
|
|
||||||
|
// FOURTH: Save property to database
|
||||||
try {
|
try {
|
||||||
|
if (cachePopulationPromises.length > 0) {
|
||||||
|
await Promise.all(cachePopulationPromises);
|
||||||
|
console.log('All cache-populated items saved successfully');
|
||||||
|
}
|
||||||
|
|
||||||
await addPropertyToDb(url, normalizedProperty);
|
await addPropertyToDb(url, normalizedProperty);
|
||||||
console.log('Property successfully saved to database:', normalizedProperty);
|
console.log('Property successfully saved to database:', normalizedProperty);
|
||||||
|
|
||||||
// Invalidate queries to refresh data from database
|
|
||||||
queryClient.invalidateQueries({ queryKey: ['items', url] });
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving property to database:', error);
|
console.error('Error saving property to database:', error);
|
||||||
// Revert optimistic updates on error
|
// Revert optimistic updates on error
|
||||||
|
@ -506,10 +509,13 @@ export function ItemsList({ url }: ItemsListProps) {
|
||||||
})));
|
})));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIFTH: Fetch Wikidata properties for items with wikidata_id that don't have cached data
|
// FIFTH: Fetch Wikidata properties for items with wikidata_id that don't have cached data
|
||||||
const itemsWithWikidataId = items.filter(item => item.wikidataId && !propertyCache[item.wikidataId]);
|
const itemsWithWikidataId = items.filter(item => item.wikidataId && !propertyCache[item.wikidataId]);
|
||||||
|
|
||||||
|
// Create array to store all save promises
|
||||||
|
const savePromises: Promise<void>[] = [];
|
||||||
|
|
||||||
for (const item of itemsWithWikidataId) {
|
for (const item of itemsWithWikidataId) {
|
||||||
if (item.wikidataId) {
|
if (item.wikidataId) {
|
||||||
try {
|
try {
|
||||||
|
@ -534,20 +540,22 @@ export function ItemsList({ url }: ItemsListProps) {
|
||||||
: prevItem
|
: prevItem
|
||||||
));
|
));
|
||||||
|
|
||||||
// Save the updated item to database to persist the auto-populated value
|
// Get current items state and save the updated item to database
|
||||||
const updatedItem = items.find(i => i.wikidataId === item.wikidataId);
|
setItems(currentItems => {
|
||||||
if (updatedItem) {
|
const updatedItem = currentItems.find(i => i.wikidataId === item.wikidataId);
|
||||||
const itemToSave = {
|
if (updatedItem) {
|
||||||
...updatedItem,
|
const itemToSave = {
|
||||||
customProperties: {
|
...updatedItem,
|
||||||
...updatedItem.customProperties,
|
customProperties: {
|
||||||
[normalizedProperty]: properties[normalizedProperty]
|
...updatedItem.customProperties,
|
||||||
}
|
[normalizedProperty]: properties[normalizedProperty]
|
||||||
};
|
}
|
||||||
saveItemToDb(url, itemToSave).catch(error => {
|
};
|
||||||
console.error('Error saving auto-populated value:', error);
|
// Add save promise to array instead of awaiting immediately
|
||||||
});
|
savePromises.push(saveItemToDb(url, itemToSave));
|
||||||
}
|
}
|
||||||
|
return currentItems; // Return unchanged state since we already updated it above
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching Wikidata properties for ${item.wikidataId}:`, error);
|
console.error(`Error fetching Wikidata properties for ${item.wikidataId}:`, error);
|
||||||
|
@ -555,8 +563,21 @@ export function ItemsList({ url }: ItemsListProps) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Property addition completed:', normalizedProperty);
|
// WAIT for all saves to complete before invalidating queries
|
||||||
}, [customProperties, propertyLabels, items, propertyCache, url]);
|
if (savePromises.length > 0) {
|
||||||
|
try {
|
||||||
|
await Promise.all(savePromises);
|
||||||
|
console.log('All auto-populated items saved successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error saving some auto-populated items:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIXTH: Only invalidate queries after ALL operations are complete
|
||||||
|
console.log('Property addition completed, refreshing data:', normalizedProperty);
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['items', url] });
|
||||||
|
|
||||||
|
}, [customProperties, propertyLabels, items, propertyCache, url, queryClient, saveItemToDb]);
|
||||||
|
|
||||||
const handleWikidataSelect = useCallback(async (suggestion: WikidataSuggestion, itemId: string) => {
|
const handleWikidataSelect = useCallback(async (suggestion: WikidataSuggestion, itemId: string) => {
|
||||||
console.log('Wikidata selection for item:', itemId, suggestion);
|
console.log('Wikidata selection for item:', itemId, suggestion);
|
||||||
|
|
Loading…
Add table
Reference in a new issue