fix: test case table ux
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<div class="text-xs text-ink-gray-5 mb-2">
|
<div class="text-xs text-ink-gray-5 mb-2">
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-x-auto border rounded-md">
|
<div class="overflow-x-auto overflow-y-visible border rounded-md">
|
||||||
<div
|
<div
|
||||||
class="grid items-center space-x-4 p-2 border-b"
|
class="grid items-center space-x-4 p-2 border-b"
|
||||||
:style="{ gridTemplateColumns: getGridTemplateColumns() }"
|
:style="{ gridTemplateColumns: getGridTemplateColumns() }"
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<input
|
<input
|
||||||
v-if="showKey(key)"
|
v-if="showKey(key)"
|
||||||
v-model="row[key]"
|
v-model="row[key]"
|
||||||
class="py-1.5 px-2 border-none focus:ring-0 focus:border focus:border-gray-300 focus:bg-surface-gray-2 rounded-sm text-sm focus:outline-none"
|
class="py-1.5 px-2 border-none focus:ring-0 focus:border focus:border-gray-300 focus:bg-surface-gray-2 rounded-md text-sm focus:outline-none"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -43,20 +43,27 @@
|
|||||||
</template>
|
</template>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div
|
<Teleport to="body">
|
||||||
v-if="menuOpenIndex === rowIndex"
|
<div
|
||||||
class="absolute right-[30px] top-5 mt-1 w-32 bg-surface-white border border-outline-gray-1 rounded-md shadow-sm"
|
v-if="menuOpenIndex === rowIndex"
|
||||||
>
|
:style="{
|
||||||
<button
|
position: 'absolute',
|
||||||
@click="deleteRow(rowIndex)"
|
top: menuTopPosition,
|
||||||
class="flex items-center space-x-2 w-full text-left px-3 py-2 text-sm text-ink-red-3"
|
left: menuLeftPosition,
|
||||||
|
}"
|
||||||
|
class="top-5 mt-1 w-32 bg-surface-white border border-outline-gray-1 rounded-md shadow-sm"
|
||||||
>
|
>
|
||||||
<Trash2 class="size-4 stroke-1.5" />
|
<button
|
||||||
<span>
|
@click="deleteRow(rowIndex)"
|
||||||
{{ __('Delete') }}
|
class="flex items-center space-x-2 w-full text-left px-3 py-2 text-sm text-ink-red-3"
|
||||||
</span>
|
>
|
||||||
</button>
|
<Trash2 class="size-4 stroke-1.5" />
|
||||||
</div>
|
<span>
|
||||||
|
{{ __('Delete') }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,17 +80,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { nextTick, ref, watch } from 'vue'
|
||||||
import { Button } from 'frappe-ui'
|
import { Button } from 'frappe-ui'
|
||||||
import { Ellipsis, Plus, Trash2 } from 'lucide-vue-next'
|
import { Ellipsis, Plus, Trash2 } from 'lucide-vue-next'
|
||||||
import { onClickOutside } from '@vueuse/core'
|
import { onClickOutside } from '@vueuse/core'
|
||||||
|
|
||||||
const rows = defineModel<Cell[][]>()
|
const rows = defineModel<Record<string, string>[]>()
|
||||||
const menuRef = ref(null)
|
const menuRef = ref(null)
|
||||||
const menuOpenIndex = ref<number | null>(null)
|
const menuOpenIndex = ref<number | null>(null)
|
||||||
const menuTopPosition = ref<string>('')
|
const menuTopPosition = ref<string>('')
|
||||||
|
const menuLeftPosition = ref('0px')
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: Cell[][]): void
|
(e: 'update:modelValue', value: Record<string, string>[]): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
type Cell = {
|
type Cell = {
|
||||||
@@ -93,19 +102,19 @@ type Cell = {
|
|||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
modelValue?: Cell[][]
|
modelValue?: Record<string, string>[]
|
||||||
columns?: string[]
|
columns?: string[]
|
||||||
label?: string
|
label?: string
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
columns: [],
|
columns: () => [] as string[],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const columns = ref(props.columns)
|
const columns = ref(props.columns)
|
||||||
|
|
||||||
watch(rows, () => {
|
watch(rows, () => {
|
||||||
if (rows.value?.length < 1) {
|
if (rows.value && rows.value.length < 1) {
|
||||||
addRow()
|
addRow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -119,12 +128,25 @@ const addRow = () => {
|
|||||||
newRow[column.toLowerCase().split(' ').join('_')] = ''
|
newRow[column.toLowerCase().split(' ').join('_')] = ''
|
||||||
})
|
})
|
||||||
rows.value.push(newRow)
|
rows.value.push(newRow)
|
||||||
|
focusNewRowInput()
|
||||||
emit('update:modelValue', rows.value)
|
emit('update:modelValue', rows.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const focusNewRowInput = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
const rowElements = document.querySelectorAll('.overflow-x-auto .grid')[
|
||||||
|
rows.value!.length
|
||||||
|
]
|
||||||
|
const firstInput = rowElements.querySelector('input')
|
||||||
|
if (firstInput) {
|
||||||
|
;(firstInput as HTMLInputElement).focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const deleteRow = (index: number) => {
|
const deleteRow = (index: number) => {
|
||||||
rows.value.splice(index, 1)
|
rows.value?.splice(index, 1)
|
||||||
emit('update:modelValue', rows.value)
|
emit('update:modelValue', rows.value ?? [])
|
||||||
}
|
}
|
||||||
|
|
||||||
const getGridTemplateColumns = () => {
|
const getGridTemplateColumns = () => {
|
||||||
@@ -132,8 +154,10 @@ const getGridTemplateColumns = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toggleMenu = (index: number, event: MouseEvent) => {
|
const toggleMenu = (index: number, event: MouseEvent) => {
|
||||||
menuOpenIndex.value = menuOpenIndex.value === index ? null : index
|
const rect = (event.target as HTMLElement).getBoundingClientRect()
|
||||||
menuTopPosition.value = `${event.clientY + 10}px`
|
menuOpenIndex.value = index
|
||||||
|
menuTopPosition.value = rect.bottom + 'px'
|
||||||
|
menuLeftPosition.value = rect.right + 'px'
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickOutside(menuRef, () => {
|
onClickOutside(menuRef, () => {
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ function submitEvaluation(close) {
|
|||||||
close()
|
close()
|
||||||
},
|
},
|
||||||
onError(err) {
|
onError(err) {
|
||||||
toast.warning(__(err.messages?.[0] || err))
|
console.log(err.messages?.[0] || err)
|
||||||
|
toast.warning(__(err.messages?.[0] || err), { duration: 10000 })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user