diff --git a/backend/src/queries.ts b/backend/src/queries.ts index 675196f..6dd6542 100644 --- a/backend/src/queries.ts +++ b/backend/src/queries.ts @@ -861,6 +861,7 @@ function pokemonProjection(locale: string): string { SELECT p.id, ${pokemonName} AS name, + p.name AS "baseName", ${translationsSelect('pokemon', 'p.id')} AS translations, ${auditSelect('p', 'pokemon_created_user', 'pokemon_updated_user')}, json_build_object('id', e.id, 'name', ${environmentName}) AS environment, @@ -924,7 +925,7 @@ export async function listDailyChecklistItems(locale = defaultLocale) { const title = localizedField('daily-checklist-items', 'c.id', 'c.title', 'title', locale); return query( ` - SELECT c.id, ${title} AS title, ${translationsSelect('daily-checklist-items', 'c.id')} AS translations + SELECT c.id, ${title} AS title, c.title AS "baseTitle", ${translationsSelect('daily-checklist-items', 'c.id')} AS translations FROM daily_checklist_items c ORDER BY c.sort_order, c.id ` @@ -935,7 +936,7 @@ async function getDailyChecklistItemById(id: number, locale = defaultLocale) { const title = localizedField('daily-checklist-items', 'c.id', 'c.title', 'title', locale); return queryOne( ` - SELECT c.id, ${title} AS title, ${translationsSelect('daily-checklist-items', 'c.id')} AS translations + SELECT c.id, ${title} AS title, c.title AS "baseTitle", ${translationsSelect('daily-checklist-items', 'c.id')} AS translations FROM daily_checklist_items c WHERE c.id = $1 `, @@ -1442,7 +1443,7 @@ export async function createPokemon(payload: Record, userId: nu export async function updatePokemon(id: number, payload: Record, userId: number, locale = defaultLocale) { const cleanPayload = cleanPokemonPayload({ ...payload, id }); - const before = await getPokemon(id, locale); + const before = await getPokemon(id, defaultLocale); const updated = await withTransaction(async (client) => { const result = await client.query( @@ -1487,6 +1488,7 @@ export async function listHabitats(locale = defaultLocale) { SELECT h.id, ${habitatName} AS name, + h.name AS "baseName", ${translationsSelect('habitats', 'h.id')} AS translations, ${auditSelect('h', 'habitat_created_user', 'habitat_updated_user')}, COALESCE(( @@ -1521,6 +1523,7 @@ export async function getHabitat(id: number, locale = defaultLocale) { SELECT h.id, ${habitatName} AS name, + h.name AS "baseName", ${translationsSelect('habitats', 'h.id')} AS translations, ${auditSelect('h', 'habitat_created_user', 'habitat_updated_user')}, COALESCE(( @@ -1650,7 +1653,7 @@ export async function createHabitat(payload: Record, userId: nu export async function updateHabitat(id: number, payload: Record, userId: number, locale = defaultLocale) { const cleanPayload = cleanHabitatPayload(payload); - const before = await getHabitat(id, locale); + const before = await getHabitat(id, defaultLocale); const updated = await withTransaction(async (client) => { const result = await client.query( @@ -1692,6 +1695,7 @@ function itemProjection(locale: string): string { SELECT i.id, ${itemName} AS name, + i.name AS "baseName", ${translationsSelect('items', 'i.id')} AS translations, ${auditSelect('i', 'item_created_user', 'item_updated_user')}, json_build_object('id', c.id, 'name', ${categoryName}) AS category, @@ -1980,7 +1984,7 @@ export async function createItem(payload: Record, userId: numbe export async function updateItem(id: number, payload: Record, userId: number, locale = defaultLocale) { const cleanPayload = cleanItemPayload(payload); - const before = await getItem(id, locale); + const before = await getItem(id, defaultLocale); const updated = await withTransaction(async (client) => { await ensureItemCanDisableRecipe(client, id, cleanPayload.noRecipe); @@ -2170,7 +2174,7 @@ export async function createRecipe(payload: Record, userId: num export async function updateRecipe(id: number, payload: Record, userId: number, locale = defaultLocale) { const cleanPayload = cleanRecipePayload(payload); - const before = await getRecipe(id, locale); + const before = await getRecipe(id, defaultLocale); const updated = await withTransaction(async (client) => { await ensureItemCanHaveRecipe(client, cleanPayload.itemId); diff --git a/frontend/src/components/TranslationFields.vue b/frontend/src/components/TranslationFields.vue index 9f7edc1..449df90 100644 --- a/frontend/src/components/TranslationFields.vue +++ b/frontend/src/components/TranslationFields.vue @@ -30,6 +30,10 @@ function fieldValue(language: Language): string { return props.translations[language.code]?.[props.field] ?? ''; } +function fieldPlaceholder(language: Language): string { + return language.code === defaultLanguage.value?.code ? '' : props.baseValue; +} + function updateField(language: Language, value: string) { if (language.code === defaultLanguage.value?.code) { emit('update:baseValue', value); @@ -68,6 +72,7 @@ function inputValue(event: Event): string { diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 9d99d27..1501068 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -56,6 +56,7 @@ export interface EditHistoryEntry { export interface Pokemon extends EditInfo { id: number; name: string; + baseName?: string; translations?: TranslationMap; environment: NamedEntity; skills: Skill[]; @@ -79,6 +80,7 @@ export interface PokemonDetail extends Pokemon { export interface Habitat extends EditInfo { id: number; name: string; + baseName?: string; translations?: TranslationMap; recipe: Array; pokemon?: NamedEntity[]; @@ -113,6 +115,7 @@ export interface HabitatUsage { export interface Item extends EditInfo { id: number; name: string; + baseName?: string; translations?: TranslationMap; category: NamedEntity; usage: NamedEntity | null; @@ -147,6 +150,7 @@ export interface Recipe extends EditInfo { export interface DailyChecklistItem { id: number; title: string; + baseTitle?: string; translations?: TranslationMap; } diff --git a/frontend/src/views/AdminView.vue b/frontend/src/views/AdminView.vue index e31f003..e20b522 100644 --- a/frontend/src/views/AdminView.vue +++ b/frontend/src/views/AdminView.vue @@ -81,7 +81,7 @@ const configNameInput = computed({ return configForm.value.name; } - return configForm.value.translations[currentConfigLocale.value]?.name ?? configForm.value.name; + return configForm.value.translations[currentConfigLocale.value]?.name ?? ''; }, set: (value: string) => { if (isConfigDefaultLocale.value) { @@ -92,6 +92,7 @@ const configNameInput = computed({ updateConfigTranslation(currentConfigLocale.value, value); } }); +const configNamePlaceholder = computed(() => (isConfigDefaultLocale.value ? '' : configForm.value.name)); const activeConfigTab = computed({ get: () => activeConfigType.value, set: (value: string) => { @@ -194,7 +195,7 @@ function closeChecklistModal() { } function editChecklistItem(item: DailyChecklistItem) { - checklistForm.value = { id: item.id, title: item.title, translations: item.translations ?? {} }; + checklistForm.value = { id: item.id, title: item.baseTitle ?? item.title, translations: item.translations ?? {} }; checklistModalOpen.value = true; } @@ -240,7 +241,7 @@ function updateConfigTranslation(localeCode: string, value: string) { } function configBaseNameForSave() { - if (configForm.value.name.trim() !== '' || isConfigDefaultLocale.value) { + if (configForm.value.name.trim() !== '') { return configForm.value.name; } @@ -805,7 +806,7 @@ onMounted(() => {