mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	feat(PostgreSQL): table fields edit
This commit is contained in:
		| @@ -21,7 +21,7 @@ I'm actively working on it, hoping to provide cool features and fixes as soon as | ||||
|  | ||||
| Why am I developing an SQL client when there are a lot of them on the market?   | ||||
| The main goal is to develop a totally free, full featured, cross platform and open source alternative, empowered by JavaScript's ecosystem.   | ||||
| An application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons or submenu. | ||||
| A modern application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons, tabs or submenu.   | ||||
|  | ||||
| ## How to contribute | ||||
|  | ||||
|   | ||||
| @@ -37,5 +37,12 @@ module.exports = { | ||||
|    indexes: false, | ||||
|    foreigns: false, | ||||
|    sortableFields: false, | ||||
|    zerofill: false | ||||
|    unsigned: false, | ||||
|    nullable: false, | ||||
|    zerofill: false, | ||||
|    autoIncrement: false, | ||||
|    comment: false, | ||||
|    collation: false, | ||||
|    arrays: false, | ||||
|    onUpdate: false | ||||
| }; | ||||
|   | ||||
| @@ -36,5 +36,11 @@ module.exports = { | ||||
|    indexes: true, | ||||
|    foreigns: true, | ||||
|    sortableFields: true, | ||||
|    zerofill: true | ||||
|    unsigned: true, | ||||
|    nullable: true, | ||||
|    zerofill: true, | ||||
|    autoIncrement: true, | ||||
|    comment: true, | ||||
|    collation: true, | ||||
|    onUpdate: true | ||||
| }; | ||||
|   | ||||
| @@ -19,7 +19,7 @@ module.exports = { | ||||
|    schedulers: false, | ||||
|    // Settings | ||||
|    databaseEdit: false, | ||||
|    tableSettings: false, | ||||
|    tableSettings: true, | ||||
|    viewSettings: false, | ||||
|    triggerSettings: false, | ||||
|    routineSettings: false, | ||||
| @@ -27,5 +27,7 @@ module.exports = { | ||||
|    schedulerSettings: false, | ||||
|    indexes: true, | ||||
|    foreigns: true, | ||||
|    sortableFields: false | ||||
|    sortableFields: false, | ||||
|    nullable: true, | ||||
|    arrays: true | ||||
| }; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'TINYINT', | ||||
|             length: true, | ||||
|             length: 4, | ||||
|             collation: false, | ||||
|             unsigned: true, | ||||
|             zerofill: true | ||||
|   | ||||
| @@ -4,22 +4,22 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'SMALLINT', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'INTEGER', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'BIGINT', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'DECIMAL', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
| @@ -29,17 +29,17 @@ module.exports = [ | ||||
|          }, | ||||
|          { | ||||
|             name: 'SMALLSERIAL', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'SERIAL', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'BIGSERIAL', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          } | ||||
|       ] | ||||
| @@ -49,12 +49,12 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'REAL', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          }, | ||||
|          { | ||||
|             name: 'DOUBLE PRECISION', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          } | ||||
|       ] | ||||
| @@ -64,7 +64,7 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'money', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: true | ||||
|          } | ||||
|       ] | ||||
| @@ -77,14 +77,9 @@ module.exports = [ | ||||
|             length: true, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
|             name: 'CHAR', | ||||
|             length: false, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
|             name: 'CHARACTER', | ||||
|             length: false, | ||||
|             length: true, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
| @@ -109,7 +104,7 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'BYTEA', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: false | ||||
|          } | ||||
|       ] | ||||
| @@ -129,17 +124,17 @@ module.exports = [ | ||||
|          }, | ||||
|          { | ||||
|             name: 'DATE', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
|             name: 'TIME', | ||||
|             length: true, | ||||
|             name: 'TIME WITHOUT TIME ZONE', | ||||
|             length: false, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
|             name: 'TIME WITH TIME ZONE', | ||||
|             length: true, | ||||
|             length: false, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
| @@ -229,12 +224,12 @@ module.exports = [ | ||||
|       types: [ | ||||
|          { | ||||
|             name: 'BIT', | ||||
|             length: false, | ||||
|             length: true, | ||||
|             unsigned: false | ||||
|          }, | ||||
|          { | ||||
|             name: 'BIT VARYING', | ||||
|             length: false, | ||||
|             length: true, | ||||
|             unsigned: false | ||||
|          } | ||||
|       ] | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| 'use strict'; | ||||
| import pg, { Pool, Client, types } from 'pg'; | ||||
| import { Pool, Client, types } from 'pg'; | ||||
| import { parse } from 'pgsql-ast-parser'; | ||||
| import { AntaresCore } from '../AntaresCore'; | ||||
| import dataTypes from 'common/data-types/postgresql'; | ||||
| @@ -8,11 +8,11 @@ function pgToString (value) { | ||||
|    return value.toString(); | ||||
| } | ||||
|  | ||||
| pg.types.setTypeParser(1082, pgToString); // date | ||||
| pg.types.setTypeParser(1083, pgToString); // time | ||||
| pg.types.setTypeParser(1114, pgToString); // timestamp | ||||
| pg.types.setTypeParser(1184, pgToString); // timestamptz | ||||
| pg.types.setTypeParser(1266, pgToString); // timetz | ||||
| types.setTypeParser(1082, pgToString); // date | ||||
| types.setTypeParser(1083, pgToString); // time | ||||
| types.setTypeParser(1114, pgToString); // timestamp | ||||
| types.setTypeParser(1184, pgToString); // timestamptz | ||||
| types.setTypeParser(1266, pgToString); // timetz | ||||
|  | ||||
| export class PostgreSQLClient extends AntaresCore { | ||||
|    constructor (args) { | ||||
| @@ -282,7 +282,7 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|             default: field.column_default, | ||||
|             charset: field.character_set_name, | ||||
|             collation: field.collation_name, | ||||
|             autoIncrement: null, | ||||
|             autoIncrement: false, | ||||
|             onUpdate: null, | ||||
|             comment: '' | ||||
|          }; | ||||
| @@ -317,7 +317,10 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|             name: row.constraint_name, | ||||
|             column: row.column_name, | ||||
|             indexType: null, | ||||
|             type: row.constraint_type | ||||
|             type: row.constraint_type, | ||||
|             cardinality: null, | ||||
|             comment: '', | ||||
|             indexComment: '' | ||||
|          }; | ||||
|       }); | ||||
|    } | ||||
| @@ -359,6 +362,8 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|             tc.constraint_name,  | ||||
|             tc.table_name,  | ||||
|             kcu.column_name,  | ||||
|             kcu.position_in_unique_constraint,  | ||||
|             kcu.ordinal_position,  | ||||
|             ccu.table_schema AS foreign_table_schema, | ||||
|             ccu.table_name AS foreign_table_name, | ||||
|             ccu.column_name AS foreign_column_name, | ||||
| @@ -1020,8 +1025,10 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|          options | ||||
|       } = params; | ||||
|  | ||||
|       let sql = `ALTER TABLE \`${table}\` `; | ||||
|       let sql = ''; | ||||
|       const alterColumns = []; | ||||
|       const renameColumns = []; | ||||
|       const createSequences = []; | ||||
|  | ||||
|       // OPTIONS | ||||
|       if ('comment' in options) alterColumns.push(`COMMENT='${options.comment}'`); | ||||
| @@ -1034,7 +1041,7 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|          const typeInfo = this._getTypeInfo(addition.type); | ||||
|          const length = typeInfo.length ? addition.numLength || addition.charLength || addition.datePrecision : false; | ||||
|  | ||||
|          alterColumns.push(`ADD COLUMN \`${addition.name}\`  | ||||
|          alterColumns.push(`ADD COLUMN ${addition.name}  | ||||
|             ${addition.type.toUpperCase()}${length ? `(${length})` : ''}  | ||||
|             ${addition.unsigned ? 'UNSIGNED' : ''}  | ||||
|             ${addition.zerofill ? 'ZEROFILL' : ''} | ||||
| @@ -1043,8 +1050,7 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|             ${addition.default ? `DEFAULT ${addition.default}` : ''} | ||||
|             ${addition.comment ? `COMMENT '${addition.comment}'` : ''} | ||||
|             ${addition.collation ? `COLLATE ${addition.collation}` : ''} | ||||
|             ${addition.onUpdate ? `ON UPDATE ${addition.onUpdate}` : ''} | ||||
|             ${addition.after ? `AFTER \`${addition.after}\`` : 'FIRST'}`); | ||||
|             ${addition.onUpdate ? `ON UPDATE ${addition.onUpdate}` : ''}`); | ||||
|       }); | ||||
|  | ||||
|       // ADD INDEX | ||||
| @@ -1071,18 +1077,33 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|       changes.forEach(change => { | ||||
|          const typeInfo = this._getTypeInfo(change.type); | ||||
|          const length = typeInfo.length ? change.numLength || change.charLength || change.datePrecision : false; | ||||
|          let localType; | ||||
|  | ||||
|          alterColumns.push(`CHANGE COLUMN \`${change.orgName}\` \`${change.name}\`  | ||||
|             ${change.type.toUpperCase()}${length ? `(${length})` : ''}  | ||||
|             ${change.unsigned ? 'UNSIGNED' : ''}  | ||||
|             ${change.zerofill ? 'ZEROFILL' : ''} | ||||
|             ${change.nullable ? 'NULL' : 'NOT NULL'} | ||||
|             ${change.autoIncrement ? 'AUTO_INCREMENT' : ''} | ||||
|             ${change.default ? `DEFAULT ${change.default}` : ''} | ||||
|             ${change.comment ? `COMMENT '${change.comment}'` : ''} | ||||
|             ${change.collation ? `COLLATE ${change.collation}` : ''} | ||||
|             ${change.onUpdate ? `ON UPDATE ${change.onUpdate}` : ''} | ||||
|             ${change.after ? `AFTER \`${change.after}\`` : 'FIRST'}`); | ||||
|          switch (change.type) { | ||||
|             case 'SERIAL': | ||||
|                localType = 'integer'; | ||||
|                break; | ||||
|             case 'SMALLSERIAL': | ||||
|                localType = 'smallint'; | ||||
|                break; | ||||
|             case 'BIGSERIAL': | ||||
|                localType = 'bigint'; | ||||
|                break; | ||||
|             default: | ||||
|                localType = change.type.toLowerCase(); | ||||
|          } | ||||
|  | ||||
|          alterColumns.push(`ALTER COLUMN "${change.orgName}" TYPE ${localType}${length ? `(${length})` : ''} USING "${change.orgName}"::${localType}`); | ||||
|          alterColumns.push(`ALTER COLUMN "${change.orgName}" ${change.nullable ? 'DROP NOT NULL' : 'SET NOT NULL'}`); | ||||
|          alterColumns.push(`ALTER COLUMN "${change.orgName}" ${change.default ? `SET DEFAULT ${change.default}` : 'DROP DEFAULT'}`); | ||||
|          if (['SERIAL', 'SMALLSERIAL', 'BIGSERIAL'].includes(change.type)) { | ||||
|             const sequenceName = `${table}_${change.name}_seq`.replace(' ', '_'); | ||||
|             createSequences.push(`CREATE SEQUENCE IF NOT EXISTS ${sequenceName} OWNED BY "${table}"."${change.orgName}"`); | ||||
|             alterColumns.push(`ALTER COLUMN "${change.orgName}" SET DEFAULT nextval('${sequenceName}')`); | ||||
|          } | ||||
|  | ||||
|          if (change.orgName !== change.name) | ||||
|             renameColumns.push(`ALTER TABLE "${table}" RENAME COLUMN "${change.orgName}" TO "${change.name}"`); | ||||
|       }); | ||||
|  | ||||
|       // CHANGE INDEX | ||||
| @@ -1113,7 +1134,7 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|  | ||||
|       // DROP FIELDS | ||||
|       deletions.forEach(deletion => { | ||||
|          alterColumns.push(`DROP COLUMN \`${deletion.name}\``); | ||||
|          alterColumns.push(`DROP COLUMN ${deletion.name}`); | ||||
|       }); | ||||
|  | ||||
|       // DROP INDEX | ||||
| @@ -1129,10 +1150,12 @@ export class PostgreSQLClient extends AntaresCore { | ||||
|          alterColumns.push(`DROP FOREIGN KEY \`${deletion.constraintName}\``); | ||||
|       }); | ||||
|  | ||||
|       sql += alterColumns.join(', '); | ||||
|       if (alterColumns.length) sql += `ALTER TABLE "${table}" ${alterColumns.join(', ')}; `; | ||||
|  | ||||
|       // RENAME | ||||
|       if (options.name) sql += `; RENAME TABLE \`${table}\` TO \`${options.name}\``; | ||||
|       if (renameColumns.length) sql += `${renameColumns.join(';')}; `; | ||||
|       if (createSequences.length) sql = `${createSequences.join(';')}; ${sql}`; | ||||
|       if (options.name) sql += `ALTER TABLE "${table}" RENAME TO "${options.name}"; `; | ||||
|  | ||||
|       return await this.raw(sql); | ||||
|    } | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
|                   > | ||||
|                </div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|             <div v-if="workspace.customizations.comment" class="form-group"> | ||||
|                <label class="form-label col-4"> | ||||
|                   {{ $t('word.comment') }} | ||||
|                </label> | ||||
| @@ -38,7 +38,7 @@ | ||||
|                   > | ||||
|                </div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|             <div v-if="workspace.customizations.autoIncrement" class="form-group"> | ||||
|                <label class="form-label col-4"> | ||||
|                   {{ $t('word.autoIncrement') }} | ||||
|                </label> | ||||
| @@ -50,7 +50,7 @@ | ||||
|                   > | ||||
|                </div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|             <div v-if="workspace.customizations.collations" class="form-group"> | ||||
|                <label class="form-label col-4"> | ||||
|                   {{ $t('word.collation') }} | ||||
|                </label> | ||||
| @@ -66,7 +66,7 @@ | ||||
|                   </select> | ||||
|                </div> | ||||
|             </div> | ||||
|             <div class="form-group"> | ||||
|             <div v-if="workspace.customizations.engines" class="form-group"> | ||||
|                <label class="form-label col-4"> | ||||
|                   {{ $t('word.engine') }} | ||||
|                </label> | ||||
|   | ||||
| @@ -433,11 +433,11 @@ export default { | ||||
|             _id: uidGen(), | ||||
|             name: `${this.$tc('word.field', 1)}_${++this.newFieldsCounter}`, | ||||
|             key: '', | ||||
|             type: 'int', | ||||
|             type: this.workspace.dataTypes[0].types[0].name, | ||||
|             schema: this.schema, | ||||
|             table: this.table, | ||||
|             numPrecision: null, | ||||
|             numLength: 11, | ||||
|             numLength: this.workspace.dataTypes[0].types[0].length, | ||||
|             datePrecision: null, | ||||
|             charLength: null, | ||||
|             nullable: false, | ||||
|   | ||||
| @@ -49,21 +49,21 @@ | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="th"> | ||||
|                <div v-if="customizations.unsigned" class="th"> | ||||
|                   <div class="column-resizable"> | ||||
|                      <div class="table-column-title"> | ||||
|                         {{ $t('word.unsigned') }} | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="th"> | ||||
|                <div v-if="customizations.nullable" class="th"> | ||||
|                   <div class="column-resizable"> | ||||
|                      <div class="table-column-title"> | ||||
|                         {{ $t('message.allowNull') }} | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="th"> | ||||
|                <div v-if="customizations.zerofill" class="th"> | ||||
|                   <div class="column-resizable"> | ||||
|                      <div class="table-column-title"> | ||||
|                         {{ $t('message.zeroFill') }} | ||||
| @@ -77,14 +77,14 @@ | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="th"> | ||||
|                <div v-if="customizations.comment" class="th"> | ||||
|                   <div class="column-resizable"> | ||||
|                      <div class="table-column-title"> | ||||
|                         {{ $t('word.comment') }} | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="th"> | ||||
|                <div v-if="customizations.collation" class="th"> | ||||
|                   <div class="column-resizable min-100"> | ||||
|                      <div class="table-column-title"> | ||||
|                         {{ $t('word.collation') }} | ||||
| @@ -106,6 +106,7 @@ | ||||
|                :indexes="getIndexes(row.name)" | ||||
|                :foreigns="getForeigns(row.name)" | ||||
|                :data-types="dataTypes" | ||||
|                :customizations="customizations" | ||||
|                @contextmenu="contextMenu" | ||||
|             /> | ||||
|          </draggable> | ||||
| @@ -154,6 +155,9 @@ export default { | ||||
|       workspaceSchema () { | ||||
|          return this.getWorkspace(this.connUid).breadcrumbs.schema; | ||||
|       }, | ||||
|       customizations () { | ||||
|          return this.getWorkspace(this.connUid).customizations; | ||||
|       }, | ||||
|       dataTypes () { | ||||
|          return this.getWorkspace(this.connUid).dataTypes; | ||||
|       }, | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <template> | ||||
|    <div class="tr" @contextmenu.prevent="$emit('contextmenu', $event, localRow._id)"> | ||||
|       <div class="td" tabindex="0"> | ||||
|          <div class="row-draggable"> | ||||
|             <i class="mdi mdi-drag-horizontal row-draggable-icon" /> | ||||
|          <div :class="customizations.sortableFields ? 'row-draggable' : 'text-center'"> | ||||
|             <i v-if="customizations.sortableFields" class="mdi mdi-drag-horizontal row-draggable-icon" /> | ||||
|             {{ localRow.order }} | ||||
|          </div> | ||||
|       </div> | ||||
| @@ -96,7 +96,11 @@ | ||||
|             > | ||||
|          </template> | ||||
|       </div> | ||||
|       <div class="td" tabindex="0"> | ||||
|       <div | ||||
|          v-if="customizations.unsigned" | ||||
|          class="td" | ||||
|          tabindex="0" | ||||
|       > | ||||
|          <label class="form-checkbox"> | ||||
|             <input | ||||
|                v-model="localRow.unsigned" | ||||
| @@ -106,7 +110,11 @@ | ||||
|             <i class="form-icon" /> | ||||
|          </label> | ||||
|       </div> | ||||
|       <div class="td" tabindex="0"> | ||||
|       <div | ||||
|          v-if="customizations.nullable" | ||||
|          class="td" | ||||
|          tabindex="0" | ||||
|       > | ||||
|          <label class="form-checkbox"> | ||||
|             <input | ||||
|                v-model="localRow.nullable" | ||||
| @@ -116,7 +124,11 @@ | ||||
|             <i class="form-icon" /> | ||||
|          </label> | ||||
|       </div> | ||||
|       <div class="td" tabindex="0"> | ||||
|       <div | ||||
|          v-if="customizations.zerofill" | ||||
|          class="td" | ||||
|          tabindex="0" | ||||
|       > | ||||
|          <label class="form-checkbox"> | ||||
|             <input | ||||
|                v-model="localRow.zerofill" | ||||
| @@ -131,7 +143,11 @@ | ||||
|             {{ fieldDefault }} | ||||
|          </span> | ||||
|       </div> | ||||
|       <div class="td type-varchar" tabindex="0"> | ||||
|       <div | ||||
|          v-if="customizations.comment" | ||||
|          class="td type-varchar" | ||||
|          tabindex="0" | ||||
|       > | ||||
|          <span | ||||
|             v-if="!isInlineEditor.comment" | ||||
|             class="cell-content" | ||||
| @@ -149,7 +165,11 @@ | ||||
|             @blur="editOFF" | ||||
|          > | ||||
|       </div> | ||||
|       <div class="td" tabindex="0"> | ||||
|       <div | ||||
|          v-if="customizations.collation" | ||||
|          class="td" | ||||
|          tabindex="0" | ||||
|       > | ||||
|          <template v-if="fieldType.collation"> | ||||
|             <span | ||||
|                v-if="!isInlineEditor.collation" | ||||
| @@ -220,7 +240,7 @@ | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div class="mb-2"> | ||||
|                <div v-if="customizations.nullable" class="mb-2"> | ||||
|                   <label class="form-radio form-inline"> | ||||
|                      <input | ||||
|                         v-model="defaultValue.type" | ||||
| @@ -230,7 +250,7 @@ | ||||
|                      ><i class="form-icon" /> NULL | ||||
|                   </label> | ||||
|                </div> | ||||
|                <div class="mb-2"> | ||||
|                <div v-if="customizations.autoIncrement" class="mb-2"> | ||||
|                   <label class="form-radio form-inline"> | ||||
|                      <input | ||||
|                         v-model="defaultValue.type" | ||||
| @@ -261,7 +281,7 @@ | ||||
|                      </div> | ||||
|                   </div> | ||||
|                </div> | ||||
|                <div> | ||||
|                <div v-if="customizations.onUpdate"> | ||||
|                   <div class="form-group"> | ||||
|                      <label class="form-label col-4"> | ||||
|                         {{ $t('message.onUpdate') }} | ||||
| @@ -294,7 +314,8 @@ export default { | ||||
|       row: Object, | ||||
|       dataTypes: Array, | ||||
|       indexes: Array, | ||||
|       foreigns: Array | ||||
|       foreigns: Array, | ||||
|       customizations: Object | ||||
|    }, | ||||
|    data () { | ||||
|       return { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user