mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	feat: context menu option to fill cell with random values
This commit is contained in:
		| @@ -29,7 +29,6 @@ export const NUMBER = [ | |||||||
|    'SMALLINT', |    'SMALLINT', | ||||||
|    'MEDIUMINT', |    'MEDIUMINT', | ||||||
|    'BIGINT', |    'BIGINT', | ||||||
|    'DECIMAL', |  | ||||||
|    'NUMERIC', |    'NUMERIC', | ||||||
|    'INTEGER', |    'INTEGER', | ||||||
|    'SMALLSERIAL', |    'SMALLSERIAL', | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ | |||||||
|          @show-delete-modal="showDeleteConfirmModal" |          @show-delete-modal="showDeleteConfirmModal" | ||||||
|          @set-null="setNull" |          @set-null="setNull" | ||||||
|          @copy-cell="copyCell" |          @copy-cell="copyCell" | ||||||
|  |          @fill-cell="fillCell" | ||||||
|          @copy-row="copyRow" |          @copy-row="copyRow" | ||||||
|          @duplicate-row="duplicateRow" |          @duplicate-row="duplicateRow" | ||||||
|          @close-context="closeContext" |          @close-context="closeContext" | ||||||
| @@ -122,7 +123,7 @@ import { useSettingsStore } from '@/stores/settings'; | |||||||
| import { useWorkspacesStore } from '@/stores/workspaces'; | import { useWorkspacesStore } from '@/stores/workspaces'; | ||||||
| import { useConsoleStore } from '@/stores/console'; | import { useConsoleStore } from '@/stores/console'; | ||||||
| import { exportRows } from '../libs/exportRows'; | import { exportRows } from '../libs/exportRows'; | ||||||
| import { TEXT, LONG_TEXT, BLOB } from 'common/fieldTypes'; | import { TEXT, LONG_TEXT, BLOB, DATE, DATETIME, TIME } from 'common/fieldTypes'; | ||||||
| import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue'; | import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue'; | ||||||
| import WorkspaceTabQueryTableRow from '@/components/WorkspaceTabQueryTableRow.vue'; | import WorkspaceTabQueryTableRow from '@/components/WorkspaceTabQueryTableRow.vue'; | ||||||
| import TableContext from '@/components/WorkspaceTabQueryTableContext.vue'; | import TableContext from '@/components/WorkspaceTabQueryTableContext.vue'; | ||||||
| @@ -133,6 +134,7 @@ import { TableField, QueryResult } from 'common/interfaces/antares'; | |||||||
| import { TableUpdateParams } from 'common/interfaces/tableApis'; | import { TableUpdateParams } from 'common/interfaces/tableApis'; | ||||||
| import { jsonToSqlInsert } from 'common/libs/sqlUtils'; | import { jsonToSqlInsert } from 'common/libs/sqlUtils'; | ||||||
| import { unproxify } from '@/libs/unproxify'; | import { unproxify } from '@/libs/unproxify'; | ||||||
|  | import faker from '@faker-js/faker'; | ||||||
|  |  | ||||||
| const { t } = useI18n(); | const { t } = useI18n(); | ||||||
|  |  | ||||||
| @@ -463,6 +465,51 @@ const copyRow = (format: string) => { | |||||||
|    } |    } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const fillCell = (event: { name: string; group: string; type: string }) => { | ||||||
|  |    const row = localResults.value.find((row: any) => selectedRows.value.includes(row._antares_id)); | ||||||
|  |    let fakeValue; | ||||||
|  |    let datePrecision = ''; | ||||||
|  |  | ||||||
|  |    for (let i = 0; i < selectedCell.value.length; i++) | ||||||
|  |       datePrecision += i === 0 ? '.S' : 'S'; | ||||||
|  |  | ||||||
|  |    if (event.group === 'custom') { | ||||||
|  |       if (event.type === 'time' && event.name === 'now') | ||||||
|  |          fakeValue = moment().format(`HH:mm:ss${datePrecision}`); | ||||||
|  |       else if (event.type === 'time' && event.name === 'random') | ||||||
|  |          fakeValue = moment(faker.date.recent()).format(`HH:mm:ss${datePrecision}`); | ||||||
|  |       else if (event.type === 'datetime' && event.name === 'now') | ||||||
|  |          fakeValue = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`); | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       fakeValue = (faker as any)[event.group][event.name](); | ||||||
|  |       if (['string', 'number'].includes(typeof fakeValue)) { | ||||||
|  |          if (typeof fakeValue === 'number') | ||||||
|  |             fakeValue = String(fakeValue); | ||||||
|  |  | ||||||
|  |          if (selectedCell.value.length) | ||||||
|  |             fakeValue = fakeValue.substring(0, selectedCell.value.length); | ||||||
|  |       } | ||||||
|  |       else if ([...DATE, ...DATETIME].includes(selectedCell.value.type)) | ||||||
|  |          fakeValue = moment(fakeValue).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`); | ||||||
|  |       else if (TIME.includes(selectedCell.value.type)) | ||||||
|  |          fakeValue = moment(fakeValue).format(`HH:mm:ss${datePrecision}`); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    const params = { | ||||||
|  |       primary: primaryField.value?.name, | ||||||
|  |       schema: getSchema(resultsetIndex.value), | ||||||
|  |       table: getTable(resultsetIndex.value), | ||||||
|  |       id: getPrimaryValue(row), | ||||||
|  |       row, | ||||||
|  |       orgRow: row, | ||||||
|  |       field: selectedCell.value.field, | ||||||
|  |       content: fakeValue | ||||||
|  |    }; | ||||||
|  |  | ||||||
|  |    emit('update-field', params); | ||||||
|  | }; | ||||||
|  |  | ||||||
| const duplicateRow = () => { | const duplicateRow = () => { | ||||||
|    const row = localResults.value.find((row: any) => selectedRows.value.includes(row._antares_id)); |    const row = localResults.value.find((row: any) => selectedRows.value.includes(row._antares_id)); | ||||||
|    const rowToDuplicate = JSON.parse(JSON.stringify(row)); |    const rowToDuplicate = JSON.parse(JSON.stringify(row)); | ||||||
|   | |||||||
| @@ -43,14 +43,25 @@ | |||||||
|          </span> |          </span> | ||||||
|       </div> |       </div> | ||||||
|       <div |       <div | ||||||
|          v-if="selectedRows.length === 1 && selectedCell.isEditable && mode === 'table'" |          v-if="selectedRows.length === 1 && selectedCell.isEditable && mode === 'table' && fakerGroup" | ||||||
|          class="context-element" |          class="context-element" | ||||||
|          @click="duplicateRow" |  | ||||||
|       > |       > | ||||||
|          <span class="d-flex"> |          <span class="d-flex"> | ||||||
|             <i class="mdi mdi-18px mdi-auto-fix text-light pr-1" /> {{ t('message.fillCell') }} |             <i class="mdi mdi-18px mdi-auto-fix text-light pr-1" /> {{ t('message.fillCell') }} | ||||||
|          </span> |          </span> | ||||||
|          <i class="mdi mdi-18px mdi-chevron-right text-light pl-1" /> |          <i class="mdi mdi-18px mdi-chevron-right text-light pl-1" /> | ||||||
|  |          <div class="context-submenu"> | ||||||
|  |             <div | ||||||
|  |                v-for="method in fakerMethods[fakerGroup]" | ||||||
|  |                :key="method.name" | ||||||
|  |                class="context-element" | ||||||
|  |                @click="fillCell(method)" | ||||||
|  |             > | ||||||
|  |                <span class="d-flex"> | ||||||
|  |                   {{ t(`faker.${method.name}`) }} | ||||||
|  |                </span> | ||||||
|  |             </div> | ||||||
|  |          </div> | ||||||
|       </div> |       </div> | ||||||
|       <div |       <div | ||||||
|          v-if="selectedRows.length === 1 && selectedCell.isEditable" |          v-if="selectedRows.length === 1 && selectedCell.isEditable" | ||||||
| @@ -74,13 +85,14 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { Prop } from 'vue'; | import { computed, Prop } from 'vue'; | ||||||
| import BaseContextMenu from '@/components/BaseContextMenu.vue'; | import BaseContextMenu from '@/components/BaseContextMenu.vue'; | ||||||
| import { useI18n } from 'vue-i18n'; | import { useI18n } from 'vue-i18n'; | ||||||
|  | import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, UUID } from 'common/fieldTypes'; | ||||||
|  |  | ||||||
| const { t } = useI18n(); | const { t } = useI18n(); | ||||||
|  |  | ||||||
| defineProps({ | const props = defineProps({ | ||||||
|    contextEvent: MouseEvent, |    contextEvent: MouseEvent, | ||||||
|    selectedRows: Array, |    selectedRows: Array, | ||||||
|    selectedCell: Object, |    selectedCell: Object, | ||||||
| @@ -93,9 +105,61 @@ const emit = defineEmits([ | |||||||
|    'set-null', |    'set-null', | ||||||
|    'copy-cell', |    'copy-cell', | ||||||
|    'copy-row', |    'copy-row', | ||||||
|    'duplicate-row' |    'duplicate-row', | ||||||
|  |    'fill-cell' | ||||||
| ]); | ]); | ||||||
|  |  | ||||||
|  | const fakerMethods = { | ||||||
|  |    string: [ | ||||||
|  |       { name: 'word', group: 'lorem' }, | ||||||
|  |       { name: 'text', group: 'lorem' }, | ||||||
|  |       { name: 'firstName', group: 'name' }, | ||||||
|  |       { name: 'lastName', group: 'name' }, | ||||||
|  |       { name: 'jobTitle', group: 'name' }, | ||||||
|  |       { name: 'phoneNumber', group: 'phone' }, | ||||||
|  |       { name: 'exampleEmail', group: 'internet' }, | ||||||
|  |       { name: 'ip', group: 'internet' }, | ||||||
|  |       { name: 'domainName', group: 'internet' }, | ||||||
|  |       { name: 'color', group: 'internet' } | ||||||
|  |    ], | ||||||
|  |    number: [ | ||||||
|  |       { name: 'number', group: 'random' } | ||||||
|  |    ], | ||||||
|  |    float: [ | ||||||
|  |       { name: 'float', group: 'random' }, | ||||||
|  |       { name: 'amount', group: 'finance' } | ||||||
|  |    ], | ||||||
|  |    datetime: [ | ||||||
|  |       { name: 'now', group: 'custom' }, | ||||||
|  |       { name: 'past', group: 'date' }, | ||||||
|  |       { name: 'future', group: 'date' } | ||||||
|  |    ], | ||||||
|  |    time: [ | ||||||
|  |       { name: 'now', group: 'custom' }, | ||||||
|  |       { name: 'random', group: 'custom' } | ||||||
|  |    ], | ||||||
|  |    uuid: [ | ||||||
|  |       { name: 'uuid', group: 'random' } | ||||||
|  |    ] | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const fakerGroup = computed(() => { | ||||||
|  |    if ([...TEXT, ...LONG_TEXT].includes(props.selectedCell.type)) | ||||||
|  |       return 'string'; | ||||||
|  |    else if (NUMBER.includes(props.selectedCell.type)) | ||||||
|  |       return 'number'; | ||||||
|  |    else if (FLOAT.includes(props.selectedCell.type)) | ||||||
|  |       return 'float'; | ||||||
|  |    else if ([...DATE, ...DATETIME].includes(props.selectedCell.type)) | ||||||
|  |       return 'datetime'; | ||||||
|  |    else if (TIME.includes(props.selectedCell.type)) | ||||||
|  |       return 'time'; | ||||||
|  |    else if (UUID.includes(props.selectedCell.type)) | ||||||
|  |       return 'uuid'; | ||||||
|  |    else | ||||||
|  |       return false; | ||||||
|  | }); | ||||||
|  |  | ||||||
| const showConfirmModal = () => { | const showConfirmModal = () => { | ||||||
|    emit('show-delete-modal'); |    emit('show-delete-modal'); | ||||||
| }; | }; | ||||||
| @@ -123,4 +187,9 @@ const duplicateRow = () => { | |||||||
|    emit('duplicate-row'); |    emit('duplicate-row'); | ||||||
|    closeContext(); |    closeContext(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const fillCell = (method: {name: string; group: string}) => { | ||||||
|  |    emit('fill-cell', { ...method, type: fakerGroup.value }); | ||||||
|  |    closeContext(); | ||||||
|  | }; | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -11,7 +11,12 @@ | |||||||
|          :class="{selected: selectedCell === cKey}" |          :class="{selected: selectedCell === cKey}" | ||||||
|          @click="selectRow($event, cKey)" |          @click="selectRow($event, cKey)" | ||||||
|  |  | ||||||
|          @contextmenu.prevent="openContext($event, { id: row._antares_id, orgField: cKey })" |          @contextmenu.prevent="openContext($event, { | ||||||
|  |             id: row._antares_id, | ||||||
|  |             orgField: cKey, | ||||||
|  |             type: fields[cKey].type, | ||||||
|  |             length: fields[cKey].charLength || fields[cKey].length | ||||||
|  |          })" | ||||||
|       > |       > | ||||||
|          <template v-if="cKey !== '_antares_id'"> |          <template v-if="cKey !== '_antares_id'"> | ||||||
|             <span |             <span | ||||||
| @@ -530,7 +535,14 @@ const getKeyUsage = (keyName: string) => { | |||||||
|    return props.keyUsage.find(key => key.field === keyName); |    return props.keyUsage.find(key => key.field === keyName); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const openContext = (event: MouseEvent, payload: { id: string; field?: string; orgField: string; isEditable?: boolean }) => { | const openContext = (event: MouseEvent, payload: { | ||||||
|  |    id: string; | ||||||
|  |    field?: string; | ||||||
|  |    orgField: string; | ||||||
|  |    isEditable?: boolean; | ||||||
|  |    type: string; | ||||||
|  |    length: number | false; | ||||||
|  | }) => { | ||||||
|    payload.field = props.fields[payload.orgField].name;// Ensures field name only |    payload.field = props.fields[payload.orgField].name;// Ensures field name only | ||||||
|    payload.isEditable = isEditable.value; |    payload.isEditable = isEditable.value; | ||||||
|    emit('contextmenu', event, payload); |    emit('contextmenu', event, payload); | ||||||
|   | |||||||
| @@ -389,6 +389,7 @@ export const enUS = { | |||||||
|       collation: 'Collation', |       collation: 'Collation', | ||||||
|       engine: 'Engine', |       engine: 'Engine', | ||||||
|       past: 'Past', |       past: 'Past', | ||||||
|  |       now: 'Now', | ||||||
|       future: 'Future', |       future: 'Future', | ||||||
|       between: 'Between', |       between: 'Between', | ||||||
|       recent: 'Recent', |       recent: 'Recent', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user