Skip to content

Commit

Permalink
Add copy and paste row functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
gudaoxuri committed Nov 30, 2023
1 parent 21b4ab4 commit 63dacee
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 25 deletions.
3 changes: 2 additions & 1 deletion components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare module 'vue' {
ColumnRename: typeof import('./src/components/layout/list/ColumnRename.vue')['default']
ColumnResize: typeof import('./src/components/layout/list/ColumnResize.vue')['default']
ColumnSort: typeof import('./src/components/layout/list/ColumnSort.vue')['default']
copy: typeof import('./src/components/layout/list/RowDelete copy.vue')['default']
copy: typeof import('./src/components/layout/list/RowAdd copy.vue')['default']
Filter: typeof import('./src/components/function/Filter.vue')['default']
Group: typeof import('./src/components/function/Group.vue')['default']
Header: typeof import('./src/components/layout/list/Header.vue')['default']
Expand All @@ -31,6 +31,7 @@ declare module 'vue' {
Menu: typeof import('./src/components/common/Menu.vue')['default']
Resize: typeof import('./src/components/function/Resize.vue')['default']
RowAdd: typeof import('./src/components/layout/list/RowAdd.vue')['default']
RowCopyPaste: typeof import('./src/components/layout/list/RowCopyPaste.vue')['default']
RowDelete: typeof import('./src/components/layout/list/RowDelete.vue')['default']
Rows: typeof import('./src/components/layout/list/Rows.vue')['default']
RowSelect: typeof import('./src/components/layout/list/RowSelect.vue')['default']
Expand Down
24 changes: 20 additions & 4 deletions docs/TableDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,32 @@ const events = {
return d
})))
}
else if (Object.values(data[0]).length === 1) {
// Copy
resp2.forEach((resp) => {
const storageRecords = resp.records.filter(record => data.find(d => d.no === record.no))
if (storageRecords.length > 0) {
let newRecords = JSON.parse(JSON.stringify(storageRecords))
newRecords = newRecords
.map((record) => {
record.no = getRandomInt(1000, 2000)
return record
})
resolve(attachDict(newRecords))
}
})
}
else {
// Update
resp2.forEach((resp) => {
let storageRecord = resp.records.find(record => record.no === data[0].no)
const storageRecord = resp.records.find(record => record.no === data[0].no)
if (storageRecord) {
storageRecord = {
...storageRecord,
let newRecords = JSON.parse(JSON.stringify(storageRecord))
newRecords = {
...newRecords,
...data[0],
}
resolve(attachDict([storageRecord]))
resolve(attachDict([newRecords]))
}
})
}
Expand Down
1 change: 1 addition & 0 deletions src/assets/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const RENAME = 'octicon-stack-24'
export const SIZE = 'octicon-typography-24'
export const LOCK = 'octicon-lock-24'
export const COPY = 'octicon-copy-24'
export const PASTE = 'octicon-paste-24'
export const SORT = 'octicon-sort-desc-24'
export const FILTER = 'octicon-filter-24'
export const CHEVRON_DOWN = 'octicon-chevron-down-24'
Expand Down
9 changes: 7 additions & 2 deletions src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"title": "Fixed"
},
"rowDelete": {
"title": "Delete"
"title": "Delete row(s)"
},
"cellWrap": {
"title": "Break words"
Expand Down Expand Up @@ -123,6 +123,11 @@
},
"rowAdd": {
"new": "New row"
},
"rowCopyPaste": {
"copyTitle": "Copy row(s)",
"pasteTitle": "Paste row(s)",
"copyAndPasteTitle": "Copy and Paste row(s)"
}
}
}
}
7 changes: 6 additions & 1 deletion src/assets/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"title": "固定列"
},
"rowDelete": {
"title": "删除"
"title": "删除行"
},
"cellWrap": {
"title": "换行"
Expand Down Expand Up @@ -123,6 +123,11 @@
},
"rowAdd": {
"new": "新增行"
},
"rowCopyPaste": {
"copyTitle": "复制行",
"pasteTitle": "粘贴行",
"copyAndPasteTitle": "复制并粘贴行"
}
}
}
45 changes: 33 additions & 12 deletions src/components/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,13 @@ export async function loadData(layoutId?: string, moreForGroupedValue?: any) {
}
}

