-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create editable table to create batch queries
- Loading branch information
Showing
4 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<template> | ||
<div class="d-flex"> | ||
<div v-if="!isEditing" class="editable-row mx-3" @click="startEditing"> | ||
<i v-if="showPlaceholder">{{ placeholder }}</i> | ||
<span v-else>{{ cellValue }}</span> | ||
</div> | ||
<b-form-input | ||
v-else | ||
ref="inputRef" | ||
v-model="cellValue" | ||
class="editable-row" | ||
type="text" | ||
@focus="$event.target.select()" | ||
@focusout.prevent="stopEditing" | ||
@keypressed.enter="stopEditing" | ||
@keyup.esc="stopEditing" | ||
/> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { nextTick, useTemplateRef, computed, watch } from 'vue' | ||
const cellValue = defineModel({ | ||
type: String, | ||
default: '' | ||
}) | ||
const isEditing = defineModel('focused', { | ||
type: Boolean, | ||
default: false | ||
}) | ||
defineProps({ | ||
placeholder: { | ||
type: String, | ||
default: 'Enter your query here' | ||
} | ||
}) | ||
const inputRef = useTemplateRef('inputRef') | ||
watch( | ||
isEditing, | ||
async (value) => { | ||
if (value) { | ||
await nextTick() | ||
inputRef.value?.focus() | ||
} | ||
}, | ||
{ immediate: true } | ||
) | ||
const showPlaceholder = computed(() => { | ||
return cellValue.value.length === 0 | ||
}) | ||
const startEditing = async () => { | ||
isEditing.value = true | ||
} | ||
const stopEditing = () => { | ||
isEditing.value = false | ||
} | ||
</script> | ||
<style scoped> | ||
div { | ||
cursor: pointer; | ||
} | ||
.editable-row { | ||
display: flex; | ||
align-items: center; | ||
cursor: pointer; | ||
height: 40px; | ||
width: 100%; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<template> | ||
<div class="table-editable"> | ||
<b-table-simple small> | ||
<thead> | ||
<tr> | ||
<th>#</th> | ||
<th><span class="mx-3">Query</span></th> | ||
<th></th> | ||
</tr> | ||
</thead> | ||
|
||
<b-tbody class="overflow-y-auto h-auto"> | ||
<b-tr v-for="(item, index) in items" :key="index" class=""> | ||
<b-td class="table-editable__index text">{{ index + 1 }}</b-td> | ||
<b-td> | ||
<row-editable | ||
v-model:focused="item.focused" | ||
:model-value="item.name" | ||
@keyup.up="focusPreviousItem(index)" | ||
@keyup.down="focusNextItem(index)" | ||
@update:model-value="updateCellValue(index, $event)" | ||
@keydown.enter="onEnter($event, index)" | ||
@keydown.tab.exact="addItem(index)" | ||
@focusout.prevent="addItem(index)" | ||
/> | ||
</b-td> | ||
<b-td class="table-editable__action"> | ||
<button-icon | ||
v-if="item.name?.length > 0" | ||
icon-left="trash" | ||
variant="outline-secondary" | ||
square | ||
hide-label | ||
size="sm" | ||
@click="removeItem(index)" | ||
@keydown.tab.exact.prevent="focusNextItem(index)" | ||
@keydown.enter.prevent="removeItem(index)" | ||
@keydown.tab.shift.exact.prevent="focusCurrentItem(index)" | ||
/> | ||
</b-td> | ||
</b-tr> | ||
</b-tbody> | ||
</b-table-simple> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { reactive } from 'vue' | ||
import RowEditable from './RowEditable.vue' | ||
import ButtonIcon from '@/components/Button/ButtonIcon' | ||
const items = defineModel('items', { | ||
type: Array, | ||
default: () => reactive([{ name: '', focused: false }]) | ||
}) | ||
defineProps({ | ||
maxHeight: { | ||
type: Number, | ||
default: 150 | ||
} | ||
}) | ||
function onEnter(_, index) { | ||
if (!items.value[index].name) { | ||
return | ||
} | ||
addItem(index) | ||
focusNextItem(index) | ||
} | ||
function focusPreviousItem(index) { | ||
if (items.value.length === index || index < 1) { | ||
return | ||
} | ||
items.value[index - 1].focused = true | ||
} | ||
function focusNextItem(index) { | ||
if (items.value.length - 1 === index) { | ||
return | ||
} | ||
items.value[index + 1].focused = true | ||
} | ||
function focusCurrentItem(index) { | ||
items.value[index].focused = true | ||
} | ||
const addItem = (index) => { | ||
if (index === items.value.length - 1 && items.value[index]?.name.length) { | ||
items.value.push({ name: '' }) | ||
} | ||
} | ||
const removeItem = (index) => { | ||
items.value.splice(index, 1) | ||
} | ||
function updateCellValue(index, val) { | ||
items.value[index].name = val | ||
} | ||
</script> | ||
<style scoped lang="scss"> | ||
.table-editable { | ||
&__index, | ||
&__action { | ||
width: 50px; | ||
vertical-align: middle; | ||
} | ||
} | ||
</style> |
18 changes: 18 additions & 0 deletions
18
src/stories/components/TableEditable/RowEditable.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import RowEditable from '@/components/TableEditable/RowEditable.vue'; | ||
|
||
export default { | ||
title: 'Components/TableEditable/RowEditable', | ||
component: RowEditable, | ||
tags: ['autodocs'], | ||
args: { | ||
modelValue: '' | ||
} | ||
}; | ||
|
||
|
||
export const Default = {}; | ||
|
||
export const WithValue = { | ||
args: {modelValue:'tutu'} | ||
} | ||
|
17 changes: 17 additions & 0 deletions
17
src/stories/components/TableEditable/TableEditable.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import TableEditable from '@/components/TableEditable/TableEditable.vue'; | ||
|
||
export default { | ||
title: 'Components/TableEditable/TableEditable', | ||
component: TableEditable, | ||
tags: ['autodocs'], | ||
args: { | ||
} | ||
}; | ||
|
||
|
||
export const Default = {}; | ||
|
||
export const WithValues = { | ||
args: { items: [{name:'tutu'},{name:'toto'},{name:'titi'}] } | ||
} | ||
|