fix(admin): drop ML copy-from locale chrome (quick-261006-s0v)
Copy overwrote the active locale with the other locale's often-empty string, so the editor went blank. Keep a single synchronized locale picker. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,12 +15,10 @@ const locales = computed(() => {
|
||||
return codes && codes.length > 0 ? [...codes] : []
|
||||
})
|
||||
const activeLocale = ref(locales.value[0] ?? 'en')
|
||||
const copyFrom = ref('')
|
||||
|
||||
const labelledBy = computed(() => `${props.controlId}-label`)
|
||||
const editorId = computed(() => `${props.controlId}-editor`)
|
||||
const activeText = computed(() => values.value[activeLocale.value] ?? '')
|
||||
const otherLocales = computed(() => locales.value.filter((code) => code !== activeLocale.value))
|
||||
const markdownField = computed(() => ({ ...props.field, type: 'markdown' }))
|
||||
|
||||
function setLocale(locale: string) {
|
||||
@@ -28,9 +26,6 @@ function setLocale(locale: string) {
|
||||
return
|
||||
}
|
||||
activeLocale.value = locale
|
||||
if (!copyFrom.value || copyFrom.value === locale) {
|
||||
copyFrom.value = otherLocales.value[0] ?? ''
|
||||
}
|
||||
}
|
||||
|
||||
function onLocaleInput(event: Event) {
|
||||
@@ -43,14 +38,6 @@ function onText(text: string) {
|
||||
emit('update:modelValue', { ...values.value, [activeLocale.value]: text })
|
||||
}
|
||||
|
||||
function copyLocale() {
|
||||
const from = copyFrom.value
|
||||
if (!from || from === activeLocale.value) {
|
||||
return
|
||||
}
|
||||
emit('update:modelValue', { ...values.value, [activeLocale.value]: values.value[from] ?? '' })
|
||||
}
|
||||
|
||||
function onBroadcast(event: Event) {
|
||||
const locale = (event as CustomEvent<string>).detail
|
||||
if (typeof locale === 'string' && locale !== '') {
|
||||
@@ -60,7 +47,6 @@ function onBroadcast(event: Event) {
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener(ML_LOCALE_CHANGE, onBroadcast)
|
||||
copyFrom.value = otherLocales.value[0] ?? ''
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener(ML_LOCALE_CHANGE, onBroadcast)
|
||||
@@ -79,25 +65,6 @@ onUnmounted(() => {
|
||||
>
|
||||
<option v-for="code in locales" :key="code" :value="code">{{ code }}</option>
|
||||
</select>
|
||||
<select
|
||||
v-if="otherLocales.length > 0"
|
||||
data-ml-copy-from
|
||||
class="rounded-control border border-border-strong bg-surface px-2 py-1 text-[13px]"
|
||||
:value="copyFrom"
|
||||
aria-label="Copy from locale"
|
||||
@change="copyFrom = ($event.target as HTMLSelectElement).value"
|
||||
>
|
||||
<option v-for="code in otherLocales" :key="code" :value="code">{{ code }}</option>
|
||||
</select>
|
||||
<button
|
||||
v-if="otherLocales.length > 0"
|
||||
type="button"
|
||||
data-ml-copy
|
||||
class="rounded-pager px-2 py-1 text-[13px] text-muted hover:bg-hover hover:text-text"
|
||||
@click="copyLocale"
|
||||
>
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
<MarkdownField
|
||||
:field="markdownField"
|
||||
|
||||
@@ -15,21 +15,16 @@ const locales = computed(() => {
|
||||
return codes && codes.length > 0 ? [...codes] : []
|
||||
})
|
||||
const activeLocale = ref(locales.value[0] ?? 'en')
|
||||
const copyFrom = ref('')
|
||||
|
||||
const labelledBy = computed(() => `${props.controlId}-label`)
|
||||
const editorId = computed(() => `${props.controlId}-editor`)
|
||||
const activeText = computed(() => values.value[activeLocale.value] ?? '')
|
||||
const otherLocales = computed(() => locales.value.filter((code) => code !== activeLocale.value))
|
||||
|
||||
function setLocale(locale: string) {
|
||||
if (!locale) {
|
||||
return
|
||||
}
|
||||
activeLocale.value = locale
|
||||
if (!copyFrom.value || copyFrom.value === locale) {
|
||||
copyFrom.value = otherLocales.value[0] ?? ''
|
||||
}
|
||||
}
|
||||
|
||||
function onLocaleInput(event: Event) {
|
||||
@@ -42,14 +37,6 @@ function onText(text: string) {
|
||||
emit('update:modelValue', { ...values.value, [activeLocale.value]: text })
|
||||
}
|
||||
|
||||
function copyLocale() {
|
||||
const from = copyFrom.value
|
||||
if (!from || from === activeLocale.value) {
|
||||
return
|
||||
}
|
||||
emit('update:modelValue', { ...values.value, [activeLocale.value]: values.value[from] ?? '' })
|
||||
}
|
||||
|
||||
function onBroadcast(event: Event) {
|
||||
const locale = (event as CustomEvent<string>).detail
|
||||
if (typeof locale === 'string' && locale !== '') {
|
||||
@@ -59,7 +46,6 @@ function onBroadcast(event: Event) {
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener(ML_LOCALE_CHANGE, onBroadcast)
|
||||
copyFrom.value = otherLocales.value[0] ?? ''
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener(ML_LOCALE_CHANGE, onBroadcast)
|
||||
@@ -78,25 +64,6 @@ onUnmounted(() => {
|
||||
>
|
||||
<option v-for="code in locales" :key="code" :value="code">{{ code }}</option>
|
||||
</select>
|
||||
<select
|
||||
v-if="otherLocales.length > 0"
|
||||
data-ml-copy-from
|
||||
class="rounded-control border border-border-strong bg-surface px-2 py-1 text-[13px]"
|
||||
:value="copyFrom"
|
||||
aria-label="Copy from locale"
|
||||
@change="copyFrom = ($event.target as HTMLSelectElement).value"
|
||||
>
|
||||
<option v-for="code in otherLocales" :key="code" :value="code">{{ code }}</option>
|
||||
</select>
|
||||
<button
|
||||
v-if="otherLocales.length > 0"
|
||||
type="button"
|
||||
data-ml-copy
|
||||
class="rounded-pager px-2 py-1 text-[13px] text-muted hover:bg-hover hover:text-text"
|
||||
@click="copyLocale"
|
||||
>
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
<TextField
|
||||
:field="{ ...field, type: 'text' }"
|
||||
|
||||
@@ -86,11 +86,15 @@ describe('ML field registry and nested save body', () => {
|
||||
})
|
||||
expect(title.findAll('[data-ml-locale]')).toHaveLength(1)
|
||||
expect(body.findAll('[data-ml-locale]')).toHaveLength(1)
|
||||
expect(title.find('[data-ml-copy-from]').exists()).toBe(false)
|
||||
expect(body.find('[data-ml-copy-from]').exists()).toBe(false)
|
||||
expect(title.find('[data-ml-copy]').exists()).toBe(false)
|
||||
expect(body.find('[data-ml-copy]').exists()).toBe(false)
|
||||
expect(title.findAll('[data-ml-locale] option').map((node) => node.text())).toEqual(['en', 'pl'])
|
||||
expect(body.findAll('[data-ml-locale] option').map((node) => node.text())).toEqual(['en', 'pl'])
|
||||
})
|
||||
|
||||
it('edits the active locale and copies from another', async () => {
|
||||
it('edits the active locale without overwriting sibling locales', async () => {
|
||||
const wrapper = mlMount(MLTextField, {
|
||||
field: field('mltext'),
|
||||
modelValue: { en: 'Hello', pl: 'Witaj' },
|
||||
@@ -100,9 +104,8 @@ describe('ML field registry and nested save body', () => {
|
||||
expect(input.element.value).toBe('Hello')
|
||||
await wrapper.find('[data-ml-locale]').setValue('pl')
|
||||
expect(wrapper.find('input').element.value).toBe('Witaj')
|
||||
await wrapper.find('[data-ml-copy-from]').setValue('en')
|
||||
await wrapper.find('[data-ml-copy]').trigger('click')
|
||||
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([{ en: 'Hello', pl: 'Hello' }])
|
||||
await wrapper.find('input').setValue('Cześć')
|
||||
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([{ en: 'Hello', pl: 'Cześć' }])
|
||||
})
|
||||
|
||||
it('switches every ML control from one selector', async () => {
|
||||
|
||||
Reference in New Issue
Block a user