export const FUN_ADD_DATA_TYPE = Symbol('FUN_ADD_DATA_TYPE') as InjectionKey<(newRecords: { [key: string]: any }[], afterPkId?: number, groupValue?: any, reFilter?: boolean, reSort?: boolean, reLoad?: boolean) => Promise<boolean>>
export async function addData(newRecords: { [key: string]: any }[], afterPkId?: number, groupValue?: any, reFilter?: boolean, reSort?: boolean, reLoad?: boolean): Promise<boolean> {
export const FUN_ADD_DATA_TYPE = Symbol('FUN_ADD_DATA_TYPE') as InjectionKey<(newRecords: { [key: string]: any }[], afterPk?: any, groupValue?: any, reFilter?: boolean, reSort?: boolean, reLoad?: boolean) => Promise<boolean>>
export async function addData(newRecords: { [key: string]: any }[], afterPk?: any, groupValue?: any, reFilter?: boolean, reSort?: boolean, reLoad?: boolean): Promise<boolean> {
const layout = tableLayoutsConf.find(layout => layout.id === currentLayoutId.value)!

if (Array.isArray(layout.data) && afterPk === undefined && groupValue === undefined)
return false

if (!events.saveData)
return false

Expand All @@ -102,22 +106,39 @@ export async function addData(newRecords: { [key: string]: any }[], afterPkId?:
return true
}

let data
if (groupValue && Array.isArray(layout.data)) {
data = layout.data.find(d => d.groupValue === groupValue)
if (Array.isArray(layout.data)) {
if (groupValue) {
const data = layout.data.find(d => d.groupValue === groupValue)!
if (afterPk !== undefined) {
const idx = data.records.findIndex(r => r[tableBasicConf.pkColumnName] === afterPk)
data.records.splice(idx + 1, 0, ...savedRecords)
}
else {
data.records.splice(data.records.length, 0, ...savedRecords)
}
}
else {
layout.data.forEach((groupData) => {
if (afterPk !== undefined) {
const idx = groupData.records.findIndex(r => r[tableBasicConf.pkColumnName] === afterPk)
if (idx !== -1)
groupData.records.splice(idx + 1, 0, ...savedRecords)
}
})
}
}
else if (layout.data && !Array.isArray(layout.data)) {
data = layout.data
if (afterPk !== undefined) {
const idx = layout.data.records.findIndex(r => r[tableBasicConf.pkColumnName] === afterPk)
layout.data.records.splice(idx + 1, 0, ...savedRecords)
}
else {
layout.data.records.splice(layout.data.records.length, 0, ...savedRecords)
}
}
else {
// Empty,unreachable
}
if (data) {
if (afterPkId)
data.records.splice(afterPkId, 0, ...savedRecords)
else
data.records.splice(data.records.length, 0, ...savedRecords)
}
return true
// TODO agg清空,重新计算
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/layout/list/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ColumnAggsComp from './ColumnAggs.vue'
import { setFixedColumnStyles } from './ColumnFixed.vue'
import HeaderComp from './Header.vue'
import RowAddComp from './RowAdd.vue'
import RowCopyPasteComp from './RowCopyPaste.vue'
import RowDeleteComp from './RowDelete.vue'
import RowSelectComp from './RowSelect.vue'
import RowsComp from './Rows.vue'
Expand Down Expand Up @@ -116,8 +117,9 @@ function setTableWidth() {
:selected-cell-info="selectedCellWrap.cellSelectedInfo"
/>
</div>
<MenuComp ref="rowMenuCompRef">
<RowDeleteComp v-if="selectedDataPks.length > 0" :selected-pks="selectedDataPks" />
<MenuComp v-if="selectedDataPks.length > 0" ref="rowMenuCompRef">
<RowCopyPasteComp :selected-pks="selectedDataPks" :pk-column-name="listConf.basic.pkColumnName" />
<RowDeleteComp :selected-pks="selectedDataPks" />
</MenuComp>
<RowSelectComp
:selected-pks="selectedDataPks" :pk-column-name="listConf.basic.pkColumnName"
Expand Down
51 changes: 51 additions & 0 deletions src/components/layout/list/RowCopyPaste.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup lang="ts">
import { inject, ref } from 'vue';
import * as iconSvg from '../../../assets/icon';
import { FUN_CLOSE_CONTEXT_MENU_TYPE } from '../../common/Menu.vue';
import { FUN_ADD_DATA_TYPE } from '../../events';
const props = defineProps<{
pkColumnName: string
selectedPks: string[] | number[]
}>()
const addDataFun = inject(FUN_ADD_DATA_TYPE)!
const closeContextMenuFun = inject(FUN_CLOSE_CONTEXT_MENU_TYPE)!
const copiedPks = ref<string[] | number[]>([])
async function copyAndPasteRow() {
await addDataFun(props.selectedPks.slice().map((pk) => {
return {
[props.pkColumnName]: pk,
}
}), props.selectedPks[props.selectedPks.length - 1])
closeContextMenuFun()
}
function copyRow() {
copiedPks.value = props.selectedPks.slice()
closeContextMenuFun()
}
async function pasteRow() {
await addDataFun(copiedPks.value.slice().map((pk) => {
return {
[props.pkColumnName]: pk,
}
}), props.selectedPks[props.selectedPks.length - 1])
closeContextMenuFun()
}
</script>

<template>
<div class="iw-contextmenu__item cursor-pointer text-sm" @click="copyAndPasteRow">
<i :class="iconSvg.COPY" /> {{ $t('list.rowCopyPaste.copyAndPasteTitle') }}
</div>
<div class="iw-contextmenu__item cursor-pointer text-sm" @click="copyRow">
<i :class="iconSvg.COPY" /> {{ $t('list.rowCopyPaste.copyTitle') }}
</div>
<div v-if="copiedPks.length > 0" class="iw-contextmenu__item cursor-pointer text-sm" @click="pasteRow">
<i :class="iconSvg.PASTE" /> {{ $t('list.rowCopyPaste.pasteTitle') }}
</div>
</template>
6 changes: 3 additions & 3 deletions src/components/layout/list/RowDelete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ const props = defineProps<{
const deleteDataFun = inject(FUN_DELETE_DATA_TYPE)!
const closeContextMenuFun = inject(FUN_CLOSE_CONTEXT_MENU_TYPE)!
function deleteData() {
async function deleteRow() {
await deleteDataFun(props.selectedPks)
closeContextMenuFun()
deleteDataFun(props.selectedPks)
}
</script>

<template>
<div class="iw-contextmenu__item cursor-pointer text-sm" @click="deleteData">
<div class="iw-contextmenu__item cursor-pointer text-sm" @click="deleteRow">
<i :class="iconSvg.DELETE" /> {{ $t('list.rowDelete.title') }}
</div>
</template>

0 comments on commit 63dacee

Please sign in to comment.