diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.ui.js index b8136d83e..5c10d077d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.ui.js @@ -98,13 +98,13 @@ class ForeignKeyColumnSchema extends BaseUISchema { get baseFields() { return [{ id: 'local_column', label: gettext('Local'), type:'text', editable: false, - cell:'', minWidth: 145, + cell:'', },{ id: 'referenced', label: gettext('Referenced'), type: 'text', editable: false, - cell:'', minWidth: 145, + cell:'', },{ id: 'references_table_name', label: gettext('Referenced Table'), type: 'text', editable: false, - cell:'', minWidth: 145, + cell:'', }]; } } @@ -326,7 +326,6 @@ export default class ForeignKeySchema extends BaseUISchema { }, } }, - minWidth: 245, }), deps: ()=>{ let ret = []; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js index e2816761c..c8980f031 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js @@ -14,7 +14,7 @@ define([ 'sources/pgadmin', 'pgadmin.browser', 'pgadmin.alertifyjs', 'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.node.schema.dir/schema_child_tree_node', 'sources/utils', - 'pgadmin.browser.collection', 'pgadmin.browser.table.partition.utils', + 'pgadmin.browser.collection', ], function( gettext, url_for, $, _, pgAdmin, pgBrowser, Alertify, Backform, Backgrid, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.ui.js index b6ac1b94c..62aa57c4b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.ui.js @@ -6,16 +6,16 @@ import { ConstraintsSchema } from '../../../static/js/table.ui'; import { PartitionKeysSchema, PartitionsSchema } from '../../../static/js/partition.utils.ui'; import { getNodePrivilegeRoleSchema } from '../../../../../../static/js/privilege.ui'; import { getNodeAjaxOptions, getNodeListByName } from '../../../../../../../../static/js/node_ajax'; -import { getNodeVacuumSettingsSchema } from '../../../../../../static/js/vacuum.ui'; import { getNodeForeignKeySchema } from '../../../constraints/foreign_key/static/js/foreign_key.ui'; import { getNodeExclusionConstraintSchema } from '../../../constraints/exclusion_constraint/static/js/exclusion_constraint.ui'; +import * as pgadminUtils from 'sources/utils'; export function getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowser) { const spcname = ()=>getNodeListByName('tablespace', treeNodeInfo, itemNodeData, {}, (m)=>{ return (m.label != 'pg_global'); }); - let tableNode = pgBrowser.Nodes['table']; + let partNode = pgBrowser.Nodes['partition']; return new PartitionTableSchema( { @@ -32,13 +32,12 @@ export function getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowse return true; }), spcname: spcname, - coll_inherits: ()=>getNodeAjaxOptions('get_inherits', tableNode, treeNodeInfo, itemNodeData), - typname: ()=>getNodeAjaxOptions('get_oftype', tableNode, treeNodeInfo, itemNodeData), - like_relation: ()=>getNodeAjaxOptions('get_relations', tableNode, treeNodeInfo, itemNodeData), + coll_inherits: ()=>getNodeAjaxOptions('get_inherits', partNode, treeNodeInfo, itemNodeData), + typname: ()=>getNodeAjaxOptions('get_oftype', partNode, treeNodeInfo, itemNodeData), + like_relation: ()=>getNodeAjaxOptions('get_relations', partNode, treeNodeInfo, itemNodeData), }, treeNodeInfo, { - vacuum_settings: ()=>getNodeVacuumSettingsSchema(tableNode, treeNodeInfo, itemNodeData), constraints: ()=>new ConstraintsSchema( treeNodeInfo, ()=>getNodeForeignKeySchema(treeNodeInfo, itemNodeData, pgBrowser, true), @@ -46,9 +45,24 @@ export function getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowse {spcname: spcname}, ), }, - (privileges)=>getNodePrivilegeRoleSchema(tableNode, treeNodeInfo, itemNodeData, privileges), + (privileges)=>getNodePrivilegeRoleSchema(partNode, treeNodeInfo, itemNodeData, privileges), (params)=>{ - return getNodeAjaxOptions('get_columns', tableNode, treeNodeInfo, itemNodeData, {urlParams: params, useCache:false}); + return getNodeAjaxOptions('get_columns', partNode, treeNodeInfo, itemNodeData, {urlParams: params, useCache:false}); + }, + ()=>getNodeAjaxOptions('get_collations', pgBrowser.Nodes['collation'], treeNodeInfo, itemNodeData), + ()=>getNodeAjaxOptions('get_op_class', pgBrowser.Nodes['table'], treeNodeInfo, itemNodeData), + ()=>{ + return getNodeAjaxOptions('get_attach_tables', partNode, treeNodeInfo, itemNodeData, { + useCache:false, + customGenerateUrl: (treeNodeInfo, actionType)=>{ + return pgadminUtils.sprintf('table/%s/%s/%s/%s/%s/%s', + encodeURIComponent(actionType), encodeURIComponent(treeNodeInfo['server_group']._id), + encodeURIComponent(treeNodeInfo['server']._id), + encodeURIComponent(treeNodeInfo['database']._id), + encodeURIComponent(treeNodeInfo['partition'].schema_id), + encodeURIComponent(treeNodeInfo['partition']._id) + ); + }}); }, { relowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name, @@ -58,7 +72,8 @@ export function getNodePartitionTableSchema(treeNodeInfo, itemNodeData, pgBrowse } export default class PartitionTableSchema extends BaseUISchema { - constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, initValues) { + constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, + getCollations, getOperatorClass, getAttachTables, initValues) { super({ name: undefined, oid: undefined, @@ -98,11 +113,11 @@ export default class PartitionTableSchema extends BaseUISchema { this.getPrivilegeRoleSchema = getPrivilegeRoleSchema; this.nodeInfo = nodeInfo; this.getColumns = getColumns; + this.getAttachTables = getAttachTables; - this.partitionKeysObj = new PartitionKeysSchema(); - this.partitionsObj = new PartitionsSchema(this.nodeInfo); + this.partitionKeysObj = new PartitionKeysSchema([], getCollations, getOperatorClass); + this.partitionsObj = new PartitionsSchema(this.nodeInfo, getCollations, getOperatorClass, getAttachTables); this.constraintsObj = this.schemas.constraints(); - this.vacuumSettingsSchema = this.schemas.vacuum_settings(); } get idAttribute() { @@ -395,13 +410,6 @@ export default class PartitionTableSchema extends BaseUISchema { ].join(''), min_version: 100000, }, - { - // Here - we will create tab control for storage parameters - // (auto vacuum). - type: 'nested-tab', group: gettext('Parameters'), - mode: ['edit', 'create'], deps: ['is_partitioned'], - schema: this.vacuumSettingsSchema, - }, { id: 'relacl_str', label: gettext('Privileges'), disabled: this.inCatalog, type: 'text', mode: ['properties'], group: gettext('Security'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js deleted file mode 100644 index 66092d5c8..000000000 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.js +++ /dev/null @@ -1,595 +0,0 @@ -///////////////////////////////////////////////////////////// -// -// pgAdmin 4 - PostgreSQL Tools -// -// Copyright (C) 2013 - 2021, The pgAdmin Development Team -// This software is released under the PostgreSQL Licence -// -////////////////////////////////////////////////////////////// - -define('pgadmin.node.table_partition_utils', [ - 'sources/gettext', 'jquery', 'underscore', 'backbone', 'pgadmin.browser', - 'pgadmin.backform','pgadmin.backgrid', 'pgadmin.browser.collection', -], function(gettext, $, _, Backbone, pgBrowser, Backform, Backgrid) { - - Backgrid.PartitionRow = Backgrid.Row.extend({ - modelDuplicateClass: 'bg-model-duplicate', - - initialize: function () { - Backgrid.Row.prototype.initialize.apply(this, arguments); - var self = this; - self.model.on('change:is_attach', function() { - setTimeout(function() { - self.columns.each(function(col) { - if (col.get('name') == 'partition_name') { - var idx = self.columns.indexOf(col), - cf = col.get('cellFunction'), - cell = new (cf.apply(col, [self.model]))({ - column: col, - model: self.model, - }), - oldCell = self.cells[idx]; - oldCell.remove(); - self.cells[idx] = cell; - self.render(); - } - }); - }, 10); - }); - self.listenTo(self.model, 'pgadmin-session:model:duplicate', self.modelDuplicate); - self.listenTo(self.model, 'pgadmin-session:model:unique', self.modelUnique); - }, - modelDuplicate: function() { - $(this.el).removeClass('new'); - $(this.el).addClass(this.modelDuplicateClass); - }, - modelUnique: function() { - $(this.el).removeClass(this.modelDuplicateClass); - }, - }); - - var getPartitionCell = function(model) { - var is_attach = model.get('is_attach'); - if (is_attach) { - var options = []; - model.set({'partition_name': undefined}, {silent:true}); - _.each(model.top.table_options, function(t) { - options.push([t.label, t.value]); - }); - return Backgrid.Extension.Select2Cell.extend({optionValues: options}); - - } else { - return Backgrid.StringCell; - } - }; - - Backform.PartitionKeyModel = pgBrowser.Node.Model.extend({ - defaults: { - key_type: 'column', - pt_column: undefined, - expression: undefined, - }, - keys:['pt_column'], - schema: [{ - id: 'key_type', label: gettext('Key type'), type:'select2', editable: true, - cell:'select2', cellHeaderClasses: 'width_percent_25', - select2: {allowClear: false}, - options:[{ - label: gettext('Column'), value: 'column', - },{ - label: gettext('Expression'), value: 'expression', - }], - },{ - id: 'pt_column', label: gettext('Column'), type:'text', - cell: Backgrid.Extension.Select2DepCell.extend({ - keyPathAccessor: function(obj, path) { - var res = obj; - if(_.isArray(res)) { - return _.map(res, function(o) { return o['pt_column']; - }); - } - path = path.split('.'); - for (var i = 0; i < path.length; i++) { - if (_.isNull(res)) return null; - if (_.isEmpty(path[i])) continue; - if (!_.isUndefined(res[path[i]])) res = res[path[i]]; - } - return _.isObject(res) && !_.isArray(res) ? null : res; - }, - initialize: function() { - // Here we will decide if we need to call URL - // Or fetch the data from parent columns collection - var self = this; - if(this.model.handler) { - Backgrid.Extension.Select2DepCell.prototype.initialize.apply(this, arguments); - // Do not listen for any event(s) for existing constraint. - if (_.isUndefined(self.model.get('oid'))) { - var tableCols = self.model.top.get('columns'); - self.listenTo(tableCols, 'remove' , self.resetColOptions); - self.listenTo(tableCols, 'change:name', self.resetColOptions); - } - - self.custom_options(); - } - }, - resetColOptions: function() { - var self = this; - - setTimeout(function () { - self.custom_options(); - self.render.apply(self); - }, 50); - }, - custom_options: function() { - // We will add all the columns entered by user in table model - var columns = this.model.top.get('columns'), - typename = this.model.top.get('typname'), - of_types_tables = this.model.top.of_types_tables, - added_columns_from_tables = []; - - if (columns.length > 0) { - _.each(columns.models, function(m) { - var col = m.get('name'); - if(!_.isUndefined(col) && !_.isNull(col)) { - added_columns_from_tables.push( - {label: col, value: col, image:'icon-column'} - ); - } - }); - } else if (!_.isUndefined(typename) && !_.isNull(typename) - && !_.isUndefined(of_types_tables) && of_types_tables.length > 0) { - // Iterate through all the of_type tables - _.each(of_types_tables, function(type) { - if (type.label == typename) { - // Iterate all the columns of selected "OF TYPE". - _.each(type.oftype_columns, function(col) { - added_columns_from_tables.push( - {label: col.name, value: col.name, image:'icon-column'} - ); - }); - } - }); - } - - // Set the values in to options so that user can select - this.column.set('options', added_columns_from_tables); - }, - remove: function() { - if(this.model.handler) { - var self = this, - tableCols = self.model.top.get('columns'); - self.stopListening(tableCols, 'remove' , self.resetColOptions); - self.stopListening(tableCols, 'change:name' , self.resetColOptions); - Backgrid.Extension.Select2DepCell.prototype.remove.apply(this, arguments); - } - }, - }), - deps: ['key_type'], - cellHeaderClasses: 'width_percent_30', - transform : function(data){ - var res = []; - if (data && _.isArray(data)) { - _.each(data, function(d) { - res.push({label: d.label, value: d.label, image:'icon-column'}); - }); - } - return res; - }, - select2:{allowClear:false}, - editable: function(m) { - if (m.get('key_type') == 'expression') { - setTimeout( function() { - m.set('pt_column', undefined); - }, 10); - return false; - } - return true; - }, - },{ - id: 'expression', label: gettext('Expression'), type:'text', - cell:Backgrid.Extension.StringDepCell, - cellHeaderClasses: 'width_percent_45', - deps: ['key_type'], - editable: function(m) { - if (m.get('key_type') == 'column') { - setTimeout( function() { - m.set('expression', undefined); - }, 10); - return false; - } - return true; - }, - }, - ], - validate: function() { - var col_type = this.get('key_type'), - pt_column = this.get('pt_column'), - expression = this.get('expression'), - msg; - - // Have to clear existing validation before initiating current state - // validation only - this.errorModel.clear(); - - if (_.isUndefined(col_type) || _.isNull(col_type) || - String(col_type).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key type cannot be empty.'); - this.errorModel.set('key_type', msg); - return msg; - } - else if (col_type == 'column' && - _.isUndefined(pt_column) || _.isNull(pt_column) || - String(pt_column).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key column cannot be empty.'); - this.errorModel.set('pt_column', msg); - return msg; - } - else if (col_type == 'expression' && - _.isUndefined(expression) || _.isNull(expression) || - String(expression).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Partition key expression cannot be empty.'); - this.errorModel.set('expression', msg); - return msg; - } - - return null; - }, - }); - - Backform.PartitionsModel = pgBrowser.Node.Model.extend({ - idAttribute: 'oid', - defaults: { - oid: undefined, - is_attach: false, - partition_name: undefined, - is_default: undefined, - values_from: undefined, - values_to: undefined, - values_in: undefined, - values_modulus: undefined, - values_remainder: undefined, - is_sub_partitioned: false, - sub_partition_type: 'range', - }, - keys:['partition_name'], - schema: [{ - id: 'oid', label: gettext('OID'), type: 'text', - mode: ['properties'], - },{ - id: 'is_attach', label:gettext('Operation'), cell: 'switch', type: 'switch', - options: {'onText': gettext('Attach'), 'offText': gettext('Create'), 'width': 65}, - cellHeaderClasses: 'width_percent_5', - editable: function(m) { - if (m instanceof Backbone.Model && m.isNew() && !m.top.isNew()) - return true; - return false; - }, - disabled: function(m) { - if (m instanceof Backbone.Model && m.isNew() && !m.top.isNew()) - return false; - return true; - }, - },{ - id: 'partition_name', label: gettext('Name'), type: 'text', cell:'string', - cellHeaderClasses: 'width_percent_15', - editable: function(m) { - if (m instanceof Backbone.Model && m.isNew()) - return true; - return false; - }, cellFunction: getPartitionCell, - disabled: function(m) { - if (m instanceof Backbone.Model && m.isNew()) - return false; - return true; - }, - },{ - id: 'is_default', label: gettext('Default'), type: 'switch', cell:'switch', - cellHeaderClasses: 'width_percent_5', min_version: 110000, - options: {'onText': gettext('Yes'), 'offText': gettext('No')}, - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - (m.handler.top.attributes.partition_type === 'range' || - m.handler.top.attributes.partition_type === 'list') && - m instanceof Backbone.Model && m.isNew() && - m.handler.top.node_info.server.version >= 110000) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - (m.handler.top.attributes.partition_type === 'range' || - m.handler.top.attributes.partition_type === 'list') && - m instanceof Backbone.Model && m.isNew() && - m.handler.top.node_info.server.version >= 110000) - return false; - return true; - }, - },{ - id: 'values_from', label: gettext('From'), type:'text', - cell:Backgrid.Extension.StringDepCell, deps: ['is_default'], - cellHeaderClasses: 'width_percent_15', - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'range' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'range' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return false; - return true; - }, - },{ - id: 'values_to', label: gettext('To'), type:'text', - cell:Backgrid.Extension.StringDepCell, deps: ['is_default'], - cellHeaderClasses: 'width_percent_15', - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'range' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'range' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return false; - return true; - }, - },{ - id: 'values_in', label: gettext('In'), type:'text', - cell:Backgrid.Extension.StringDepCell, deps: ['is_default'], - cellHeaderClasses: 'width_percent_15', - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'list' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'list' && - m instanceof Backbone.Model && m.isNew() && m.get('is_default') !== true) - return false; - return true; - }, - },{ - id: 'values_modulus', label: gettext('Modulus'), type:'int', - cell:Backgrid.Extension.StringDepCell, - cellHeaderClasses: 'width_percent_15', - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'hash' && - m instanceof Backbone.Model && m.isNew()) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'hash' && - m instanceof Backbone.Model && m.isNew()) - return false; - return true; - }, - },{ - id: 'values_remainder', label: gettext('Remainder'), type:'int', - cell:Backgrid.Extension.StringDepCell, - cellHeaderClasses: 'width_percent_15 width_percent_20', - editable: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'hash' && - m instanceof Backbone.Model && m.isNew()) - return true; - return false; - }, - disabled: function(m) { - if(m.handler && m.handler.top && - m.handler.top.attributes && - m.handler.top.attributes.partition_type === 'hash' && - m instanceof Backbone.Model && m.isNew()) - return false; - return true; - }, - },{ - id: 'is_sub_partitioned', label:gettext('Partitioned table?'), cell: 'switch', - group: 'Partition', type: 'switch', mode: ['properties', 'create', 'edit'], - deps: ['is_attach'], - disabled: function(m) { - if(!m.isNew()) - return true; - - if (m.get('is_attach')) { - setTimeout( function() { - m.set('is_sub_partitioned', false); - }, 10); - return true; - } - return false; - }, - },{ - id: 'sub_partition_type', label:gettext('Partition Type'), - editable: false, type: 'select2', select2: {allowClear: false}, - group: 'Partition', deps: ['is_sub_partitioned'], - options: function() { - var options = [{ - label: gettext('Range'), value: 'range', - },{ - label: gettext('List'), value: 'list', - }]; - - if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server) - && !_.isUndefined(this.node_info.server.version) && - this.node_info.server.version >= 110000) { - options.push({ - label: gettext('Hash'), value: 'hash', - }); - } - return options; - }, - visible: function(m) { - if (m.isNew()) - return true; - return false; - }, - disabled: function(m) { - if (!m.isNew() || !m.get('is_sub_partitioned')) - return true; - return false; - }, - },{ - id: 'sub_partition_keys', label:gettext('Partition Keys'), - model: Backform.PartitionKeyModel, - subnode: Backform.PartitionKeyModel, - editable: true, type: 'collection', - group: 'Partition', mode: ['properties', 'create', 'edit'], - deps: ['is_sub_partitioned', 'sub_partition_type'], - canEdit: false, canDelete: true, - control: 'sub-node-collection', - canAdd: function(m) { - if (m.isNew() && m.get('is_sub_partitioned')) - return true; - return false; - }, - canAddRow: function(m) { - var columns = m.top.get('columns'), - typename = m.top.get('typname'), - columns_exist= false; - - var max_row_count = 1000; - if (m.get('sub_partition_type') && m.get('sub_partition_type') == 'list') - max_row_count = 1; - - /* If columns are not specified by the user then it may be - * possible that he/she selected 'OF TYPE', so we should check - * for that as well. - */ - if (columns.length <= 0 && !_.isUndefined(typename) - && !_.isNull(typename) && m.of_types_tables.length > 0){ - _.each(m.of_types_tables, function(data) { - if (data.label == typename && data.oftype_columns.length > 0){ - columns_exist = true; - } - }); - } else if (columns.length > 0) { - columns_exist = _.some(columns.pluck('name')); - } - - return (m.get('sub_partition_keys') && - m.get('sub_partition_keys').length < max_row_count && columns_exist - ); - - }, - disabled: function(m) { - if (m.get('sub_partition_keys') && m.get('sub_partition_keys').models.length > 0) { - setTimeout(function () { - var coll = m.get('sub_partition_keys'); - coll.remove(coll.filter(function() { return true; })); - - }, 10); - } - }, - visible: function(m) { - if (m.isNew()) - return true; - return false; - }, - },{ - id: 'sub_partition_scheme', label: gettext('Partition Scheme'), - type: 'note', group: 'Partition', mode: ['edit'], - visible: function(m) { - if (!m.isNew() && !_.isUndefined(m.get('sub_partition_scheme')) && - m.get('sub_partition_scheme') != '') - return true; - return false; - }, - disabled: function(m) { - if (!m.isNew()) { - this.text = m.get('sub_partition_scheme'); - } - }, - }], - validate: function() { - var partition_name = this.get('partition_name'), - is_default = this.get('is_default'), - values_from = this.get('values_from'), - values_to = this.get('values_to'), - values_in = this.get('values_in'), - values_modulus = this.get('values_modulus'), - values_remainder = this.get('values_remainder'), - is_sub_partitioned = this.get('is_sub_partitioned'), - sub_partition_keys = this.get('sub_partition_keys'), - msg; - - // Have to clear existing validation before initiating current state - // validation only - this.errorModel.clear(); - this.top.errorModel.clear(); - - if (_.isUndefined(partition_name) || _.isNull(partition_name) || - String(partition_name).replace(/^\s+|\s+$/g, '') === '') { - msg = gettext('Partition name cannot be empty.'); - this.errorModel.set('partition_name', msg); - return msg; - } - - if (is_sub_partitioned && this.isNew() && - !_.isNull(sub_partition_keys) && sub_partition_keys.length <= 0) { - msg = gettext('Please specify at least one key for partitioned table.'); - this.top.errorModel.set('sub_partition_keys', msg); - return msg; - } - - if (this.top.get('partition_type') === 'range') { - if (is_default !== true && (_.isUndefined(values_from) || - _.isNull(values_from) || String(values_from).replace(/^\s+|\s+$/g, '') === '')) { - msg = gettext('For range partition From field cannot be empty.'); - this.errorModel.set('values_from', msg); - return msg; - } else if (is_default !== true && (_.isUndefined(values_to) || _.isNull(values_to) || - String(values_to).replace(/^\s+|\s+$/g, '') === '')) { - msg = gettext('For range partition To field cannot be empty.'); - this.errorModel.set('values_to', msg); - return msg; - } - } else if (this.top.get('partition_type') === 'list') { - if (is_default !== true && (_.isUndefined(values_in) || _.isNull(values_in) || - String(values_in).replace(/^\s+|\s+$/g, '') === '')) { - msg = gettext('For list partition In field cannot be empty.'); - this.errorModel.set('values_in', msg); - return msg; - } - } else if (this.top.get('partition_type') === 'hash') { - if (_.isUndefined(values_modulus) || _.isNull(values_modulus) || - String(values_modulus).replace(/^\s+|\s+$/g, '') === '') { - msg = gettext('For hash partition Modulus field cannot be empty.'); - this.errorModel.set('values_modulus', msg); - return msg; - } else if (_.isUndefined(values_remainder) || _.isNull(values_remainder) || - String(values_remainder).replace(/^\s+|\s+$/g, '') === '') { - msg = gettext('For hash partition Remainder field cannot be empty.'); - this.errorModel.set('values_remainder', msg); - return msg; - } - } - - return null; - }, - }); - -}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js index 72e60fb4c..f6a49eb3d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js @@ -113,7 +113,7 @@ export class PartitionKeysSchema extends BaseUISchema { } } export class PartitionsSchema extends BaseUISchema { - constructor(nodeInfo, getCollations, getOperatorClass) { + constructor(nodeInfo, getCollations, getOperatorClass, getAttachTables=()=>[]) { super({ oid: undefined, is_attach: false, @@ -129,6 +129,7 @@ export class PartitionsSchema extends BaseUISchema { }); this.subPartitionsObj = new PartitionKeysSchema([], getCollations, getOperatorClass); + this.getAttachTables = getAttachTables; this.nodeInfo = nodeInfo; } @@ -143,7 +144,7 @@ export class PartitionsSchema extends BaseUISchema { mode: ['properties'], },{ id: 'is_attach', label:gettext('Operation'), cell: 'select', type: 'select', - minWidth: 120, options: [ + width: 120, disableResizing: true, options: [ {label: gettext('Attach'), value: true}, {label: gettext('Create'), value: false}, ], controlProps: {allowClear: false}, @@ -160,8 +161,34 @@ export class PartitionsSchema extends BaseUISchema { return true; }, },{ - id: 'partition_name', label: gettext('Name'), type: 'text', cell:'text', - minWidth: 80, editable: function(state) { + id: 'partition_name', label: gettext('Name'), + type: (state)=>{ + if(state.is_attach) { + return { + type: 'select', + options: this.getAttachTables, + controlProps: {allowClear: false}, + }; + } else { + return { + type: 'text', + }; + } + }, + cell: (state)=>{ + if(state.is_attach) { + return { + cell: 'select', + options: this.getAttachTables, + controlProps: {allowClear: false}, + }; + } else { + return { + cell: 'text', + }; + } + }, + editable: function(state) { if(obj.isNew(state)) { return true; } @@ -175,7 +202,7 @@ export class PartitionsSchema extends BaseUISchema { }, noEmpty: true, },{ id: 'is_default', label: gettext('Default'), type: 'switch', cell:'switch', - minWidth: 55, min_version: 110000, + width: 55, disableResizing: true, min_version: 110000, editable: function(state) { if(obj.top && (obj.top.sessData.partition_type == 'range' || obj.top.sessData.partition_type == 'list') && obj.isNew(state) @@ -194,7 +221,7 @@ export class PartitionsSchema extends BaseUISchema { }, },{ id: 'values_from', label: gettext('From'), type:'text', cell: 'text', - minWidth: 80, deps: ['is_default'], + deps: ['is_default'], editable: function(state) { if(obj.top && obj.top.sessData.partition_type == 'range' && obj.isNew(state) && state.is_default !== true) { @@ -212,7 +239,7 @@ export class PartitionsSchema extends BaseUISchema { }, { id: 'values_to', label: gettext('To'), type:'text', cell: 'text', - minWidth: 80, deps: ['is_default'], + deps: ['is_default'], editable: function(state) { if(obj.top && obj.top.sessData.partition_type == 'range' && obj.isNew(state) && state.is_default !== true) { @@ -229,7 +256,7 @@ export class PartitionsSchema extends BaseUISchema { }, },{ id: 'values_in', label: gettext('In'), type:'text', cell: 'text', - minWidth: 80, deps: ['is_default'], + deps: ['is_default'], editable: function(state) { if(obj.top && obj.top.sessData.partition_type == 'list' && obj.isNew(state) && state.is_default !== true) { @@ -246,7 +273,6 @@ export class PartitionsSchema extends BaseUISchema { }, },{ id: 'values_modulus', label: gettext('Modulus'), type:'int', cell: 'int', - minWidth: 80, editable: function(state) { if(obj.top && obj.top.sessData.partition_type == 'hash' && obj.isNew(state)) { return true; @@ -262,7 +288,6 @@ export class PartitionsSchema extends BaseUISchema { }, },{ id: 'values_remainder', label: gettext('Remainder'), type:'int', cell: 'int', - minWidth: 80, editable: function(state) { if(obj.top && obj.top.sessData.partition_type == 'hash' && obj.isNew(state)) { return true; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index 2c1103f4a..87e6299c1 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -16,7 +16,7 @@ define('pgadmin.node.table', [ 'pgadmin.alertifyjs', 'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.node.schema.dir/child','pgadmin.node.schema.dir/schema_child_tree_node', 'pgadmin.browser.collection', 'pgadmin.node.column', - 'pgadmin.node.constraints', 'pgadmin.browser.table.partition.utils', + 'pgadmin.node.constraints', ], function( tableFunctions, gettext, url_for, $, _, pgAdmin, pgBrowser, Alertify, Backform, Backgrid, @@ -292,41 +292,6 @@ define('pgadmin.node.table', [ }); }, }, - fetchColumnsInherits: function(arg) { - var self = this, - url = 'get_columns', - m = self.model.top || self.model, - data = undefined, - node = this.field.get('schema_node'), - node_info = this.field.get('node_info'), - full_url = node.generate_url.apply( - node, [ - null, url, this.field.get('node_data'), - this.field.get('url_with_id') || false, node_info, - ] - ), - cache_level = this.field.get('cache_level') || node.type, - cache_node = this.field.get('cache_node'); - - cache_node = (cache_node && pgBrowser.Nodes[cache_node]) || node; - - m.trigger('pgadmin:view:fetching', m, self.field); - // Fetching Columns data for the selected table. - $.ajax({ - async: false, - url: full_url, - data: arg, - }) - .done(function(res) { - data = cache_node.cache(url, node_info, cache_level, res.data); - }) - .fail(function() { - m.trigger('pgadmin:view:fetch:error', m, self.field); - }); - m.trigger('pgadmin:view:fetched', m, self.field); - data = (data && data.data) || []; - return data; - }, getSchema: function(treeNodeInfo, itemNodeData) { return getNodeTableSchema(treeNodeInfo, itemNodeData, pgBrowser); }, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js index d9c3f1fdf..9ea434ab9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.ui.js @@ -59,6 +59,9 @@ export function getNodeTableSchema(treeNodeInfo, itemNodeData, pgBrowser) { }, ()=>getNodeAjaxOptions('get_collations', pgBrowser.Nodes['collation'], treeNodeInfo, itemNodeData), ()=>getNodeAjaxOptions('get_op_class', pgBrowser.Nodes['table'], treeNodeInfo, itemNodeData), + ()=>{ + return getNodeAjaxOptions('get_attach_tables', tableNode, treeNodeInfo, itemNodeData, {useCache:false, urlWithId: true}); + }, { relowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name, schema: treeNodeInfo.schema?._label, @@ -272,7 +275,8 @@ export class LikeSchema extends BaseUISchema { } export default class TableSchema extends BaseUISchema { - constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, getCollations, getOperatorClass, initValues) { + constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, + getCollations, getOperatorClass, getAttachTables, initValues) { super({ name: undefined, oid: undefined, @@ -316,7 +320,7 @@ export default class TableSchema extends BaseUISchema { this.nodeInfo = nodeInfo; this.getColumns = getColumns; - this.partitionsObj = new PartitionsSchema(this.nodeInfo, getCollations, getOperatorClass); + this.partitionsObj = new PartitionsSchema(this.nodeInfo, getCollations, getOperatorClass, getAttachTables); this.constraintsObj = this.schemas.constraints(); this.columnsSchema = this.schemas.columns(); this.vacuumSettingsSchema = this.schemas.vacuum_settings(); diff --git a/web/pgadmin/browser/static/js/node_ajax.js b/web/pgadmin/browser/static/js/node_ajax.js index 124bcb531..aaf6649ab 100644 --- a/web/pgadmin/browser/static/js/node_ajax.js +++ b/web/pgadmin/browser/static/js/node_ajax.js @@ -65,15 +65,22 @@ export function getNodeAjaxOptions(url, nodeObj, treeNodeInfo, itemNodeData, par urlWithId: false, jumpAfterNode: null, useCache: true, + customGenerateUrl: null, ...params }; return new Promise((resolve, reject)=>{ const api = getApiInstance(); let fullUrl = ''; if(url) { - fullUrl = generateNodeUrl.call( - nodeObj, treeNodeInfo, url, itemNodeData, otherParams.urlWithId, nodeObj.parent_type, otherParams.jumpAfterNode - ); + if(otherParams.customGenerateUrl) { + fullUrl = otherParams.customGenerateUrl.call( + nodeObj, treeNodeInfo, url, itemNodeData, otherParams.urlWithId, otherParams.jumpAfterNode + ); + } else { + fullUrl = generateNodeUrl.call( + nodeObj, treeNodeInfo, url, itemNodeData, otherParams.urlWithId, otherParams.jumpAfterNode + ); + } } if (url) { diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx index 103bca91f..a7d93f522 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx @@ -332,6 +332,9 @@ export default function DataGridView({ if(field.width) { widthParms.width = field.width; widthParms.minWidth = field.width; + } else { + widthParms.width = 75; + widthParms.minWidth = 75; } if(field.minWidth) { widthParms.minWidth = field.minWidth; diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 868fc3047..f91506ed1 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -213,7 +213,6 @@ var webpackShimConfig = { 'pgadmin.browser.toolbar': path.join(__dirname, './pgadmin/browser/static/js/toolbar'), 'pgadmin.browser.server.privilege': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/privilege'), 'pgadmin.browser.server.variable': path.join(__dirname, './pgadmin/browser/server_groups/servers/static/js/variable'), - 'pgadmin.browser.table.partition.utils': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils'), 'pgadmin.browser.utils': '/browser/js/utils', 'pgadmin.browser.wizard': path.join(__dirname, './pgadmin/browser/static/js/wizard'), 'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/dashboard'),