|
1 | 1 | <template>
|
2 |
| - <div v-loading="state.loading" class="data-view" id="doc"> |
3 |
| - <ExportDataDialog :visible.sync="exportDataDialogVisible" @submit="onExportSubmit"/> |
4 |
| - <Toolbar :items="iToolBarItems"/> |
| 2 | + <div id="doc" v-loading="state.loading" class="data-view" @contextmenu.prevent="preventDefaultContextMenu"> |
| 3 | + <RightMenu ref="rightMenu" :menus="menus" /> |
| 4 | + <ExportDataDialog :visible.sync="exportDataDialogVisible" @submit="onExportSubmit" /> |
| 5 | + <Toolbar :items="iToolBarItems" /> |
5 | 6 | <AgGridVue
|
6 | 7 | :rowData="rowData"
|
7 | 8 | :columnDefs="colDefs"
|
8 | 9 | class="ag-theme-balham-dark"
|
9 | 10 | style="height: 100%"
|
10 | 11 | :defaultColDef="defaultColDef"
|
11 | 12 | :gridOptions="gridOptions"
|
| 13 | + @cell-context-menu="showContextMenu" |
12 | 14 | />
|
13 | 15 | </div>
|
14 | 16 | </template>
|
15 | 17 |
|
16 | 18 | <script>
|
| 19 | +import store from '@/store' |
17 | 20 | import Toolbar from '@/framework/components/Toolbar/index.vue'
|
18 | 21 | import { Subject } from 'rxjs'
|
19 | 22 | import ExportDataDialog from '@/components/Main/Explore/DataView/ExportDataDialog.vue'
|
20 | 23 | import { AgGridVue } from 'ag-grid-vue'
|
| 24 | +import RightMenu from '@/components/Main/Explore/DataView/RightMenu.vue' |
| 25 | +import { SpecialCharacters, GeneralInsertSQL, GeneralUpdateSQL } from './const' |
21 | 26 |
|
22 | 27 | import 'ag-grid-community/styles/ag-grid.css'
|
23 | 28 | import 'ag-grid-community/styles/ag-theme-balham.css'
|
24 | 29 |
|
25 | 30 | export default {
|
26 | 31 | name: 'DataView',
|
27 |
| - components: { ExportDataDialog, Toolbar, AgGridVue }, |
| 32 | + components: { ExportDataDialog, Toolbar, AgGridVue, RightMenu }, |
28 | 33 | props: {
|
29 | 34 | meta: {
|
30 | 35 | type: Object,
|
@@ -164,7 +169,30 @@ export default {
|
164 | 169 | suppressMovableColumnsHints: true,
|
165 | 170 | suppressSortingHints: true
|
166 | 171 | },
|
167 |
| - init: false |
| 172 | + init: false, |
| 173 | + currentRow: null, |
| 174 | + menus: [ |
| 175 | + { |
| 176 | + name: 'copy', |
| 177 | + title: this.$t('Copy'), |
| 178 | + icon: 'el-icon-document-copy', |
| 179 | + hidden: () => { return !store.getters.profile.canCopy }, |
| 180 | + children: [ |
| 181 | + { |
| 182 | + name: 'copy-insert', |
| 183 | + title: this.$t('InsertStatement'), |
| 184 | + icon: 'el-icon-document-copy', |
| 185 | + callback: () => this.handleCopy('insert') |
| 186 | + }, |
| 187 | + { |
| 188 | + name: 'copy-update', |
| 189 | + title: this.$t('UpdateStatement'), |
| 190 | + icon: 'el-icon-document-copy', |
| 191 | + callback: () => this.handleCopy('update') |
| 192 | + } |
| 193 | + ] |
| 194 | + } |
| 195 | + ] |
168 | 196 | }
|
169 | 197 | },
|
170 | 198 | computed: {
|
@@ -231,9 +259,64 @@ export default {
|
231 | 259 | onExportSubmit(scope) {
|
232 | 260 | this.exportDataDialogVisible = false
|
233 | 261 | this.$emit('action', { action: 'export', data: scope })
|
| 262 | + }, |
| 263 | + showContextMenu(params) { |
| 264 | + this.currentRow = params.data |
| 265 | + this.$refs.rightMenu.show(params.event) |
| 266 | + }, |
| 267 | + preventDefaultContextMenu(event) { |
| 268 | + event.preventDefault() |
| 269 | + }, |
| 270 | + wrap(str, specChar) { |
| 271 | + const result = str ? str.trim() : '' |
| 272 | + return `${specChar}${result}${specChar}` |
| 273 | + }, |
| 274 | + handleCopy(action) { |
| 275 | + let sql = '' |
| 276 | + let fields = '' |
| 277 | + let values = '' |
| 278 | + let updated_attrs = '' |
| 279 | + let conditional_attrs = '' |
| 280 | + let hasPrimary = false |
| 281 | + const dbType = store.getters.profile.dbType |
| 282 | + const { schema, table } = this.meta |
| 283 | + const char = SpecialCharacters[dbType] |
| 284 | + const tableName = `${this.wrap(schema, char)}.${this.wrap(table, char)}` |
| 285 | + const primaryKeys = ['id'] |
| 286 | + for (let i = 0; i < this.colDefs.length; i++) { |
| 287 | + const fieldName = this.colDefs[i].field |
| 288 | + const fieldValue = `'${(this.currentRow[fieldName] || '')}'` |
| 289 | + if (action === 'insert') { |
| 290 | + fields += (i > 0 ? ', ' : '') + this.wrap(fieldName, char) |
| 291 | + values += (i > 0 ? ', ' : '') + `${fieldValue}` |
| 292 | + sql = GeneralInsertSQL |
| 293 | + .replace('{table_name}', tableName) |
| 294 | + .replace('{fields}', fields) |
| 295 | + .replace('{values}', values) |
| 296 | + } else { |
| 297 | + if (primaryKeys.includes(fieldName)) { |
| 298 | + hasPrimary = true |
| 299 | + } else { |
| 300 | + updated_attrs += (i > 0 ? ', ' : '') + `${this.wrap(fieldName, char)} = ${fieldValue}` |
| 301 | + } |
| 302 | + if (hasPrimary) { |
| 303 | + conditional_attrs = `${this.wrap('id', char)} = '${this.currentRow['id']}'` |
| 304 | + } else { |
| 305 | + conditional_attrs = `${updated_attrs} LIMIT 1` |
| 306 | + } |
| 307 | + sql = GeneralUpdateSQL |
| 308 | + .replace('{table_name}', tableName) |
| 309 | + .replace('{updated_attrs}', updated_attrs) |
| 310 | + .replace('{conditional_attrs}', conditional_attrs) |
| 311 | + } |
| 312 | + } |
| 313 | + navigator.clipboard.writeText(sql).then(() => { |
| 314 | + this.$message.success(this.$t('CopySucceeded')) |
| 315 | + }).catch((error) => { |
| 316 | + this.$message.error(`${this.$t('CopyFailed')}: ${error}`) |
| 317 | + }) |
234 | 318 | }
|
235 | 319 | }
|
236 |
| -
|
237 | 320 | }
|
238 | 321 | </script>
|
239 | 322 |
|
|
0 commit comments