+
+
{col.name}
{this.state.show_details &&
{col.cltype}{col.attlen ? ('('+ col.attlen + (col.attprecision ? ','+col.attprecision : '') +')') : ''}}
@@ -172,12 +191,12 @@ export class TableNodeWidget extends React.Component {
}} title="Check note" />}
-
-
{node_data.schema}
+
+ {node_data.schema}
-
-
{node_data.name}
+
+
{node_data.name}
{_.map(node_data.columns, (col)=>this.generateColumn(col))}
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
index c36d87e03..90c284ab8 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
@@ -542,6 +542,35 @@ export default class BodyWidget extends React.Component {
this.canvasEle.style.width = this.canvasEle.scrollWidth + 'px';
this.canvasEle.style.height = this.canvasEle.scrollHeight + 'px';
+ /* html2canvas ignores CSS styles, set the CSS styles to inline */
+ const setSvgInlineStyles = (targetElem) => {
+ const transformProperties = [
+ 'fill',
+ 'color',
+ 'font-size',
+ 'stroke',
+ 'font'
+ ];
+ let svgElems = Array.from(targetElem.getElementsByTagName("svg"));
+ for (let svgElement of svgElems) {
+ svgElement.setAttribute('width', svgElement.clientWidth);
+ svgElement.setAttribute('height', svgElement.clientHeight);
+ recurseElementChildren(svgElement);
+ }
+ function recurseElementChildren(node) {
+ if (!node.style)
+ return;
+
+ let styles = getComputedStyle(node);
+ for (let transformProperty of transformProperties) {
+ node.style[transformProperty] = styles[transformProperty];
+ }
+ for (let child of Array.from(node.childNodes)) {
+ recurseElementChildren(child);
+ }
+ }
+ }
+
html2canvas(this.canvasEle, {
width: this.canvasEle.scrollWidth + 10,
height: this.canvasEle.scrollHeight + 10,
@@ -550,11 +579,16 @@ export default class BodyWidget extends React.Component {
useCORS: true,
allowTaint: true,
backgroundColor: window.getComputedStyle(this.canvasEle).backgroundColor,
+ onclone: (clonedEle)=>{
+ setSvgInlineStyles(clonedEle);
+ return clonedEle;
+ },
}).then((canvas)=>{
let link = document.createElement('a');
link.setAttribute('href', canvas.toDataURL('image/png'));
link.setAttribute('download', this.getCurrentProjectName() + '.png');
link.click();
+ link.remove();
}).catch((err)=>{
console.error(err);
let msg = gettext('Unknown error. Check console logs');
diff --git a/web/pgadmin/tools/erd/static/scss/_erd.scss b/web/pgadmin/tools/erd/static/scss/_erd.scss
index 4fffcf4be..a54df1284 100644
--- a/web/pgadmin/tools/erd/static/scss/_erd.scss
+++ b/web/pgadmin/tools/erd/static/scss/_erd.scss
@@ -97,20 +97,8 @@
width: 175px;
font-size: 0.8em;
- .table-icon-schema {
- background-image: url('~top/browser/server_groups/servers/databases/schemas/static/img/schema.svg') !important;
- // background-repeat: no-repeat;
- // // background-size: 20px !important;
- // align-content: center;
- // vertical-align: middle;
- // height: 100%;
- // background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIwLjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA2NCA2NCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjQgNjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojOTk5OTk5O3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEwO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTIxLjksMjIuMmMwLDMuNS0yLjksNi40LTYuNCw2LjRzLTYuNC0yLjktNi40LTYuNHMyLjktNi40LDYuNC02LjRTMjEuOSwxOC43LDIxLjksMjIuMnogTTQuMiw1MWwyMi4xLTE5CgkgTTQ2LjUsNTEuMUwyNi40LDMyIE0zNy42LDQyLjZsMTEuNi0xMCBNNjIuNCw0NS4xTDQ5LjIsMzIuNyBNNjMsMUgxdjYyaDYyVjF6IE0xLDUxLjRoNjIiLz4KPC9zdmc+Cg==');
-
- width: 20px;
- height: 20px;
- // background: transparent url('~top/browser/server_groups/servers/databases/schemas/static/img/schema.svg') no-repeat center center;
- // height: 100%;
- // width: 20px;
+ .table-icon {
+ padding: 0rem 0.125rem;
}
&.selected {
@@ -175,6 +163,7 @@
.svg-link-ele.path {
pointer-events: all;
+ cursor: move;
}
@keyframes svg-link-ele-selected {
diff --git a/web/regression/javascript/erd/erd_core_spec.js b/web/regression/javascript/erd/erd_core_spec.js
index c42d4732b..b26a5fc05 100644
--- a/web/regression/javascript/erd/erd_core_spec.js
+++ b/web/regression/javascript/erd/erd_core_spec.js
@@ -304,7 +304,7 @@ describe('ERDCore', ()=>{
setTimeout(()=>{
expect(erdCoreObj.dagreDistributeNodes).toHaveBeenCalled();
done();
- }, 10);
+ }, 500);
});
it('clearSelection', ()=>{
diff --git a/web/regression/javascript/erd/table_node_spec.js b/web/regression/javascript/erd/table_node_spec.js
index 4818d2a7a..37d45e99b 100644
--- a/web/regression/javascript/erd/table_node_spec.js
+++ b/web/regression/javascript/erd/table_node_spec.js
@@ -275,13 +275,6 @@ describe('ERD TableNodeWidget', ()=>{
expect(nodeWidget.find('.table-node .table-cols .col-row').length).toBe(3);
});
- it('icons', ()=>{
- let cols = nodeWidget.find('.table-node .table-cols .col-row-data');
- expect(cols.at(0).find('.wcTabIcon').hasClass('icon-primary_key')).toBeTruthy();
- expect(cols.at(1).find('.wcTabIcon').hasClass('icon-column')).toBeTruthy();
- expect(cols.at(2).find('.wcTabIcon').hasClass('icon-column')).toBeTruthy();
- });
-
it('column names', ()=>{
let cols = nodeWidget.find('.table-node .table-cols .col-row-data');
expect(cols.at(0).find('.col-name').text()).toBe('id');
diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js
index 7cc1923e9..5ca7f52c0 100644
--- a/web/webpack.test.config.js
+++ b/web/webpack.test.config.js
@@ -44,6 +44,35 @@ module.exports = {
}, {
test: /\.css$/,
use: [ 'style-loader', 'raw-loader' ],
+ }, {
+ test: /\.(jpe?g|png|gif|svg)$/i,
+ loaders: [{
+ loader: 'url-loader',
+ options: {
+ emitFile: true,
+ name: 'img/[name].[ext]',
+ limit: 4096,
+ },
+ }, {
+ loader: 'image-webpack-loader',
+ query: {
+ bypassOnDebug: true,
+ mozjpeg: {
+ progressive: true,
+ },
+ gifsicle: {
+ interlaced: false,
+ },
+ optipng: {
+ optimizationLevel: 7,
+ },
+ pngquant: {
+ quality: '75-90',
+ speed: 3,
+ },
+ },
+ }],
+ exclude: /vendor/,
}, {
test: /.*slickgrid[\\\/]+slick\.(?!core)*/,
loader: 'imports-loader?' +