diff --git a/src/di/container.tsx b/src/di/container.tsx index 77580bb66..659641450 100644 --- a/src/di/container.tsx +++ b/src/di/container.tsx @@ -84,15 +84,15 @@ import { } from '~/modules/profile/application/profile' import { createRecentFoodCrud } from '~/modules/recent-food/application/usecases/recentFoodCrud' import { createRecentFoodRepository } from '~/modules/recent-food/infrastructure/recentFoodRepository' +import { + createTemplateSearchState, + type TemplateSearchState, +} from '~/modules/search/application/store/templateSearchState' import { type CachedSearchCrud, createCachedSearchCrud, } from '~/modules/search/application/usecases/cachedSearchCrud' import { createCachedSearchRepository } from '~/modules/search/infrastructure/cachedSearchRepository' -import { - createTemplateSearchState, - type TemplateSearchState, -} from '~/modules/template-search/application/usecases/templateSearchState' import { createUserUseCases, type UserUseCases, diff --git a/src/modules/diet/food/application/usecases/foodCrud.ts b/src/modules/diet/food/application/usecases/foodCrud.ts index d0631580d..8f4b114bf 100644 --- a/src/modules/diet/food/application/usecases/foodCrud.ts +++ b/src/modules/diet/food/application/usecases/foodCrud.ts @@ -1,6 +1,8 @@ import { type Food } from '~/modules/diet/food/domain/food' -import { type FoodSearchParams } from '~/modules/diet/food/domain/foodRepository' -import { type FoodRepository } from '~/modules/diet/food/domain/foodRepository' +import { + type FoodRepository, + type FoodSearchParams, +} from '~/modules/diet/food/domain/foodRepository' import { createApiFoodImportService } from '~/modules/diet/food/infrastructure/api/application/apiFood' import { type CachedSearchCrud } from '~/modules/search/application/usecases/cachedSearchCrud' import { showPromise } from '~/modules/toast/application/toastManager' @@ -109,7 +111,4 @@ export function createFoodCrud(deps: { } } -/** - * Convenience type for the concrete use-cases returned by the factory. - */ export type FoodCrud = ReturnType diff --git a/src/modules/diet/food/infrastructure/api/application/apiFood.ts b/src/modules/diet/food/infrastructure/api/application/apiFood.ts index d42550bc9..4f3947564 100644 --- a/src/modules/diet/food/infrastructure/api/application/apiFood.ts +++ b/src/modules/diet/food/infrastructure/api/application/apiFood.ts @@ -64,11 +64,10 @@ export function createApiFoodImportService(deps: { logging.debug(`Found ${apiFoods.length} foods`) - const foodsToupsert = apiFoods.map(convertApi2Food) - - const upsertPromises = foodsToupsert.map(foodRepository.upsertFood) - + const foodsToUpsert = apiFoods.map(convertApi2Food) + const upsertPromises = foodsToUpsert.map(foodRepository.upsertFood) const upsertionResults = await Promise.allSettled(upsertPromises) + logging.debug( `upserted ${upsertionResults.length} foods. ${ upsertionResults.filter((result) => result.status === 'fulfilled') diff --git a/src/modules/recent-food/application/store/recentFoodStore.ts b/src/modules/recent-food/application/store/recentFoodStore.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/modules/search/application/store/cachedSearchCacheStore.ts b/src/modules/search/application/store/cachedSearchCacheStore.ts new file mode 100644 index 000000000..7d296700b --- /dev/null +++ b/src/modules/search/application/store/cachedSearchCacheStore.ts @@ -0,0 +1,52 @@ +import { createSignal } from 'solid-js' + +import { type CachedSearch } from '~/modules/search/domain/cachedSearch' +import { logging } from '~/shared/utils/logging' + +export function createCachedSearchCacheStore() { + const [cachedSearches, setCachedSearches] = createSignal< + readonly CachedSearch[] + >([]) + + return { + // Upsert to cache (from realtime events) + upsertToCache: (cachedSearch: CachedSearch) => { + const current = cachedSearches() + const existingIndex = current.findIndex( + (search) => search.search === cachedSearch.search, + ) + + if (existingIndex >= 0) { + // Update existing + const updated = [...current] + updated[existingIndex] = cachedSearch + setCachedSearches(updated) + logging.debug('Updated cached search in cache:', { cachedSearch }) + } else { + // Add new + setCachedSearches([cachedSearch, ...current]) + logging.debug('Added new cached search to cache:', { cachedSearch }) + } + }, + + // Remove from cache (from realtime events) + removeFromCache: (selector: { + by: 'search' + value: CachedSearch['search'] + }) => { + const current = cachedSearches() + const searchToRemove = current.find( + (search) => search.search === selector.value, + ) + + if (searchToRemove) { + const updated = current.filter( + (search) => search.search !== selector.value, + ) + setCachedSearches(updated) + + logging.debug('Removed cached search from cache:', { searchToRemove }) + } + }, + } +} diff --git a/src/modules/template-search/application/usecases/templateSearchState.ts b/src/modules/search/application/store/templateSearchState.ts similarity index 92% rename from src/modules/template-search/application/usecases/templateSearchState.ts rename to src/modules/search/application/store/templateSearchState.ts index c59878e7a..ad12f9106 100644 --- a/src/modules/template-search/application/usecases/templateSearchState.ts +++ b/src/modules/search/application/store/templateSearchState.ts @@ -3,8 +3,8 @@ import { createResource, createRoot, createSignal } from 'solid-js' import { type FoodCrud } from '~/modules/diet/food/application/usecases/foodCrud' import { type RecipeCrud } from '~/modules/diet/recipe/application/usecases/recipeCrud' import { type RecentFoodCrud } from '~/modules/recent-food/application/usecases/recentFoodCrud' -import { fetchTemplatesByTabLogic } from '~/modules/template-search/application/templateSearchLogic' -import { type TemplateSearchTab } from '~/sections/search/components/TemplateSearchTabs' +import { fetchTemplatesByTabLogic } from '~/modules/search/application/usecases/templateSearchLogic' +import { type TemplateSearchTab } from '~/modules/search/ui/TemplateSearchTabs' import { createDebouncedSignal } from '~/shared/utils/createDebouncedSignal' export function createTemplateSearchState(deps: { diff --git a/src/modules/search/application/usecases/cachedSearchCrud.ts b/src/modules/search/application/usecases/cachedSearchCrud.ts index e5913e77d..61c54503d 100644 --- a/src/modules/search/application/usecases/cachedSearchCrud.ts +++ b/src/modules/search/application/usecases/cachedSearchCrud.ts @@ -1,5 +1,13 @@ import { type CachedSearchRepository } from '~/modules/search/domain/searchRepository' +export function createCachedSearchCrudUseCases( + cachedSearchRepository: CachedSearchRepository, +) { + return createCachedSearchCrud({ + repository: cachedSearchRepository, + }) +} + /** * Factory that creates cached-search CRUD use-cases. * @@ -14,32 +22,14 @@ export function createCachedSearchCrud(deps: { }) { const repository = deps.repository - /** - * Checks whether a given search query result is already cached. - * - * @param query The search query to check. - * @returns A promise resolving to `true` if cached, otherwise `false`. - */ async function isSearchCached(query: string): Promise { return await repository.isSearchCached(query) } - /** - * Marks the given search query as cached. - * - * @param query The search query to mark as cached. - * @returns A promise that resolves when the operation completes. - */ async function markSearchAsCached(query: string): Promise { await repository.markSearchAsCached(query) } - /** - * Removes the cached mark for the given search query. - * - * @param query The search query to unmark. - * @returns A promise that resolves when the operation completes. - */ async function unmarkSearchAsCached(query: string): Promise { await repository.unmarkSearchAsCached(query) } @@ -51,7 +41,4 @@ export function createCachedSearchCrud(deps: { } } -/** - * Type for DI/testing consumers. - */ export type CachedSearchCrud = ReturnType diff --git a/src/modules/search/application/usecases/searchUseCases.ts b/src/modules/search/application/usecases/searchUseCases.ts new file mode 100644 index 000000000..453c539d0 --- /dev/null +++ b/src/modules/search/application/usecases/searchUseCases.ts @@ -0,0 +1,65 @@ +import { createRoot } from 'solid-js' + +import { createCachedSearchCacheStore } from '~/modules/search/application/store/cachedSearchCacheStore' +import { createCachedSearchCrudUseCases } from '~/modules/search/application/usecases/cachedSearchCrud' +import { cachedSearchSchema } from '~/modules/search/domain/cachedSearch' +import { createCachedSearchRepository } from '~/modules/search/infrastructure/cachedSearchRepository' +import { initializeCachedSearchRealtime } from '~/modules/search/infrastructure/supabase/realtime' +import { parseWithStack } from '~/shared/utils/parseWithStack' + +const { cachedSearchCacheStore, cachedSearchCrudUseCases } = createRoot(() => { + const cachedSearchCacheStore = createCachedSearchCacheStore() + const cachedSearchRepository = createCachedSearchRepository() + const cachedSearchCrudUseCases = createCachedSearchCrudUseCases( + cachedSearchRepository, + ) + + initializeCachedSearchRealtime({ + onInsert: (newRecord) => { + cachedSearchCacheStore.upsertToCache(newRecord) + }, + onUpdate: (newRecord) => { + cachedSearchCacheStore.upsertToCache(newRecord) + }, + onDelete: (oldRecord) => { + cachedSearchCacheStore.removeFromCache({ + by: 'search', + value: oldRecord.search, + }) + }, + }) + + return { cachedSearchCacheStore, cachedSearchCrudUseCases } +}) + +export const searchUseCases = { + isSearchCached: async (query: string): Promise => { + const result = await cachedSearchCrudUseCases.isSearchCached(query) + if (result) { + cachedSearchCacheStore.upsertToCache( + parseWithStack(cachedSearchSchema, { search: query }), + ) + } else { + cachedSearchCacheStore.removeFromCache({ + by: 'search', + value: query, + }) + } + return result + }, + markSearchAsCached: async (query: string): Promise => { + await cachedSearchCrudUseCases.markSearchAsCached(query) + cachedSearchCacheStore.upsertToCache( + parseWithStack(cachedSearchSchema, { + search: query, + }), + ) + }, + unmarkSearchAsCached: async (query: string): Promise => { + await cachedSearchCrudUseCases.unmarkSearchAsCached(query) + cachedSearchCacheStore.removeFromCache({ + by: 'search', + value: query, + }) + }, +} diff --git a/src/modules/template-search/application/templateSearchLogic.ts b/src/modules/search/application/usecases/templateSearchLogic.ts similarity index 97% rename from src/modules/template-search/application/templateSearchLogic.ts rename to src/modules/search/application/usecases/templateSearchLogic.ts index 5e23dc15b..794faa44e 100644 --- a/src/modules/template-search/application/templateSearchLogic.ts +++ b/src/modules/search/application/usecases/templateSearchLogic.ts @@ -5,8 +5,8 @@ import type { Food } from '~/modules/diet/food/domain/food' import type { FoodSearchParams } from '~/modules/diet/food/domain/foodRepository' import type { Recipe } from '~/modules/diet/recipe/domain/recipe' import type { Template } from '~/modules/diet/template/domain/template' +import { availableTabs } from '~/modules/search/ui/TemplateSearchTabs' import { type User } from '~/modules/user/domain/user' -import { availableTabs } from '~/sections/search/components/TemplateSearchTabs' /** * Dependencies for fetchTemplatesByTabLogic diff --git a/src/modules/template-search/application/tests/templateSearchLogic.test.ts b/src/modules/search/application/usecases/tests/templateSearchLogic.test.ts similarity index 97% rename from src/modules/template-search/application/tests/templateSearchLogic.test.ts rename to src/modules/search/application/usecases/tests/templateSearchLogic.test.ts index 78532ab1c..8d09bd3bf 100644 --- a/src/modules/template-search/application/tests/templateSearchLogic.test.ts +++ b/src/modules/search/application/usecases/tests/templateSearchLogic.test.ts @@ -12,8 +12,8 @@ import { import { fetchTemplatesByTabLogic, type FetchTemplatesDeps, -} from '~/modules/template-search/application/templateSearchLogic' -import { availableTabs } from '~/sections/search/components/TemplateSearchTabs' +} from '~/modules/search/application/usecases/templateSearchLogic' +import { availableTabs } from '~/modules/search/ui/TemplateSearchTabs' describe('fetchTemplatesByTabLogic', () => { const mockFood = promoteNewFoodToFood( diff --git a/src/modules/search/infrastructure/supabase/realtime.ts b/src/modules/search/infrastructure/supabase/realtime.ts new file mode 100644 index 000000000..475f47ebc --- /dev/null +++ b/src/modules/search/infrastructure/supabase/realtime.ts @@ -0,0 +1,52 @@ +import { + type CachedSearch, + cachedSearchSchema, +} from '~/modules/search/domain/cachedSearch' +import { registerSubapabaseRealtimeCallback } from '~/shared/supabase/supabase' +import { logging } from '~/shared/utils/logging' + +const SUPABASE_TABLE_CACHED_SEARCHES = 'cached_searches' + +let initialized = false + +export function initializeCachedSearchRealtime(callbacks: { + onInsert: (newRecord: CachedSearch) => void + onUpdate: (newRecord: CachedSearch) => void + onDelete: (oldRecord: CachedSearch) => void +}): void { + if (initialized) { + return + } + logging.debug(`Cached search realtime initialized!`) + initialized = true + registerSubapabaseRealtimeCallback( + SUPABASE_TABLE_CACHED_SEARCHES, + cachedSearchSchema, + (event) => { + logging.debug(`Event:`, event) + + switch (event.eventType) { + case 'INSERT': { + if (event.new !== undefined) { + callbacks.onInsert(event.new) + } + break + } + + case 'UPDATE': { + if (event.new) { + callbacks.onUpdate(event.new) + } + break + } + + case 'DELETE': { + if (event.old) { + callbacks.onDelete(event.old) + } + break + } + } + }, + ) +} diff --git a/src/modules/template-search/infrastructure/templateSearchTabPreference.ts b/src/modules/search/infrastructure/templateSearchTabPreference.ts similarity index 97% rename from src/modules/template-search/infrastructure/templateSearchTabPreference.ts rename to src/modules/search/infrastructure/templateSearchTabPreference.ts index 31c5e92ad..778e236c9 100644 --- a/src/modules/template-search/infrastructure/templateSearchTabPreference.ts +++ b/src/modules/search/infrastructure/templateSearchTabPreference.ts @@ -8,7 +8,7 @@ import { availableTabs, type TemplateSearchTab, -} from '~/sections/search/components/TemplateSearchTabs' +} from '~/modules/search/ui/TemplateSearchTabs' const STORAGE_KEY = 'macroflows:template-search-tab' diff --git a/src/modules/template-search/infrastructure/tests/templateSearchTabPreference.test.ts b/src/modules/search/infrastructure/tests/templateSearchTabPreference.test.ts similarity index 78% rename from src/modules/template-search/infrastructure/tests/templateSearchTabPreference.test.ts rename to src/modules/search/infrastructure/tests/templateSearchTabPreference.test.ts index 3774a2b40..adf842824 100644 --- a/src/modules/template-search/infrastructure/tests/templateSearchTabPreference.test.ts +++ b/src/modules/search/infrastructure/tests/templateSearchTabPreference.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { availableTabs } from '~/sections/search/components/TemplateSearchTabs' +import { availableTabs } from '~/modules/search/ui/TemplateSearchTabs' let localStorageMock: Record = {} @@ -32,7 +32,7 @@ describe('templateSearchTabPreference', () => { describe('loadTabPreference', () => { it('returns default tab when localStorage is empty', async () => { const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() expect(tabPreference.loadTabPreference()).toBe(availableTabs.Todos.id) @@ -44,7 +44,7 @@ describe('templateSearchTabPreference', () => { vi.resetModules() const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() expect(tabPreference.loadTabPreference()).toBe(availableTabs.Favoritos.id) @@ -56,7 +56,7 @@ describe('templateSearchTabPreference', () => { vi.resetModules() const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() expect(tabPreference.loadTabPreference()).toBe(availableTabs.Recentes.id) @@ -68,7 +68,7 @@ describe('templateSearchTabPreference', () => { vi.resetModules() const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() expect(tabPreference.loadTabPreference()).toBe(availableTabs.Receitas.id) @@ -80,7 +80,7 @@ describe('templateSearchTabPreference', () => { vi.resetModules() const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() expect(tabPreference.loadTabPreference()).toBe(availableTabs.Todos.id) @@ -90,7 +90,7 @@ describe('templateSearchTabPreference', () => { describe('saveTabPreference', () => { it('saves tab preference to localStorage', async () => { const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() tabPreference.saveTabPreference(availableTabs.Favoritos.id) @@ -100,7 +100,7 @@ describe('templateSearchTabPreference', () => { it('does not persist hidden tab state', async () => { const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() tabPreference.saveTabPreference('hidden') @@ -114,7 +114,7 @@ describe('templateSearchTabPreference', () => { vi.resetModules() const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() tabPreference.saveTabPreference(availableTabs.Recentes.id) @@ -126,19 +126,16 @@ describe('templateSearchTabPreference', () => { describe('round-trip persistence', () => { it('can save and load tab preference', async () => { const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() - // Save a preference tabPreference.saveTabPreference(availableTabs.Receitas.id) - // Re-import to get fresh module state vi.resetModules() const freshModule = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const freshTabPreference = freshModule.createTemplateSearchTabPreference() - // Load should return the saved preference expect(freshTabPreference.loadTabPreference()).toBe( availableTabs.Receitas.id, ) @@ -148,7 +145,7 @@ describe('templateSearchTabPreference', () => { describe('createTemplateSearchTabPreference', () => { it('returns load and save methods', async () => { const { createTemplateSearchTabPreference } = - await import('~/modules/template-search/infrastructure/templateSearchTabPreference') + await import('~/modules/search/infrastructure/templateSearchTabPreference') const tabPreference = createTemplateSearchTabPreference() diff --git a/src/sections/search/components/SearchLoadingIndicator.tsx b/src/modules/search/ui/SearchLoadingIndicator.tsx similarity index 100% rename from src/sections/search/components/SearchLoadingIndicator.tsx rename to src/modules/search/ui/SearchLoadingIndicator.tsx diff --git a/src/sections/search/components/TemplateSearchBar.tsx b/src/modules/search/ui/TemplateSearchBar.tsx similarity index 100% rename from src/sections/search/components/TemplateSearchBar.tsx rename to src/modules/search/ui/TemplateSearchBar.tsx diff --git a/src/sections/search/components/TemplateSearchModal.tsx b/src/modules/search/ui/TemplateSearchModal.tsx similarity index 88% rename from src/sections/search/components/TemplateSearchModal.tsx rename to src/modules/search/ui/TemplateSearchModal.tsx index ba3706ac4..0fe06b0cc 100644 --- a/src/sections/search/components/TemplateSearchModal.tsx +++ b/src/modules/search/ui/TemplateSearchModal.tsx @@ -12,7 +12,13 @@ import { import { type Template } from '~/modules/diet/template/domain/template' import { isTemplateRecipe } from '~/modules/diet/template/domain/template' import { type TemplateItem } from '~/modules/diet/template-item/domain/templateItem' -import { createTemplateSearchTabPreference } from '~/modules/template-search/infrastructure/templateSearchTabPreference' +import { createTemplateSearchTabPreference } from '~/modules/search/infrastructure/templateSearchTabPreference' +import { TemplateSearchBar } from '~/modules/search/ui/TemplateSearchBar' +import { TemplateSearchResults } from '~/modules/search/ui/TemplateSearchResults' +import { + type TemplateSearchTab, + TemplateSearchTabs, +} from '~/modules/search/ui/TemplateSearchTabs' import { showError, showSuccess, @@ -21,12 +27,6 @@ import { EANButton } from '~/sections/common/components/EANButton' import { PageLoading } from '~/sections/common/components/PageLoading' import { EANInsertModal } from '~/sections/ean/components/EANInsertModal' import { openItemEditModal } from '~/sections/item/ui/openItemEditModal' -import { TemplateSearchBar } from '~/sections/search/components/TemplateSearchBar' -import { TemplateSearchResults } from '~/sections/search/components/TemplateSearchResults' -import { - type TemplateSearchTab, - TemplateSearchTabs, -} from '~/sections/search/components/TemplateSearchTabs' import { formatError } from '~/shared/formatError' import { closeModal, @@ -65,9 +65,9 @@ export function TemplateSearchModal(props: TemplateSearchModalProps) { title: 'Edit Item', targetName: props.targetName, onApply: (templateItem: TemplateItem) => { - const Item = createItemFromTemplate(template, templateItem) + const item = createItemFromTemplate(template, templateItem) - handleNewItem(Item, templateItem, () => closeModal(modalId)).catch( + handleNewItem(item, templateItem, () => closeModal(modalId)).catch( (err) => { logging.error('TemplateSearchModal handleNewItem error:', err) showError(err, {}, `Erro ao adicionar item: ${formatError(err)}`) @@ -124,14 +124,12 @@ export function TemplateSearchModal(props: TemplateSearchModalProps) { item: originalAddedItem, }) - // Check if any macro nutrient would overflow const isOverflowing = overflowResults['carbs']() || overflowResults['protein']() || overflowResults['fat']() if (isOverflowing) { - // Prompt if user wants to add item even if it overflows const overflowModalId = openConfirmModal( 'Os macros deste item ultrapassam as metas diárias. Deseja adicionar mesmo assim?', { @@ -191,7 +189,7 @@ export function TemplateSearchModal(props: TemplateSearchModalProps) { } return ( -
+
void }) { const templateSearchState = useContainer().templateSearchState() - // TODO: Determine if user is on desktop or mobile to set autofocus const isDesktop = false - // Load persisted tab preference on mount (only once) onMount(() => { const persistedTab = templateSearchTabPreference.loadTabPreference() templateSearchState.setTemplateSearchTab(persistedTab) }) - // Wrapper that persists tab changes to localStorage const handleSetTab = ( tabOrUpdater: | TemplateSearchTab | ((prev: TemplateSearchTab) => TemplateSearchTab), ) => { - // Compute the new value based on whether it's a function or direct value const newTab = typeof tabOrUpdater === 'function' ? tabOrUpdater(templateSearchState.templateSearchTab()) @@ -233,7 +227,7 @@ export function TemplateSearch(props: { return ( <>
-

+

Busca por nome ou código de barras

{ - openContentModal( - () => ( - { - logging.debug('New unified item added') - }} - onFinish={() => {}} - onClose={() => {}} - /> - ), - { - title: 'Buscar alimentos', + openTemplateSearchModal({ + targetName: 'Test Meal', + onNewItem: (newItem) => { + logging.debug('New item from TemplateSearchModal:', newItem) + showSuccess('Item adicionado: ' + newItem.name) }, - ) + title: 'Adicionar item ao Test Meal', + }) }} > Open Template Search Modal diff --git a/src/sections/day-diet/components/DayMeals.tsx b/src/sections/day-diet/components/DayMeals.tsx index e549d99e2..c1ce06dd1 100644 --- a/src/sections/day-diet/components/DayMeals.tsx +++ b/src/sections/day-diet/components/DayMeals.tsx @@ -13,6 +13,7 @@ import { addItemToMeal, updateItemInMeal, } from '~/modules/diet/meal/domain/mealOperations' +import { openTemplateSearchModal } from '~/modules/search/ui/openTemplateSearchModal' import { showError } from '~/modules/toast/application/toastManager' import { CopyLastDayButton } from '~/sections/day-diet/components/CopyLastDayButton' import { DeleteDayButton } from '~/sections/day-diet/components/DeleteDayButton' @@ -23,7 +24,6 @@ import { MealEditViewContent, MealEditViewHeader, } from '~/sections/meal/components/MealEditView' -import { openTemplateSearchModal } from '~/sections/search/ui/openTemplateSearchModal' import { openConfirmModal } from '~/shared/modal/helpers/modalHelpers' import { logging } from '~/shared/utils/logging' @@ -79,6 +79,7 @@ const handleEditItem = ( showAddItemButton: true, }) } + const handleUpdateMeal = async ( dayEditUseCases: DayEditOrchestrator, meal: Meal, diff --git a/src/sections/item/components/ItemView/ItemEdit/ItemEditModal.tsx b/src/sections/item/components/ItemView/ItemEdit/ItemEditModal.tsx index 28aea9810..a576ca4a6 100644 --- a/src/sections/item/components/ItemView/ItemEdit/ItemEditModal.tsx +++ b/src/sections/item/components/ItemView/ItemEdit/ItemEditModal.tsx @@ -24,12 +24,12 @@ import { itemSchema, } from '~/modules/diet/item/schema/itemSchema' import { type Recipe } from '~/modules/diet/recipe/domain/recipe' +import { openTemplateSearchModal } from '~/modules/search/ui/openTemplateSearchModal' import { DownloadIcon } from '~/sections/common/components/icons/DownloadIcon' import { useFloatField } from '~/sections/common/hooks/useField' import { ItemEditBody } from '~/sections/item/components/ItemView/ItemEdit/ItemEditBody' import { openItemEditModal } from '~/sections/item/ui/openItemEditModal' import { openRecipeEditModal } from '~/sections/recipe/ui/openRecipeEditModal' -import { openTemplateSearchModal } from '~/sections/search/ui/openTemplateSearchModal' import { generateId, regenerateId } from '~/shared/utils/idUtils' import { logging } from '~/shared/utils/logging' diff --git a/src/sections/recipe/components/RecipeEditModal.tsx b/src/sections/recipe/components/RecipeEditModal.tsx index 9cbf76d70..d4ef28f2d 100644 --- a/src/sections/recipe/components/RecipeEditModal.tsx +++ b/src/sections/recipe/components/RecipeEditModal.tsx @@ -11,6 +11,7 @@ import { addItemToRecipe, updateItemInRecipe, } from '~/modules/diet/recipe/domain/recipeOperations' +import { openTemplateSearchModal } from '~/modules/search/ui/openTemplateSearchModal' import { showError } from '~/modules/toast/application/toastManager' import { Button } from '~/sections/common/components/buttons/Button' import { openItemEditModal } from '~/sections/item/ui/openItemEditModal' @@ -19,7 +20,6 @@ import { RecipeEditHeader, } from '~/sections/recipe/components/RecipeEditView' import { RecipeEditContextProvider } from '~/sections/recipe/context/RecipeEditContext' -import { openTemplateSearchModal } from '~/sections/search/ui/openTemplateSearchModal' import { openDeleteConfirmModal } from '~/shared/modal/ui/DeleteConfirmModal' import { logging } from '~/shared/utils/logging'