├── cp.bat ├── core.js ├── run.bat ├── p.bat ├── src ├── favicon.ico ├── loading.gif ├── loading2.gif ├── bs │ ├── components │ │ ├── header.css │ │ ├── override-ace.css │ │ ├── override-select.css │ │ ├── collapse-icon.jsx │ │ ├── breakpoint │ │ │ ├── _no-query.scss │ │ │ └── parsers │ │ │ │ ├── single │ │ │ │ └── _default.scss │ │ │ │ ├── double │ │ │ │ ├── _default.scss │ │ │ │ ├── _double-string.scss │ │ │ │ └── _default-pair.scss │ │ │ │ ├── triple │ │ │ │ └── _default.scss │ │ │ │ ├── _single.scss │ │ │ │ ├── _triple.scss │ │ │ │ ├── _resolution.scss │ │ │ │ ├── _double.scss │ │ │ │ └── resolution │ │ │ │ └── _resolution.scss │ │ ├── log-status.jsx │ │ ├── require-context.js │ │ ├── server-list.css │ │ ├── server-list.scss │ │ ├── database-diagram.css │ │ ├── checkbox.jsx │ │ ├── message.jsx │ │ ├── database-filter.jsx │ │ ├── react-tabs.scss │ │ ├── server-filter.jsx │ │ ├── Ace.js │ │ ├── EditModal.js │ │ ├── update-checker.jsx │ │ ├── footer.jsx │ │ ├── server-list.jsx │ │ └── jointjs-diagram-table.js │ ├── utils │ │ ├── wait.js │ │ ├── file-handler.js │ │ └── convert.js │ ├── containers │ │ ├── server-management2.jsx │ │ ├── query-browser2.jsx │ │ ├── query-browser.css │ │ ├── Home.jsx │ │ ├── react-tabs.css │ │ ├── ModalEdit.js │ │ └── ModalAbout.js │ ├── reducers │ │ ├── tableEdit.js │ │ ├── status.js │ │ ├── index.js │ │ ├── views.js │ │ ├── indexes.js │ │ ├── triggers.js │ │ ├── config.js │ │ ├── sqlscripts.js │ │ └── schemas.js │ ├── actions │ │ ├── views.js │ │ ├── schemas.js │ │ ├── routines.js │ │ ├── indexes.js │ │ ├── keys.js │ │ ├── triggers.js │ │ ├── tables.js │ │ ├── columns.js │ │ └── config.js │ ├── AppSql.js │ └── store │ │ └── configure.js ├── logo-128px.png ├── mui │ ├── utils │ │ ├── wait.js │ │ ├── file-handler.js │ │ └── convert.js │ ├── containers │ │ ├── query-browser2.jsx │ │ ├── server-management2.jsx │ │ ├── query-browser.css │ │ ├── Home.jsx │ │ ├── app.jsx │ │ ├── react-tabs.css │ │ ├── ModalAbout.js │ │ └── ModalEdit.js │ ├── components │ │ ├── log-status.jsx │ │ ├── breakpoint │ │ │ ├── _no-query.scss │ │ │ └── parsers │ │ │ │ ├── single │ │ │ │ └── _default.scss │ │ │ │ ├── double │ │ │ │ ├── _default.scss │ │ │ │ ├── _double-string.scss │ │ │ │ └── _default-pair.scss │ │ │ │ ├── triple │ │ │ │ └── _default.scss │ │ │ │ ├── _single.scss │ │ │ │ ├── _triple.scss │ │ │ │ ├── _resolution.scss │ │ │ │ ├── _double.scss │ │ │ │ └── resolution │ │ │ │ └── _resolution.scss │ │ ├── collapse-icon.jsx │ │ ├── require-context.js │ │ ├── message.jsx │ │ ├── checkbox.jsx │ │ ├── database-filter.jsx │ │ ├── EditModal.js │ │ ├── server-filter.jsx │ │ ├── confim-modal.jsx │ │ ├── Ace.js │ │ ├── server-list.jsx │ │ ├── update-checker.jsx │ │ ├── footer.jsx │ │ ├── server-db-client-info-modal.jsx │ │ └── jointjs-diagram-table.js │ ├── reducers │ │ ├── tableEdit.js │ │ ├── status.js │ │ ├── index.js │ │ ├── views.js │ │ ├── indexes.js │ │ ├── triggers.js │ │ ├── config.js │ │ ├── sqlscripts.js │ │ └── schemas.js │ ├── actions │ │ ├── views.js │ │ ├── schemas.js │ │ ├── routines.js │ │ ├── indexes.js │ │ ├── keys.js │ │ ├── triggers.js │ │ ├── tables.js │ │ ├── columns.js │ │ └── config.js │ ├── AppSql.js │ └── store │ │ └── configure.js ├── semantic1 │ ├── components │ │ ├── src - 快捷方式.lnk │ │ ├── header.css │ │ ├── log-status.jsx~HEAD │ │ ├── log-status.jsx~1572c5914a1c2861ea611e07c0f1b245e7281167 │ │ ├── override-ace.css │ │ ├── override-select.css │ │ ├── loader.jsx │ │ ├── collapse-icon.jsx │ │ ├── checkbox.jsx │ │ ├── breakpoint │ │ │ ├── _no-query.scss │ │ │ └── parsers │ │ │ │ ├── single │ │ │ │ └── _default.scss │ │ │ │ ├── double │ │ │ │ ├── _default.scss │ │ │ │ ├── _double-string.scss │ │ │ │ └── _default-pair.scss │ │ │ │ ├── triple │ │ │ │ └── _default.scss │ │ │ │ └── _single.scss │ │ ├── message.jsx │ │ ├── EditModal.js │ │ ├── server-filter.jsx │ │ ├── footer.jsx │ │ ├── require-context.js │ │ ├── server-list.css │ │ └── server-db-client-info-modal.jsx │ ├── utils │ │ └── wait.js │ ├── containers │ │ ├── Home.jsx~HEAD │ │ ├── Home.jsx~1572c5914a1c2861ea611e07c0f1b245e7281167 │ │ ├── server-management2.jsx │ │ ├── query-browser2.jsx │ │ ├── query-browser.css │ │ ├── ModalAbout.js │ │ ├── Ace.js~HEAD │ │ └── Ace.js~1572c5914a1c2861ea611e07c0f1b245e7281167 │ ├── menu-handler.js │ ├── reducers │ │ └── tableEdit.js │ └── AppSql.js~HEAD ├── index.js ├── manifest.json ├── .eslintrc ├── menu-handler.js ├── Comp1.test.js ├── index.html ├── Counter.js └── Counter.test.js ├── public ├── favicon.ico ├── logo-128px.png ├── server-db-client-mysql.png ├── server-db-client-sqlite.png ├── server-db-client-cassandra.png ├── server-db-client-postgresql.png ├── server-db-client-sqlserver.png ├── manifest.json └── myremote.js ├── docs ├── development │ ├── build-instructions.md │ ├── docker-databases.md │ ├── run-from-source.md │ ├── test-core-changes.md │ └── release.md └── app │ └── logging.md ├── .gitignore ├── preload.js ├── native.py ├── menu └── index.js ├── update-checker.js ├── main.js ├── babel.config.js ├── c1.js ├── merge.txt ├── app_main.js ├── logger.js └── README.md /cp.bat: -------------------------------------------------------------------------------- 1 | python native.py 2 | -------------------------------------------------------------------------------- /core.js: -------------------------------------------------------------------------------- 1 | const sqlectron = require('sqlectron-core'); -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/run.bat -------------------------------------------------------------------------------- /p.bat: -------------------------------------------------------------------------------- 1 | node_modules\.bin\prettier --single-quote --trailing-comma es5 --write "src/**/*.jsx" -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/src/loading.gif -------------------------------------------------------------------------------- /src/loading2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/src/loading2.gif -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/bs/components/header.css: -------------------------------------------------------------------------------- 1 | #header .right.menu { 2 | margin-left: 0 !important; 3 | } 4 | -------------------------------------------------------------------------------- /src/logo-128px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/src/logo-128px.png -------------------------------------------------------------------------------- /public/logo-128px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/logo-128px.png -------------------------------------------------------------------------------- /public/server-db-client-mysql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/server-db-client-mysql.png -------------------------------------------------------------------------------- /public/server-db-client-sqlite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/server-db-client-sqlite.png -------------------------------------------------------------------------------- /public/server-db-client-cassandra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/server-db-client-cassandra.png -------------------------------------------------------------------------------- /public/server-db-client-postgresql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/server-db-client-postgresql.png -------------------------------------------------------------------------------- /public/server-db-client-sqlserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/public/server-db-client-sqlserver.png -------------------------------------------------------------------------------- /src/bs/utils/wait.js: -------------------------------------------------------------------------------- 1 | export default function wait(time) { 2 | return new Promise(resolve => setTimeout(resolve, time)); 3 | } 4 | -------------------------------------------------------------------------------- /src/mui/utils/wait.js: -------------------------------------------------------------------------------- 1 | export default function wait(time) { 2 | return new Promise(resolve => setTimeout(resolve, time)); 3 | } 4 | -------------------------------------------------------------------------------- /src/semantic1/components/src - 快捷方式.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mahongquan/sqlectron-gui/HEAD/src/semantic1/components/src - 快捷方式.lnk -------------------------------------------------------------------------------- /docs/development/build-instructions.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | 1. `npm install` 4 | 1. `npm run dist` 5 | 1. The installer will be placed at `dist` folder. 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | out 4 | releases 5 | installers 6 | npm-debug.log 7 | .DS_Store 8 | .tmp 9 | *.log 10 | *.lock 11 | *.bak 12 | .storybook 13 | build 14 | 15 | -------------------------------------------------------------------------------- /src/bs/components/override-ace.css: -------------------------------------------------------------------------------- 1 | .ace_editor.ace_autocomplete .ace_completion-highlight { 2 | /* Avoid Blurry render of Highlighting in Retina display */ 3 | text-shadow: 1px 0px 0px !important; 4 | } 5 | -------------------------------------------------------------------------------- /docs/development/docker-databases.md: -------------------------------------------------------------------------------- 1 | # Docker databases 2 | 3 | You can test it using your own database or use a [docker-compose](https://github.com/sqlectron/sqlectron-databases) built for us to bring up several different databases. 4 | -------------------------------------------------------------------------------- /src/bs/components/override-select.css: -------------------------------------------------------------------------------- 1 | .Select-input input { 2 | padding: 0 !important; 3 | border: 0 !important; 4 | } 5 | 6 | .error .Select .Select-control { 7 | background: #fff6f6; 8 | border-color: #e0b4b4; 9 | color: #9f3a38; 10 | border-radius: ''; 11 | box-shadow: none; 12 | } 13 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import App from './mui/AppSql'; 2 | import * as ReactDOMClient from 'react-dom/client' 3 | import "react-tabs/style/react-tabs.css"; 4 | import "@szhsin/react-menu/dist/core.css"; 5 | import React, { Component } from 'react'; 6 | const root=ReactDOMClient.createRoot(document.getElementById('root')); 7 | root.render() -------------------------------------------------------------------------------- /src/mui/containers/query-browser2.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import QueryBrowserContainer from './query-browser.jsx'; 3 | import App from './app.jsx'; 4 | export default function AppContainer(props){ 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /src/mui/containers/server-management2.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ServerManagement from './server-management.jsx'; 3 | import App from './app.jsx'; 4 | export default function AppContainer(props){ 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /src/bs/containers/server-management2.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import ServerManagement from './server-management.jsx'; 3 | import App from './app.jsx'; 4 | export default class AppContainer extends Component { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/bs/containers/query-browser2.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import QueryBrowserContainer from './query-browser.jsx'; 3 | import App from './app.jsx'; 4 | export default class AppContainer extends Component { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/semantic1/components/header.css: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | #header .right.menu { 3 | margin-left: 0 !important; 4 | } 5 | ======= 6 | <<<<<<< HEAD 7 | #header .right.menu { 8 | margin-left: 0 !important; 9 | } 10 | ======= 11 | #header .right.menu { 12 | margin-left: 0 !important; 13 | } 14 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 15 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 16 | -------------------------------------------------------------------------------- /src/bs/components/collapse-icon.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | const CollapseIcon = ({ arrowDirection }) => ( 4 | 8 | ); 9 | 10 | CollapseIcon.propTypes = { 11 | arrowDirection: PropTypes.string.isRequired, 12 | }; 13 | 14 | export default CollapseIcon; 15 | -------------------------------------------------------------------------------- /src/mui/components/log-status.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | var config = window.myremote.config.get(); 3 | const log = config.log; 4 | 5 | export default function LogStatus(props){ 6 | if (!log.console && !log.file) { 7 | return null; 8 | } 9 | //console.log(log.level); 10 | return ( 11 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/_no-query.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-no-query($query) { 2 | @if type-of($query) == 'list' { 3 | $keyword: nth($query, 1); 4 | 5 | @if type-of($keyword) == 'string' and ($keyword == 'no-query' or $keyword == 'no query' or $keyword == 'fallback') { 6 | @return nth($query, 2); 7 | } 8 | @else { 9 | @return false; 10 | } 11 | } 12 | @else { 13 | @return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/_no-query.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-no-query($query) { 2 | @if type-of($query) == 'list' { 3 | $keyword: nth($query, 1); 4 | 5 | @if type-of($keyword) == 'string' and ($keyword == 'no-query' or $keyword == 'no query' or $keyword == 'fallback') { 6 | @return nth($query, 2); 7 | } 8 | @else { 9 | @return false; 10 | } 11 | } 12 | @else { 13 | @return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /preload.js: -------------------------------------------------------------------------------- 1 | /* eslint no-var: 0, prefer-arrow-callback:0 */ 2 | /** 3 | * Inject global configurations in the renderer process. 4 | * 5 | * Since it is loaded directly from the renderer process, 6 | * without passing through a transpiler, this file must use ES5. 7 | */ 8 | 9 | // var config = require('./config'); 10 | 11 | 12 | // process.once('loaded', function onLoaded() { 13 | // global.SQLECTRON_CONFIG = config.get(); 14 | // }); 15 | 16 | -------------------------------------------------------------------------------- /docs/development/run-from-source.md: -------------------------------------------------------------------------------- 1 | # Run from Source 2 | 3 | The Sqlectron developer environment requires Node **(6 or higher)** and NPM. 4 | 5 | **Cloning this project:** 6 | 7 | ```shell 8 | git clone git@github.com:sqlectron/sqlectron-gui.git 9 | cd sqlectron-gui 10 | ``` 11 | 12 | **Installing the dependencies:** 13 | 14 | ```shell 15 | npm install 16 | ``` 17 | 18 | **Running the application:** 19 | 20 | ```shell 21 | npm run dev 22 | ``` 23 | -------------------------------------------------------------------------------- /src/bs/containers/query-browser.css: -------------------------------------------------------------------------------- 1 | #sidebar { overflow-y: hidden; overflow-x: hidden; } 2 | #sidebar ::-webkit-scrollbar{ display:none } 3 | 4 | #sidebar:hover { overflow-y:auto; overflow-y:overlay } 5 | #sidebar:hover ::-webkit-scrollbar { display:block } 6 | 7 | #sidebar ::-webkit-scrollbar { -webkit-appearance:none } 8 | #sidebar ::-webkit-scrollbar-thumb { 9 | box-shadow: inset 0 -2px,inset 0 -8px,inset 0 2px,inset 0 8px; 10 | min-height: 36px 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/mui/containers/query-browser.css: -------------------------------------------------------------------------------- 1 | #sidebar { overflow-y: hidden; overflow-x: hidden; } 2 | #sidebar ::-webkit-scrollbar{ display:none } 3 | 4 | #sidebar:hover { overflow-y:auto; overflow-y:overlay } 5 | #sidebar:hover ::-webkit-scrollbar { display:block } 6 | 7 | #sidebar ::-webkit-scrollbar { -webkit-appearance:none } 8 | #sidebar ::-webkit-scrollbar-thumb { 9 | box-shadow: inset 0 -2px,inset 0 -8px,inset 0 2px,inset 0 8px; 10 | min-height: 36px 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/bs/components/log-status.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | var config = window.myremote.config.get(); 3 | const log = config.log; 4 | 5 | export default class LogStatus extends Component { 6 | render() { 7 | if (!log.console && !log.file) { 8 | return null; 9 | } 10 | //console.log(log.level); 11 | return ( 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/single/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-default($feature) { 2 | $default: breakpoint-get('default feature'); 3 | 4 | // Set Context 5 | $context-setter: private-breakpoint-set-context($default, $feature); 6 | 7 | @if (breakpoint-get('to ems') == true) and (type-of($feature) == 'number') { 8 | @return '#{$default}: #{breakpoint-to-base-em($feature)}'; 9 | } 10 | @else { 11 | @return '#{$default}: #{$feature}'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/single/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-default($feature) { 2 | $default: breakpoint-get('default feature'); 3 | 4 | // Set Context 5 | $context-setter: private-breakpoint-set-context($default, $feature); 6 | 7 | @if (breakpoint-get('to ems') == true) and (type-of($feature) == 'number') { 8 | @return '#{$default}: #{breakpoint-to-base-em($feature)}'; 9 | } 10 | @else { 11 | @return '#{$default}: #{$feature}'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/mui/components/collapse-icon.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | // import ArrowBackIcon from '@mui/icons-material/ArrowBack'; 4 | const CollapseIcon = ({ arrowDirection }) => ( 5 | 9 | ); 10 | 11 | CollapseIcon.propTypes = { 12 | arrowDirection: PropTypes.string.isRequired, 13 | }; 14 | 15 | export default CollapseIcon; 16 | -------------------------------------------------------------------------------- /src/semantic1/components/log-status.jsx~HEAD: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | var config = window.myremote.config.get(); 3 | const log = config.log; 4 | 5 | export default class LogStatus extends Component { 6 | render() { 7 | if (!log.console && !log.file) { 8 | return null; 9 | } 10 | //console.log(log.level); 11 | return ( 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/semantic1/utils/wait.js: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | export default function wait(time) { 3 | return new Promise(resolve => setTimeout(resolve, time)); 4 | } 5 | ======= 6 | <<<<<<< HEAD 7 | export default function wait(time) { 8 | return new Promise(resolve => setTimeout(resolve, time)); 9 | } 10 | ======= 11 | export default function wait(time) { 12 | return new Promise(resolve => setTimeout(resolve, time)); 13 | } 14 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 15 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 16 | -------------------------------------------------------------------------------- /src/semantic1/components/log-status.jsx~1572c5914a1c2861ea611e07c0f1b245e7281167: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | var config = window.myremote.config.get(); 3 | const log = config.log; 4 | 5 | export default class LogStatus extends Component { 6 | render() { 7 | if (!log.console && !log.file) { 8 | return null; 9 | } 10 | //console.log(log.level); 11 | return ( 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/mui/containers/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { withRouter } from 'react-router'; 4 | function Home(props){ 5 | return ( 6 |
7 |
8 |

Home

9 |
10 | to Counter 11 |
12 |
13 | to Db 14 |
15 |
16 |
17 | ); 18 | } 19 | export default withRouter(Home); 20 | -------------------------------------------------------------------------------- /native.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | dir1=r".\node_modules\sqlite3\lib\binding\electron-v1.8-win32-ia32" 4 | if not os.path.exists(dir1): 5 | os.makedirs(dir1) 6 | srcfile="node_sqlite3.node" 7 | desfile=".\\node_modules\\sqlite3\\lib\\binding\\electron-v1.8-win32-ia32\\node_sqlite3.node" 8 | shutil.copyfile(srcfile,desfile) 9 | # dir1=r".\node_modules\serialport\build\Release" 10 | # if not os.path.exists(dir1): 11 | # os.makedirs(dir1) 12 | # srcfile="serialport.node" 13 | # desfile=".\\node_modules\\serialport\\build\\Release\\serialport.node" 14 | # shutil.copyfile(srcfile,desfile) -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "env": { 4 | "browser": true 5 | }, 6 | "rules": { 7 | "no-use-before-define": 0, 8 | "react/jsx-closing-bracket-location": 0, 9 | "react/jsx-first-prop-new-line": 0, 10 | "react/jsx-uses-react": 2, 11 | "react/jsx-uses-vars": 2, 12 | "react/react-in-jsx-scope": 2, 13 | "space-before-function-paren": 0, 14 | "func-names": 0 15 | }, 16 | "ecmaFeatures": { 17 | "jsx": true 18 | }, 19 | "plugins": [ 20 | "react" 21 | ], 22 | "globals": { 23 | "$": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/double/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-double-default($first, $second) { 2 | $feature: ''; 3 | $value: ''; 4 | 5 | @if type-of($first) == 'string' { 6 | $feature: $first; 7 | $value: $second; 8 | } 9 | @else { 10 | $feature: $second; 11 | $value: $first; 12 | } 13 | 14 | // Set Context 15 | $context-setter: private-breakpoint-set-context($feature, $value); 16 | 17 | @if (breakpoint-get('to ems') == true) { 18 | $value: breakpoint-to-base-em($value); 19 | } 20 | 21 | @return '(#{$feature}: #{$value})' 22 | } 23 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/double/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-double-default($first, $second) { 2 | $feature: ''; 3 | $value: ''; 4 | 5 | @if type-of($first) == 'string' { 6 | $feature: $first; 7 | $value: $second; 8 | } 9 | @else { 10 | $feature: $second; 11 | $value: $first; 12 | } 13 | 14 | // Set Context 15 | $context-setter: private-breakpoint-set-context($feature, $value); 16 | 17 | @if (breakpoint-get('to ems') == true) { 18 | $value: breakpoint-to-base-em($value); 19 | } 20 | 21 | @return '(#{$feature}: #{$value})' 22 | } 23 | -------------------------------------------------------------------------------- /docs/development/test-core-changes.md: -------------------------------------------------------------------------------- 1 | # Testing changes of sqlectron-core 2 | 3 | This is an easy way to test sqlectron-core changes on the GUI project. 4 | 5 | 1. Make the GUI project use the core from `../sqlectron-core` directory: 6 | 7 | ```bash 8 | # from sqlectron-gui directory 9 | ./scripts/link-sqlectron-core.sh 10 | ``` 11 | 12 | 1. Start the auto compile of sqlectron-core: 13 | 14 | ```bash 15 | # from sqlectron-core directory 16 | npm run watch 17 | ``` 18 | 19 | 1. Then run the GUI project normally: 20 | 21 | ```shell 22 | # from sqlectron-gui directory 23 | npm run dev 24 | ``` 25 | -------------------------------------------------------------------------------- /src/semantic1/components/override-ace.css: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | .ace_editor.ace_autocomplete .ace_completion-highlight { 6 | /* Avoid Blurry render of Highlighting in Retina display */ 7 | text-shadow: 1px 0px 0px !important; 8 | } 9 | <<<<<<< HEAD 10 | ======= 11 | ======= 12 | .ace_editor.ace_autocomplete .ace_completion-highlight { 13 | /* Avoid Blurry render of Highlighting in Retina display */ 14 | text-shadow: 1px 0px 0px !important; 15 | } 16 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 17 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 18 | -------------------------------------------------------------------------------- /src/menu-handler.js: -------------------------------------------------------------------------------- 1 | var { ipcRenderer } = window.myremote.electron; // 2 | 3 | export default class MenuHandler { 4 | setMenus(commands) { 5 | if (this.commands) { 6 | this.removeAllMenus(); 7 | } 8 | 9 | Object.keys(commands).forEach(command => 10 | ipcRenderer.on(command, commands[command]) 11 | ); 12 | 13 | this.commands = commands; 14 | } 15 | 16 | removeAllMenus() { 17 | if(!this.commands) return; 18 | Object.keys(this.commands).forEach(command => 19 | ipcRenderer.removeListener(command, this.commands[command]) 20 | ); 21 | 22 | this.commands = null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/mui/containers/app.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import * as ConfigActions from '../actions/config.js'; 4 | function AppContainer(props){ 5 | React.useEffect(()=>{ 6 | props.dispatch(ConfigActions.loadConfig()); 7 | },[]) 8 | const { children, config } = props; 9 | return ( 10 |
11 | {config.isLoaded ? children : null} 12 |
13 | ); 14 | } 15 | function mapStateToProps(state) { 16 | return { 17 | config: state.config, 18 | }; 19 | } 20 | 21 | 22 | export default connect(mapStateToProps)(AppContainer); 23 | 24 | -------------------------------------------------------------------------------- /src/bs/reducers/tableEdit.js: -------------------------------------------------------------------------------- 1 | export const SHOW_EDIT = 'SHOW_EDIT'; 2 | export const HIDE_EDIT = 'HIDE_EDIT'; 3 | const INITIAL_STATE = { 4 | show_edit: false, 5 | database:"", 6 | item:"", 7 | }; 8 | 9 | 10 | export default function (state = INITIAL_STATE, action) { 11 | switch (action.type) { 12 | case SHOW_EDIT: { 13 | return { 14 | ...state, 15 | show_edit:true, 16 | database:action.database, 17 | item:action.item, 18 | } 19 | } 20 | case HIDE_EDIT: { 21 | return { 22 | ...state, 23 | show_edit:false, 24 | } 25 | } 26 | default : return state; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/triple/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-triple-default($feature, $first, $second) { 2 | 3 | // Sort into min and max 4 | $min: min($first, $second); 5 | $max: max($first, $second); 6 | 7 | // Set Context 8 | $context-setter: private-breakpoint-set-context(min-#{$feature}, $min); 9 | $context-setter: private-breakpoint-set-context(max-#{$feature}, $max); 10 | 11 | // Make them EMs if need be 12 | @if (breakpoint-get('to ems') == true) { 13 | $min: breakpoint-to-base-em($min); 14 | $max: breakpoint-to-base-em($max); 15 | } 16 | 17 | @return '(min-#{$feature}: #{$min}) and (max-#{$feature}: #{$max})'; 18 | } 19 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/triple/_default.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-triple-default($feature, $first, $second) { 2 | 3 | // Sort into min and max 4 | $min: min($first, $second); 5 | $max: max($first, $second); 6 | 7 | // Set Context 8 | $context-setter: private-breakpoint-set-context(min-#{$feature}, $min); 9 | $context-setter: private-breakpoint-set-context(max-#{$feature}, $max); 10 | 11 | // Make them EMs if need be 12 | @if (breakpoint-get('to ems') == true) { 13 | $min: breakpoint-to-base-em($min); 14 | $max: breakpoint-to-base-em($max); 15 | } 16 | 17 | @return '(min-#{$feature}: #{$min}) and (max-#{$feature}: #{$max})'; 18 | } 19 | -------------------------------------------------------------------------------- /src/mui/reducers/tableEdit.js: -------------------------------------------------------------------------------- 1 | export const SHOW_EDIT = 'SHOW_EDIT'; 2 | export const HIDE_EDIT = 'HIDE_EDIT'; 3 | const INITIAL_STATE = { 4 | show_edit: false, 5 | database:"", 6 | item:"", 7 | }; 8 | 9 | 10 | export default function (state = INITIAL_STATE, action) { 11 | switch (action.type) { 12 | case SHOW_EDIT: { 13 | return { 14 | ...state, 15 | show_edit:true, 16 | database:action.database, 17 | item:action.item, 18 | } 19 | } 20 | case HIDE_EDIT: { 21 | return { 22 | ...state, 23 | show_edit:false, 24 | } 25 | } 26 | default : return state; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/bs/components/require-context.js: -------------------------------------------------------------------------------- 1 | // export const requireLogos = require('./server-db-client-.*\.png$/); 2 | const cassandraPNG = './server-db-client-cassandra.png'; 3 | const mysqlPNG = './server-db-client-mysql.png'; 4 | const pgPNG = './server-db-client-postgresql.png'; 5 | const sqlitePNG = './server-db-client-sqlite.png'; 6 | const sqlserverPNG = './server-db-client-sqlserver.png'; 7 | 8 | var dic1 = { 9 | cassandra: cassandraPNG, 10 | postgresql: pgPNG, 11 | mysql: mysqlPNG, 12 | sqlite: sqlitePNG, 13 | sqlserver: sqlserverPNG, 14 | }; 15 | export const requireLogos = name => { 16 | return dic1[name]; 17 | }; // require.context('./', false, /server-db-client-.*\.png$/); 18 | -------------------------------------------------------------------------------- /src/mui/components/require-context.js: -------------------------------------------------------------------------------- 1 | // export const requireLogos = require('./server-db-client-.*\.png$/); 2 | const cassandraPNG = './server-db-client-cassandra.png'; 3 | const mysqlPNG = './server-db-client-mysql.png'; 4 | const pgPNG = './server-db-client-postgresql.png'; 5 | const sqlitePNG = './server-db-client-sqlite.png'; 6 | const sqlserverPNG = './server-db-client-sqlserver.png'; 7 | 8 | var dic1 = { 9 | cassandra: cassandraPNG, 10 | postgresql: pgPNG, 11 | mysql: mysqlPNG, 12 | sqlite: sqlitePNG, 13 | sqlserver: sqlserverPNG, 14 | }; 15 | export const requireLogos = name => { 16 | return dic1[name]; 17 | }; // require.context('./', false, /server-db-client-.*\.png$/); 18 | -------------------------------------------------------------------------------- /src/Comp1.test.js: -------------------------------------------------------------------------------- 1 | import TestRenderer from 'react-test-renderer'; 2 | import React from 'react'; 3 | function MyComponent() { 4 | return ( 5 |
6 | 7 |

Hello

8 |
9 | ) 10 | } 11 | 12 | function SubComponent() { 13 | return ( 14 |

Sub

15 | ); 16 | } 17 | const testRenderer = TestRenderer.create(); 18 | const testInstance = testRenderer.root; 19 | test('test props', () => { 20 | expect(testInstance.findByType(SubComponent).props.foo).toBe('bar'); 21 | }); 22 | test('test children', () => { 23 | expect(testInstance.findByProps({className: "sub"}).children).toEqual(['Sub']); 24 | }); 25 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/double/_double-string.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-double-string($first, $second) { 2 | $feature: ''; 3 | $value: ''; 4 | 5 | // Test to see which is the feature and which is the value 6 | @if (breakpoint-string-value($first) == true) { 7 | $feature: $first; 8 | $value: $second; 9 | } 10 | @else if (breakpoint-string-value($second) == true) { 11 | $feature: $second; 12 | $value: $first; 13 | } 14 | @else { 15 | @warn "Neither #{$first} nor #{$second} is a valid media query name."; 16 | } 17 | 18 | // Set Context 19 | $context-setter: private-breakpoint-set-context($feature, $value); 20 | 21 | @return '(#{$feature}: #{$value})'; 22 | } -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | sqlectron 7 | 8 | 9 | 10 | 11 | 14 |
15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/double/_double-string.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-double-string($first, $second) { 2 | $feature: ''; 3 | $value: ''; 4 | 5 | // Test to see which is the feature and which is the value 6 | @if (breakpoint-string-value($first) == true) { 7 | $feature: $first; 8 | $value: $second; 9 | } 10 | @else if (breakpoint-string-value($second) == true) { 11 | $feature: $second; 12 | $value: $first; 13 | } 14 | @else { 15 | @warn "Neither #{$first} nor #{$second} is a valid media query name."; 16 | } 17 | 18 | // Set Context 19 | $context-setter: private-breakpoint-set-context($feature, $value); 20 | 21 | @return '(#{$feature}: #{$value})'; 22 | } -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/double/_default-pair.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-default-pair($first, $second) { 2 | $default: breakpoint-get('default pair'); 3 | $min: ''; 4 | $max: ''; 5 | 6 | // Sort into min and max 7 | $min: min($first, $second); 8 | $max: max($first, $second); 9 | 10 | // Set Context 11 | $context-setter: private-breakpoint-set-context(min-#{$default}, $min); 12 | $context-setter: private-breakpoint-set-context(max-#{$default}, $max); 13 | 14 | // Make them EMs if need be 15 | @if (breakpoint-get('to ems') == true) { 16 | $min: breakpoint-to-base-em($min); 17 | $max: breakpoint-to-base-em($max); 18 | } 19 | 20 | @return '(min-#{$default}: #{$min}) and (max-#{$default}: #{$max})'; 21 | } 22 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/double/_default-pair.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-parse-default-pair($first, $second) { 2 | $default: breakpoint-get('default pair'); 3 | $min: ''; 4 | $max: ''; 5 | 6 | // Sort into min and max 7 | $min: min($first, $second); 8 | $max: max($first, $second); 9 | 10 | // Set Context 11 | $context-setter: private-breakpoint-set-context(min-#{$default}, $min); 12 | $context-setter: private-breakpoint-set-context(max-#{$default}, $max); 13 | 14 | // Make them EMs if need be 15 | @if (breakpoint-get('to ems') == true) { 16 | $min: breakpoint-to-base-em($min); 17 | $max: breakpoint-to-base-em($max); 18 | } 19 | 20 | @return '(min-#{$default}: #{$min}) and (max-#{$default}: #{$max})'; 21 | } 22 | -------------------------------------------------------------------------------- /src/bs/components/server-list.css: -------------------------------------------------------------------------------- 1 | #server-list { 2 | /** 3 | * 1 card per row 4 | */ 5 | /** 6 | * 2 cards per row 7 | */ 8 | /** 9 | * 4 cards per row 10 | */ 11 | } 12 | #server-list .ui.cards > .card { 13 | width: 100%; 14 | } 15 | #server-list .ui.cards { 16 | margin-left: -1em; 17 | margin-right: -1em; 18 | } 19 | #server-list .ui.cards > .card { 20 | width: calc( 50% - 2em ); 21 | margin-left: 1em; 22 | margin-right: 1em; 23 | } 24 | #server-list .ui.cards { 25 | margin-left: -0.75em; 26 | margin-right: -0.75em; 27 | } 28 | #server-list .ui.cards > .card { 29 | width: calc( 25% - 1.5em ); 30 | margin-left: 0.75em; 31 | margin-right: 0.75em; 32 | } 33 | #server-list .card .content .header, #server-list .card .content .meta { 34 | word-break: break-all; 35 | } 36 | -------------------------------------------------------------------------------- /docs/development/release.md: -------------------------------------------------------------------------------- 1 | # Release 2 | 3 | We use [electron-builder](https://github.com/electron-userland/electron-builder) to package and distribute the application. Which makes really easy doing that. 4 | 5 | 1. Change the app version on [app/package.json](https://github.com/sqlectron/sqlectron-gui/blob/master/app/package.json#L3) based on [SemVer](http://semver.org/). 6 | 1. Create a new **DRAFT** [release](https://github.com/sqlectron/sqlectron-gui/releases) with the same version of the previous step. 7 | 1. On the next CI build it will upload the installers to this release. This allows testing the installers before release. 8 | 1. Once the [release](https://github.com/sqlectron/sqlectron-gui/releases) is ready just publish it. 9 | 1. Update [Homebrew Cask](https://github.com/caskroom/homebrew-cask/blob/master/CONTRIBUTING.md#updating-a-cask). 10 | -------------------------------------------------------------------------------- /menu/index.js: -------------------------------------------------------------------------------- 1 | var { Menu } =require('electron'); // eslint-disable-line import/no-unresolved 2 | var darwin =require('./darwin'); 3 | var linux =require('./linux'); 4 | var win32 =require('./win32'); 5 | 6 | 7 | const menus = { 8 | darwin, 9 | linux, 10 | win32, 11 | }; 12 | 13 | 14 | function attachMenuToWindow(app, buildNewWindow, appConfig) { 15 | const template = menus[process.platform].buildTemplate(app, buildNewWindow, appConfig); 16 | const menu = Menu.buildFromTemplate(template); 17 | Menu.setApplicationMenu(menu); 18 | 19 | if (process.platform === 'darwin') { 20 | const dockTemplate = menus.darwin.buildTemplateDockMenu(app, buildNewWindow); 21 | const dockMenu = Menu.buildFromTemplate(dockTemplate); 22 | app.dock.setMenu(dockMenu); 23 | } 24 | } 25 | exports.attachMenuToWindow=attachMenuToWindow 26 | -------------------------------------------------------------------------------- /src/semantic1/components/override-select.css: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | .Select-input input { 6 | padding: 0 !important; 7 | border: 0 !important; 8 | } 9 | 10 | .error .Select .Select-control { 11 | background: #fff6f6; 12 | border-color: #e0b4b4; 13 | color: #9f3a38; 14 | border-radius: ''; 15 | box-shadow: none; 16 | } 17 | <<<<<<< HEAD 18 | ======= 19 | ======= 20 | .Select-input input { 21 | padding: 0 !important; 22 | border: 0 !important; 23 | } 24 | 25 | .error .Select .Select-control { 26 | background: #fff6f6; 27 | border-color: #e0b4b4; 28 | color: #9f3a38; 29 | border-radius: ''; 30 | box-shadow: none; 31 | } 32 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 33 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 34 | -------------------------------------------------------------------------------- /src/Counter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | export default class App extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | this.state = {count: 0}; 7 | this.handleClick = this.handleClick.bind(this); 8 | } 9 | componentDidMount() { 10 | document.title = `You clicked ${this.state.count} times`; 11 | } 12 | componentDidUpdate() { 13 | document.title = `You clicked ${this.state.count} times`; 14 | } 15 | handleClick() { 16 | this.setState(state => ({ 17 | count: state.count + 1, 18 | })); 19 | } 20 | render() { 21 | return ( 22 |
23 |

You clicked {this.state.count} times

24 | 27 |
28 | ); 29 | } 30 | } -------------------------------------------------------------------------------- /src/bs/containers/Home.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { withRouter } from 'react-router'; 4 | class Home extends Component { 5 | componentDidMount() { 6 | console.log(this.props); 7 | this.props.history.push('/manage'); 8 | } 9 | UNSAFE_componentWillReceiveProps(nextProps) { 10 | console.log(nextProps); 11 | } 12 | render() { 13 | console.log('render==========='); 14 | return ( 15 |
16 |
17 |

Home

18 |
19 | to Counter 20 |
21 |
22 | to Db 23 |
24 |
25 |
26 | ); 27 | } 28 | } 29 | export default withRouter(Home); 30 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/_single.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "single/default"; 5 | 6 | @function breakpoint-parse-single($feature, $empty-media, $first) { 7 | $parsed: ''; 8 | $leader: ''; 9 | // If we're forcing 10 | @if not ($empty-media) or not ($first) { 11 | $leader: 'and '; 12 | } 13 | 14 | // If it's a single feature that can stand alone, we let it 15 | @if (breakpoint-single-string($feature)) { 16 | $parsed: $feature; 17 | // Set Context 18 | $context-setter: private-breakpoint-set-context($feature, $feature); 19 | } 20 | // If it's not a stand alone feature, we pass it off to the default handler. 21 | @else { 22 | $parsed: breakpoint-parse-default($feature); 23 | } 24 | 25 | @return $leader + '(' + $parsed + ')'; 26 | } 27 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/_single.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "single/default"; 5 | 6 | @function breakpoint-parse-single($feature, $empty-media, $first) { 7 | $parsed: ''; 8 | $leader: ''; 9 | // If we're forcing 10 | @if not ($empty-media) or not ($first) { 11 | $leader: 'and '; 12 | } 13 | 14 | // If it's a single feature that can stand alone, we let it 15 | @if (breakpoint-single-string($feature)) { 16 | $parsed: $feature; 17 | // Set Context 18 | $context-setter: private-breakpoint-set-context($feature, $feature); 19 | } 20 | // If it's not a stand alone feature, we pass it off to the default handler. 21 | @else { 22 | $parsed: breakpoint-parse-default($feature); 23 | } 24 | 25 | @return $leader + '(' + $parsed + ')'; 26 | } 27 | -------------------------------------------------------------------------------- /src/semantic1/containers/Home.jsx~HEAD: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { withRouter } from 'react-router'; 4 | 5 | class Home extends Component { 6 | componentDidMount() { 7 | console.log(this.props); 8 | this.props.history.push('/manage'); 9 | } 10 | UNSAFE_componentWillReceiveProps(nextProps) { 11 | console.log(nextProps); 12 | } 13 | render() { 14 | console.log('render==========='); 15 | return ( 16 |
17 |
18 |

Home

19 |
20 | to Counter 21 |
22 |
23 | to Db 24 |
25 |
26 |
27 | ); 28 | } 29 | } 30 | export default withRouter(Home); 31 | -------------------------------------------------------------------------------- /src/semantic1/containers/Home.jsx~1572c5914a1c2861ea611e07c0f1b245e7281167: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { withRouter } from 'react-router'; 4 | 5 | class Home extends Component { 6 | componentDidMount() { 7 | console.log(this.props); 8 | this.props.history.push('/manage'); 9 | } 10 | UNSAFE_componentWillReceiveProps(nextProps) { 11 | console.log(nextProps); 12 | } 13 | render() { 14 | console.log('render==========='); 15 | return ( 16 |
17 |
18 |

Home

19 |
20 | to Counter 21 |
22 |
23 | to Db 24 |
25 |
26 |
27 | ); 28 | } 29 | } 30 | export default withRouter(Home); 31 | -------------------------------------------------------------------------------- /src/semantic1/containers/server-management2.jsx: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | import React, { Component } from 'react'; 6 | import ServerManagement from './server-management.jsx'; 7 | import App from './app.jsx'; 8 | export default class AppContainer extends Component { 9 | render() { 10 | return ( 11 | 12 | 13 | 14 | ); 15 | } 16 | } 17 | <<<<<<< HEAD 18 | ======= 19 | ======= 20 | import React, { Component } from 'react'; 21 | import ServerManagement from './server-management.jsx'; 22 | import App from './app.jsx'; 23 | export default class AppContainer extends Component { 24 | render() { 25 | return ( 26 | 27 | 28 | 29 | ); 30 | } 31 | } 32 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 33 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 34 | -------------------------------------------------------------------------------- /src/semantic1/containers/query-browser2.jsx: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | import React, { Component } from 'react'; 6 | import QueryBrowserContainer from './query-browser.jsx'; 7 | import App from './app.jsx'; 8 | export default class AppContainer extends Component { 9 | render() { 10 | return ( 11 | 12 | 13 | 14 | ); 15 | } 16 | } 17 | <<<<<<< HEAD 18 | ======= 19 | ======= 20 | import React, { Component } from 'react'; 21 | import QueryBrowserContainer from './query-browser.jsx'; 22 | import App from './app.jsx'; 23 | export default class AppContainer extends Component { 24 | render() { 25 | return ( 26 | 27 | 28 | 29 | ); 30 | } 31 | } 32 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 33 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 34 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/_triple.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "triple/default"; 5 | 6 | @function breakpoint-parse-triple($feature, $empty-media, $first) { 7 | $parsed: ''; 8 | $leader: ''; 9 | 10 | // If we're forcing 11 | @if not ($empty-media) or not ($first) { 12 | $leader: 'and '; 13 | } 14 | 15 | // separate the string features from the value numbers 16 | $string: null; 17 | $numbers: null; 18 | @each $val in $feature { 19 | @if type-of($val) == string { 20 | $string: $val; 21 | } 22 | @else { 23 | @if type-of($numbers) == 'null' { 24 | $numbers: $val; 25 | } 26 | @else { 27 | $numbers: append($numbers, $val); 28 | } 29 | } 30 | } 31 | 32 | $parsed: breakpoint-parse-triple-default($string, nth($numbers, 1), nth($numbers, 2)); 33 | 34 | @return $leader + $parsed; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/_triple.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "triple/default"; 5 | 6 | @function breakpoint-parse-triple($feature, $empty-media, $first) { 7 | $parsed: ''; 8 | $leader: ''; 9 | 10 | // If we're forcing 11 | @if not ($empty-media) or not ($first) { 12 | $leader: 'and '; 13 | } 14 | 15 | // separate the string features from the value numbers 16 | $string: null; 17 | $numbers: null; 18 | @each $val in $feature { 19 | @if type-of($val) == string { 20 | $string: $val; 21 | } 22 | @else { 23 | @if type-of($numbers) == 'null' { 24 | $numbers: $val; 25 | } 26 | @else { 27 | $numbers: append($numbers, $val); 28 | } 29 | } 30 | } 31 | 32 | $parsed: breakpoint-parse-triple-default($string, nth($numbers, 1), nth($numbers, 2)); 33 | 34 | @return $leader + $parsed; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/_resolution.scss: -------------------------------------------------------------------------------- 1 | @import "resolution/resolution"; 2 | 3 | @function breakpoint-build-resolution($query-print, $query-resolution, $empty-media, $first) { 4 | $leader: ''; 5 | // If we're forcing 6 | @if not ($empty-media) or not ($first) { 7 | $leader: 'and '; 8 | } 9 | 10 | @if breakpoint-get('transform resolutions') and $query-resolution { 11 | $resolutions: breakpoint-make-resolutions($query-resolution); 12 | $length: length($resolutions); 13 | $query-holder: ''; 14 | 15 | @for $i from 1 through $length { 16 | $query: '#{$query-print} #{$leader}#{nth($resolutions, $i)}'; 17 | @if $i == 1 { 18 | $query-holder: $query; 19 | } 20 | @else { 21 | $query-holder: '#{$query-holder}, #{$query}'; 22 | } 23 | } 24 | 25 | @return $query-holder; 26 | } 27 | @else { 28 | // Return with attached resolution 29 | @return $query-print; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/_resolution.scss: -------------------------------------------------------------------------------- 1 | @import "resolution/resolution"; 2 | 3 | @function breakpoint-build-resolution($query-print, $query-resolution, $empty-media, $first) { 4 | $leader: ''; 5 | // If we're forcing 6 | @if not ($empty-media) or not ($first) { 7 | $leader: 'and '; 8 | } 9 | 10 | @if breakpoint-get('transform resolutions') and $query-resolution { 11 | $resolutions: breakpoint-make-resolutions($query-resolution); 12 | $length: length($resolutions); 13 | $query-holder: ''; 14 | 15 | @for $i from 1 through $length { 16 | $query: '#{$query-print} #{$leader}#{nth($resolutions, $i)}'; 17 | @if $i == 1 { 18 | $query-holder: $query; 19 | } 20 | @else { 21 | $query-holder: '#{$query-holder}, #{$query}'; 22 | } 23 | } 24 | 25 | @return $query-holder; 26 | } 27 | @else { 28 | // Return with attached resolution 29 | @return $query-print; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/mui/components/message.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | export default function Message(props){ 4 | const [state,setState]=React.useState({}); 5 | React.useEffect(()=>{ 6 | setState({ visible: true }); 7 | return ()=>{ 8 | setState({ visible: false }); 9 | } 10 | },[]); 11 | const onClose=()=> { 12 | setState({ visible: false }); 13 | } 14 | 15 | const { closeable, title, message, type, preformatted } = props; 16 | var classtype = `ui message ${type || ''}`; 17 | return ( 18 |
19 |
20 | {closeable && ( 21 | 22 | )} 23 | {title &&
{title}
} 24 | {message && preformatted ?
{message}
:

{message}

} 25 |
26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /update-checker.js: -------------------------------------------------------------------------------- 1 | var axios =require('axios'); 2 | //import createLogger from './logger'; 3 | 4 | //const logger = createLogger('gh-update-checker'); 5 | const WAIT_2_SECS = 2000; 6 | 7 | 8 | async function check(mainWindow, appConfig) { 9 | const currentVersion = `v${appConfig.version}`; 10 | //logger.debug('current version %s', currentVersion); 11 | 12 | const repo = appConfig.repository.url.replace('https://github.com/', ''); 13 | const latestReleaseURL = `https://api.github.com/repos/${repo}/releases/latest`; 14 | const response = await axios.get(latestReleaseURL); 15 | 16 | //logger.debug('latest version %s', response.data.tag_name); 17 | if (currentVersion === response.data.tag_name) { 18 | //logger.debug('already using the latest version'); 19 | return; 20 | } 21 | 22 | // give some time to the render process be ready 23 | setTimeout( 24 | () => mainWindow.webContents.send('sqlectron:update-available'), 25 | WAIT_2_SECS 26 | ); 27 | } 28 | exports.check=check; -------------------------------------------------------------------------------- /src/mui/components/checkbox.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import Checkbox from '@mui/material/Checkbox'; 4 | export default function CheckboxMe(props){ 5 | // static propTypes = { 6 | // name: PropTypes.string.isRequired, 7 | // label: PropTypes.string.isRequired, 8 | // disabled: PropTypes.bool, 9 | // defaultChecked: PropTypes.bool, 10 | // onChecked: PropTypes.func.isRequired, 11 | // onUnchecked: PropTypes.func.isRequired, 12 | // }; 13 | const onChange = () => { 14 | if (!props.defaultChecked) { 15 | props.onChecked(); 16 | } else { 17 | props.onUnchecked(); 18 | } 19 | }; 20 | const { name, label, disabled } = props; 21 | return ( 22 |
23 | {label} 24 | 31 |
32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /src/mui/components/database-filter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | 4 | const DatabaseFilter=React.forwardRef((props,ref_filter)=>{ 5 | const filter=React.useRef(null); 6 | const onFilterChange=(event)=> { 7 | props.onFilterChange(event.target.value); 8 | } 9 | 10 | const focus=()=> { 11 | ref_filter.current.focus(); 12 | } 13 | 14 | //console.log("render DatabaseFilter"); 15 | //console.log(this.props); 16 | 17 | var { value, placeholder, isFetching } = props; 18 | if (!value) value = ''; 19 | return ( 20 |
21 | 29 | 30 |
31 | ); 32 | }); 33 | export default DatabaseFilter; -------------------------------------------------------------------------------- /src/bs/components/server-list.scss: -------------------------------------------------------------------------------- 1 | @import "breakpoint"; 2 | 3 | 4 | #server-list { 5 | /** 6 | * 1 card per row 7 | */ 8 | .ui.cards > .card { 9 | width: 100%; 10 | } 11 | 12 | /** 13 | * 2 cards per row 14 | */ 15 | @include respond-to('bigger than small') { 16 | .ui.cards { 17 | margin-left: -1em; 18 | margin-right: -1em; 19 | } 20 | 21 | .ui.cards > .card { 22 | width: calc( 50% - 2em ); 23 | margin-left: 1em; 24 | margin-right: 1em; 25 | } 26 | } 27 | 28 | /** 29 | * 4 cards per row 30 | */ 31 | @include respond-to('bigger than small-medium') { 32 | .ui.cards { 33 | margin-left: -0.75em; 34 | margin-right: -0.75em; 35 | } 36 | 37 | .ui.cards > .card { 38 | width: calc( 25% - 1.5em ); 39 | margin-left: 0.75em; 40 | margin-right: 0.75em; 41 | } 42 | } 43 | 44 | 45 | .card .content { 46 | .header, .meta { 47 | word-break: break-all; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/bs/reducers/status.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as tablesTypes from '../actions/tables'; 3 | import * as queriesTypes from '../actions/queries'; 4 | 5 | 6 | const INITIAL_STATE = ''; 7 | 8 | 9 | export default function (state = INITIAL_STATE, action) { 10 | switch (action.type) { 11 | case connTypes.CONNECTION_REQUEST: 12 | return 'Connecting to database...'; 13 | case connTypes.CONNECTION_SUCCESS: 14 | return 'Connection to database established'; 15 | case tablesTypes.FETCH_TABLES_REQUEST: 16 | return 'Loading list of tables...'; 17 | case queriesTypes.EXECUTE_QUERY_REQUEST: 18 | return 'Executing query...'; 19 | case queriesTypes.SAVE_QUERY_REQUEST: 20 | return 'Saving query...'; 21 | case queriesTypes.SAVE_QUERY_SUCCESS: 22 | return 'Query saved successfully'; 23 | case queriesTypes.SAVE_QUERY_FAILURE: 24 | return `Error saving query. ${action.error}`; 25 | default: 26 | return INITIAL_STATE; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/mui/reducers/status.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as tablesTypes from '../actions/tables'; 3 | import * as queriesTypes from '../actions/queries'; 4 | 5 | 6 | const INITIAL_STATE = ''; 7 | 8 | 9 | export default function (state = INITIAL_STATE, action) { 10 | switch (action.type) { 11 | case connTypes.CONNECTION_REQUEST: 12 | return 'Connecting to database...'; 13 | case connTypes.CONNECTION_SUCCESS: 14 | return 'Connection to database established'; 15 | case tablesTypes.FETCH_TABLES_REQUEST: 16 | return 'Loading list of tables...'; 17 | case queriesTypes.EXECUTE_QUERY_REQUEST: 18 | return 'Executing query...'; 19 | case queriesTypes.SAVE_QUERY_REQUEST: 20 | return 'Saving query...'; 21 | case queriesTypes.SAVE_QUERY_SUCCESS: 22 | return 'Query saved successfully'; 23 | case queriesTypes.SAVE_QUERY_FAILURE: 24 | return `Error saving query. ${action.error}`; 25 | default: 26 | return INITIAL_STATE; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/bs/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import config from './config'; 3 | import databases from './databases'; 4 | import servers from './servers'; 5 | import queries from './queries'; 6 | import connections from './connections'; 7 | import schemas from './schemas'; 8 | import tables from './tables'; 9 | import status from './status'; 10 | import views from './views'; 11 | import routines from './routines'; 12 | import columns from './columns'; 13 | import triggers from './triggers'; 14 | import indexes from './indexes'; 15 | import sqlscripts from './sqlscripts'; 16 | import keys from './keys'; 17 | import tableEdit from './tableEdit'; 18 | 19 | 20 | const rootReducer = combineReducers({ 21 | config, 22 | databases, 23 | servers, 24 | queries, 25 | connections, 26 | schemas, 27 | tables, 28 | status, 29 | views, 30 | routines, 31 | columns, 32 | triggers, 33 | indexes, 34 | sqlscripts, 35 | keys, 36 | tableEdit, 37 | }); 38 | 39 | 40 | export default rootReducer; 41 | -------------------------------------------------------------------------------- /src/mui/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import config from './config'; 3 | import databases from './databases'; 4 | import servers from './servers'; 5 | import queries from './queries'; 6 | import connections from './connections'; 7 | import schemas from './schemas'; 8 | import tables from './tables'; 9 | import status from './status'; 10 | import views from './views'; 11 | import routines from './routines'; 12 | import columns from './columns'; 13 | import triggers from './triggers'; 14 | import indexes from './indexes'; 15 | import sqlscripts from './sqlscripts'; 16 | import keys from './keys'; 17 | import tableEdit from './tableEdit'; 18 | 19 | 20 | const rootReducer = combineReducers({ 21 | config, 22 | databases, 23 | servers, 24 | queries, 25 | connections, 26 | schemas, 27 | tables, 28 | status, 29 | views, 30 | routines, 31 | columns, 32 | triggers, 33 | indexes, 34 | sqlscripts, 35 | keys, 36 | tableEdit, 37 | }); 38 | 39 | 40 | export default rootReducer; 41 | -------------------------------------------------------------------------------- /src/semantic1/components/loader.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import { Dimmer, Loader, Segment } from 'semantic-ui-react'; 4 | export default class Loading extends Component { 5 | state = { active: false }; 6 | static propTypes = { 7 | message: PropTypes.string, 8 | type: PropTypes.string, 9 | inverted: PropTypes.bool, 10 | }; 11 | 12 | componentDidMount() { 13 | //$(this.refs.loader).dimmer('show'); 14 | this.setState({ active: true }); 15 | } 16 | 17 | componentWillUnmount() { 18 | //$(this.refs.loader).dimmer('hide'); 19 | this.setState({ active: false }); 20 | } 21 | 22 | render() { 23 | const { message } = this.props; 24 | //const inverted = this.props.inverted ? 'inverted' : ''; 25 | return ( 26 | 27 | 28 | {message} 29 | 30 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/bs/components/database-diagram.css: -------------------------------------------------------------------------------- 1 | /* Disable removing links between objects */ 2 | .link-tools .tool-remove { 3 | display: none 4 | } 5 | 6 | /* Make custom element appear above jointjs generic rect */ 7 | .sqlectron-table, .sqlectron-table-cell { 8 | position: absolute; 9 | /* Make sure events are propagated to the JointJS element so, e.g. dragging works.*/ 10 | pointer-events: none; 11 | -webkit-user-select: none; 12 | z-index: 2; 13 | } 14 | 15 | .sqlectron-table { 16 | border-radius: 4px; 17 | border: 2px solid; 18 | box-shadow: inset 0 0 1px black, 1px 1px 1px gray; 19 | padding: 5px; 20 | } 21 | 22 | .sqlectron-table p { 23 | font-size: 14px; 24 | font-weight: bold; 25 | text-align: center; 26 | background-color: rgba(34, 36, 38, 0.15); 27 | } 28 | 29 | .sqlectron-table-cell { 30 | margin: 0 7px 0 7px; 31 | } 32 | 33 | /* Disable disconnecting links from elements */ 34 | .marker-arrowheads { 35 | display: none 36 | } 37 | 38 | .ui.simple.upward.dropdown > .menu { 39 | top: auto !important; 40 | } 41 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* eslint global-require:0, no-var: 0, no-extend-native: 0, vars-on-top: 0 */ 2 | // var config = require('./config'); 3 | 4 | // var configData = config.get(); 5 | 6 | // if (configData.printVersion) { 7 | // //console.log(configData.name, configData.version); // eslint-disable-line no-console 8 | // process.exit(0); 9 | // } 10 | const {ipcMain} = require('electron') 11 | // ipcMain.on('asynchronous-message', (event, arg) => { 12 | // console.log(arg) // prints "ping" 13 | // event.sender.send('asynchronous-reply', 'pong') 14 | // }) 15 | 16 | // ipcMain.on('getconfig', (event, arg) => { 17 | // //console.log(arg) // prints "ping" 18 | // var configData = config.get(arg); 19 | // event.returnValue = configData; 20 | // }) 21 | ipcMain.on('getpath', (event, arg) => { 22 | event.returnValue = __dirname; 23 | }) 24 | // enables ES6+ support 25 | //if (configData.devMode) { 26 | // require('babel-register'); 27 | //} 28 | 29 | //require('babel-polyfill'); 30 | 31 | // starts the electron app 32 | require('./app_main'); 33 | -------------------------------------------------------------------------------- /src/mui/components/EditModal.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import Dialog from '@mui/material/Dialog'; 4 | import DialogTitle from '@mui/material/DialogTitle'; 5 | import DialogContent from '@mui/material/DialogContent'; 6 | import DialogActions from '@mui/material/DialogActions'; 7 | export default function PreviewModal(props){ 8 | return ( 9 | 15 | Content Preview 16 | 17 |

{props.pos.row}

18 |

{props.pos.col}

19 |
20 | 21 |
26 | Close 27 |
28 |
29 |
30 | ); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/semantic1/components/collapse-icon.jsx: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | import React from 'react'; 6 | import PropTypes from 'proptypes'; 7 | const CollapseIcon = ({ arrowDirection }) => ( 8 | 12 | ); 13 | 14 | CollapseIcon.propTypes = { 15 | arrowDirection: PropTypes.string.isRequired, 16 | }; 17 | 18 | export default CollapseIcon; 19 | <<<<<<< HEAD 20 | ======= 21 | ======= 22 | import React from 'react'; 23 | import PropTypes from 'proptypes'; 24 | const CollapseIcon = ({ arrowDirection }) => ( 25 | 29 | ); 30 | 31 | CollapseIcon.propTypes = { 32 | arrowDirection: PropTypes.string.isRequired, 33 | }; 34 | 35 | export default CollapseIcon; 36 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 37 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 38 | -------------------------------------------------------------------------------- /src/semantic1/components/checkbox.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | //import {Input} from 'semantic-ui-react'; 4 | import { Checkbox } from 'semantic-ui-react'; 5 | export default class CheckboxMe extends Component { 6 | static propTypes = { 7 | name: PropTypes.string.isRequired, 8 | label: PropTypes.string.isRequired, 9 | disabled: PropTypes.bool, 10 | defaultChecked: PropTypes.bool, 11 | onChecked: PropTypes.func.isRequired, 12 | onUnchecked: PropTypes.func.isRequired, 13 | }; 14 | onChange = () => { 15 | if (!this.props.defaultChecked) { 16 | this.props.onChecked(); 17 | } else { 18 | this.props.onUnchecked(); 19 | } 20 | }; 21 | render() { 22 | const { name, label, disabled } = this.props; 23 | return ( 24 | 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | 4 | return { 5 | highlightCode:false, 6 | presets: [ 7 | ['@babel/preset-env',{targets: { electron: '3.0' }}], 8 | ], 9 | plugins: [ 10 | '@babel/plugin-syntax-jsx', 11 | '@babel/plugin-transform-react-jsx', 12 | '@babel/plugin-transform-react-display-name', 13 | '@babel/plugin-proposal-class-properties', 14 | '@babel/plugin-transform-react-jsx-self', 15 | '@babel/plugin-transform-react-jsx-source', 16 | '@babel/plugin-transform-flow-strip-types', 17 | "@babel/plugin-proposal-export-default-from", 18 | '@babel/plugin-proposal-export-namespace-from', 19 | "@babel/plugin-proposal-logical-assignment-operators", 20 | ["@babel/plugin-proposal-optional-chaining", { "loose": false }], 21 | ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }], 22 | ["@babel/plugin-proposal-nullish-coalescing-operator", { "loose": false }], 23 | "@babel/plugin-proposal-do-expressions", 24 | ] 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /src/bs/components/checkbox.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | // import Checkbox from '@material-ui/core/Checkbox'; 4 | import {Form} from "react-bootstrap" 5 | export default class CheckboxMe extends Component { 6 | static propTypes = { 7 | name: PropTypes.string.isRequired, 8 | label: PropTypes.string.isRequired, 9 | disabled: PropTypes.bool, 10 | defaultChecked: PropTypes.bool, 11 | onChecked: PropTypes.func.isRequired, 12 | onUnchecked: PropTypes.func.isRequired, 13 | }; 14 | onChange = () => { 15 | if (!this.props.defaultChecked) { 16 | this.props.onChecked(); 17 | } else { 18 | this.props.onUnchecked(); 19 | } 20 | }; 21 | render() { 22 | const { name, label, disabled } = this.props; 23 | //todo 24 | return ( 25 | 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/_no-query.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-no-query($query) { 6 | @if type-of($query) == 'list' { 7 | $keyword: nth($query, 1); 8 | 9 | @if type-of($keyword) == 'string' and ($keyword == 'no-query' or $keyword == 'no query' or $keyword == 'fallback') { 10 | @return nth($query, 2); 11 | } 12 | @else { 13 | @return false; 14 | } 15 | } 16 | @else { 17 | @return false; 18 | } 19 | } 20 | <<<<<<< HEAD 21 | ======= 22 | ======= 23 | @function breakpoint-no-query($query) { 24 | @if type-of($query) == 'list' { 25 | $keyword: nth($query, 1); 26 | 27 | @if type-of($keyword) == 'string' and ($keyword == 'no-query' or $keyword == 'no query' or $keyword == 'fallback') { 28 | @return nth($query, 2); 29 | } 30 | @else { 31 | @return false; 32 | } 33 | } 34 | @else { 35 | @return false; 36 | } 37 | } 38 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 39 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 40 | -------------------------------------------------------------------------------- /c1.js: -------------------------------------------------------------------------------- 1 | const cloneDeep =require('lodash.clonedeep'); 2 | const sqlectron = require('sqlectron-core'); 3 | console.log(sqlectron); 4 | //sqlectron.servers.getAll(); 5 | //console.log(sqlectron.db.CLIENTS.length); 6 | //console.log(sqlectron.db.CLIENTS); 7 | var serverConfig={client:"sqlite"} 8 | var db=sqlectron.db.createServer(serverConfig); 9 | //console.log(db); 10 | var con=db.createConnection("/home/mhq/python/parts/data.sqlite") 11 | console.log(con); 12 | async function getContacts(){ 13 | let results= await con.executeQuery("select * from parts_contact;"); 14 | //.then((data)=>{ 15 | // for(var i in data){ 16 | // console.log(i); 17 | // } 18 | // con.executeQuery("insert into ma(id) values(1);"); 19 | // var ts=con.listTables().then((data)=>{ 20 | // console.log(data); 21 | // }); 22 | //}); 23 | //const results = cloneDeep(remoteResult); 24 | console.log("results:"+results); 25 | for(var i in results){ 26 | console.log(i,results[i]); 27 | } 28 | } 29 | con.connect().then(()=>{ 30 | console.log("connected"); 31 | getContacts(); 32 | }); 33 | //con.executeQuery("create table ma(id int)"); -------------------------------------------------------------------------------- /src/Counter.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { act } from 'react-dom/test-utils'; 4 | import Counter from './Counter'; 5 | 6 | let container; 7 | 8 | beforeEach(() => { 9 | container = document.createElement('div'); 10 | document.body.appendChild(container); 11 | }); 12 | 13 | afterEach(() => { 14 | document.body.removeChild(container); 15 | container = null; 16 | }); 17 | 18 | it('can render and update a counter', () => { 19 | // Test first render and componentDidMount 20 | act(() => { 21 | ReactDOM.render(, container); 22 | }); 23 | const button = container.querySelector('button'); 24 | const label = container.querySelector('p'); 25 | expect(label.textContent).toBe('You clicked 0 times'); 26 | expect(document.title).toBe('You clicked 0 times'); 27 | 28 | // Test second render and componentDidUpdate 29 | act(() => { 30 | button.dispatchEvent(new MouseEvent('click', {bubbles: true})); 31 | }); 32 | expect(label.textContent).toBe('You clicked 1 times'); 33 | expect(document.title).toBe('You clicked 1 times'); 34 | }); -------------------------------------------------------------------------------- /src/bs/containers/react-tabs.css: -------------------------------------------------------------------------------- 1 | .react-tabs__tab-list { 2 | border-bottom: 1px solid #aaa; 3 | margin: 0 0 10px; 4 | padding: 0; 5 | } 6 | 7 | .react-tabs__tab { 8 | display: inline-block; 9 | border: 1px solid transparent; 10 | border-bottom: none; 11 | bottom: -1px; 12 | position: relative; 13 | list-style: none; 14 | padding: 6px 12px; 15 | cursor: pointer; 16 | } 17 | 18 | .react-tabs__tab--selected { 19 | background: #fff; 20 | border-color: #aaa; 21 | color: black; 22 | border-radius: 5px 5px 0 0; 23 | } 24 | 25 | .react-tabs__tab--disabled { 26 | color: GrayText; 27 | cursor: default; 28 | } 29 | 30 | .react-tabs__tab:focus { 31 | box-shadow: 0 0 5px hsl(208, 99%, 50%); 32 | border-color: hsl(208, 99%, 50%); 33 | outline: none; 34 | } 35 | 36 | .react-tabs__tab:focus:after { 37 | content: ""; 38 | position: absolute; 39 | height: 5px; 40 | left: -4px; 41 | right: -4px; 42 | bottom: -5px; 43 | background: #fff; 44 | } 45 | 46 | .react-tabs__tab-panel { 47 | display: none; 48 | } 49 | 50 | .react-tabs__tab-panel--selected { 51 | display: block; 52 | } 53 | -------------------------------------------------------------------------------- /src/mui/containers/react-tabs.css: -------------------------------------------------------------------------------- 1 | .react-tabs__tab-list { 2 | border-bottom: 1px solid #aaa; 3 | margin: 0 0 10px; 4 | padding: 0; 5 | } 6 | 7 | .react-tabs__tab { 8 | display: inline-block; 9 | border: 1px solid transparent; 10 | border-bottom: none; 11 | bottom: -1px; 12 | position: relative; 13 | list-style: none; 14 | padding: 6px 12px; 15 | cursor: pointer; 16 | } 17 | 18 | .react-tabs__tab--selected { 19 | background: #fff; 20 | border-color: #aaa; 21 | color: black; 22 | border-radius: 5px 5px 0 0; 23 | } 24 | 25 | .react-tabs__tab--disabled { 26 | color: GrayText; 27 | cursor: default; 28 | } 29 | 30 | .react-tabs__tab:focus { 31 | box-shadow: 0 0 5px hsl(208, 99%, 50%); 32 | border-color: hsl(208, 99%, 50%); 33 | outline: none; 34 | } 35 | 36 | .react-tabs__tab:focus:after { 37 | content: ""; 38 | position: absolute; 39 | height: 5px; 40 | left: -4px; 41 | right: -4px; 42 | bottom: -5px; 43 | background: #fff; 44 | } 45 | 46 | .react-tabs__tab-panel { 47 | display: none; 48 | } 49 | 50 | .react-tabs__tab-panel--selected { 51 | display: block; 52 | } 53 | -------------------------------------------------------------------------------- /src/semantic1/containers/query-browser.css: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | #sidebar { overflow-y: hidden; overflow-x: hidden; } 6 | #sidebar ::-webkit-scrollbar{ display:none } 7 | 8 | #sidebar:hover { overflow-y:auto; overflow-y:overlay } 9 | #sidebar:hover ::-webkit-scrollbar { display:block } 10 | 11 | #sidebar ::-webkit-scrollbar { -webkit-appearance:none } 12 | #sidebar ::-webkit-scrollbar-thumb { 13 | box-shadow: inset 0 -2px,inset 0 -8px,inset 0 2px,inset 0 8px; 14 | min-height: 36px 15 | } 16 | 17 | <<<<<<< HEAD 18 | ======= 19 | ======= 20 | #sidebar { overflow-y: hidden; overflow-x: hidden; } 21 | #sidebar ::-webkit-scrollbar{ display:none } 22 | 23 | #sidebar:hover { overflow-y:auto; overflow-y:overlay } 24 | #sidebar:hover ::-webkit-scrollbar { display:block } 25 | 26 | #sidebar ::-webkit-scrollbar { -webkit-appearance:none } 27 | #sidebar ::-webkit-scrollbar-thumb { 28 | box-shadow: inset 0 -2px,inset 0 -8px,inset 0 2px,inset 0 8px; 29 | min-height: 36px 30 | } 31 | 32 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 33 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 34 | -------------------------------------------------------------------------------- /merge.txt: -------------------------------------------------------------------------------- 1 | CONFLICT (content): Merge conflict in src/semantic1/containers/query-browser.jsx 2 | Auto-merging src/semantic1/containers/app.jsx 3 | CONFLICT (content): Merge conflict in src/semantic1/containers/app.jsx 4 | CONFLICT (rename/delete): src/AppTabs.js deleted in c75557ecfd5a5c0c0d9b9769b6a721e52e7f3e26 5 | 1/containers/app.css in HEAD. Version HEAD of src/semantic1/containers/app.css left in tree. 6 | 7 | CONFLICT (rename/delete): src/containers/query-browser-l.js deleted in c75557ecfd 8 | med to src/mui/containers/query-browser-l.js in HEAD. Version HEAD of src/mui/con 9 | 10 | CONFLICT (content): Merge conflict in src/index_local.js 11 | CONFLICT (rename/delete): src/components/Elem.js deleted in HEAD and renamed to src/containers/Elem.js in c75 12 | 0c0d9b9769b6a721e52e7f3e26. Version c75557ecfd5a5c0c0d9b9769b6a721e52e7f3e26 of src/containers/Elem.js left i 13 | CONFLICT (rename/delete): src/components/Ace.js deleted in HEAD and renamed to src/containers/Ace.js in c7555 14 | 0d9b9769b6a721e52e7f3e26. Version c75557ecfd5a5c0c0d9b9769b6a721e52e7f3e26 of src/containers/Ace.js left in t 15 | Removing src/boot.js 16 | Automatic merge failed; fix conflicts and then commit the result. -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/single/_default.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-parse-default($feature) { 6 | $default: breakpoint-get('default feature'); 7 | 8 | // Set Context 9 | $context-setter: private-breakpoint-set-context($default, $feature); 10 | 11 | @if (breakpoint-get('to ems') == true) and (type-of($feature) == 'number') { 12 | @return '#{$default}: #{breakpoint-to-base-em($feature)}'; 13 | } 14 | @else { 15 | @return '#{$default}: #{$feature}'; 16 | } 17 | } 18 | <<<<<<< HEAD 19 | ======= 20 | ======= 21 | @function breakpoint-parse-default($feature) { 22 | $default: breakpoint-get('default feature'); 23 | 24 | // Set Context 25 | $context-setter: private-breakpoint-set-context($default, $feature); 26 | 27 | @if (breakpoint-get('to ems') == true) and (type-of($feature) == 'number') { 28 | @return '#{$default}: #{breakpoint-to-base-em($feature)}'; 29 | } 30 | @else { 31 | @return '#{$default}: #{$feature}'; 32 | } 33 | } 34 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 35 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 36 | -------------------------------------------------------------------------------- /src/bs/containers/ModalEdit.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogTitle from '@material-ui/core/DialogTitle'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogActions from '@material-ui/core/DialogActions'; 6 | // var {electron}=window.myremote;// 7 | export default class App extends React.Component{ 8 | onClick=()=>{ 9 | } 10 | render=()=>{ 11 | console.log(this.props); 12 | return 17 | Edit Table 18 | 19 |
database name:{this.props.database.name},table:{this.props.item.name}
20 | 21 | 22 | 23 | 24 |
25 |
26 | 27 | 30 | 31 |
; 32 | } 33 | } -------------------------------------------------------------------------------- /app_main.js: -------------------------------------------------------------------------------- 1 | var { app, dialog } =require('electron'); // eslint-disable-line import/no-unresolved 2 | var createLogger =require('./logger'); 3 | var { buildNewWindow } =require('./window'); 4 | 5 | const logger = createLogger('app'); 6 | 7 | // TODO: Create a server to receive the crash reports 8 | // Report crashes to our server. 9 | // require('crash-reporter').start({ 10 | // productName: 'Sqlectron', 11 | // companyName: 'Sqlectron', 12 | // submitURL: 'https://your-domain.com/url-to-submit', 13 | // autoSubmit: true 14 | // }); 15 | 16 | app.allowRendererProcessReuse=false; 17 | // Quit when all windows are closed. 18 | app.on('window-all-closed', () => { 19 | if (process.platform !== 'darwin') { 20 | app.quit(); 21 | } 22 | }); 23 | 24 | 25 | // This method will be called when Electron has done everything 26 | // initialization and ready for creating browser windows. 27 | app.on('ready', () => buildNewWindow(app)); 28 | 29 | 30 | // Show only the error description to the user 31 | process.on('uncaughtException', error => { 32 | logger.error('uncaughtException', error); 33 | return dialog.showErrorBox('An error occurred', error.name + ': ' + error.message); 34 | }); 35 | -------------------------------------------------------------------------------- /src/bs/components/message.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | export default class Message extends Component { 4 | static propTypes = { 5 | closeable: PropTypes.bool, 6 | type: PropTypes.string, 7 | title: PropTypes.string, 8 | message: PropTypes.string, 9 | preformatted: PropTypes.bool, 10 | }; 11 | constructor() { 12 | super(); 13 | this.state = { visible: true }; 14 | } 15 | onClose() { 16 | //$(this.refs.message).transition('fade'); 17 | this.setState({ visible: false }); 18 | } 19 | 20 | render() { 21 | const { closeable, title, message, type, preformatted } = this.props; 22 | var classtype = `ui message ${type || ''}`; 23 | return ( 24 |
25 |
26 | {closeable && ( 27 | 28 | )} 29 | {title &&
{title}
} 30 | {message && preformatted ?
{message}
:

{message}

} 31 |
32 |
33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/bs/components/database-filter.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | 4 | export default class DatabaseFilter extends Component { 5 | static propTypes = { 6 | value: PropTypes.string, 7 | placeholder: PropTypes.string, 8 | isFetching: PropTypes.bool.isRequired, 9 | onFilterChange: PropTypes.func.isRequired, 10 | }; 11 | 12 | onFilterChange(event) { 13 | this.props.onFilterChange(event.target.value); 14 | } 15 | 16 | focus() { 17 | this.refs.searchInput.focus(); 18 | } 19 | 20 | render() { 21 | //console.log("render DatabaseFilter"); 22 | //console.log(this.props); 23 | 24 | var { value, placeholder, isFetching } = this.props; 25 | if (!value) value = ''; 26 | return ( 27 |
28 | 36 | 37 |
38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/bs/actions/views.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_VIEWS_REQUEST = 'FETCH_VIEWS_REQUEST'; 5 | export const FETCH_VIEWS_SUCCESS = 'FETCH_VIEWS_SUCCESS'; 6 | export const FETCH_VIEWS_FAILURE = 'FETCH_VIEWS_FAILURE'; 7 | 8 | 9 | export function fetchViewsIfNeeded (database, filter) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchViews(getState(), database)) { 12 | dispatch(fetchViews(database, filter)); 13 | } 14 | }; 15 | } 16 | 17 | function shouldFetchViews (state, database) { 18 | const views = state.views; 19 | if (!views) return true; 20 | if (views.isFetching) return false; 21 | if (!views.viewsByDatabase[database]) return true; 22 | return views.didInvalidate; 23 | } 24 | 25 | function fetchViews (database, filter) { 26 | return async (dispatch, getState) => { 27 | dispatch({ type: FETCH_VIEWS_REQUEST, database }); 28 | try { 29 | const dbConn = getCurrentDBConn(getState()); 30 | const views = await dbConn.listViews(filter); 31 | dispatch({ type: FETCH_VIEWS_SUCCESS, database, views }); 32 | } catch (error) { 33 | dispatch({ type: FETCH_VIEWS_FAILURE, error }); 34 | } 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/mui/actions/views.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_VIEWS_REQUEST = 'FETCH_VIEWS_REQUEST'; 5 | export const FETCH_VIEWS_SUCCESS = 'FETCH_VIEWS_SUCCESS'; 6 | export const FETCH_VIEWS_FAILURE = 'FETCH_VIEWS_FAILURE'; 7 | 8 | 9 | export function fetchViewsIfNeeded (database, filter) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchViews(getState(), database)) { 12 | dispatch(fetchViews(database, filter)); 13 | } 14 | }; 15 | } 16 | 17 | function shouldFetchViews (state, database) { 18 | const views = state.views; 19 | if (!views) return true; 20 | if (views.isFetching) return false; 21 | if (!views.viewsByDatabase[database]) return true; 22 | return views.didInvalidate; 23 | } 24 | 25 | function fetchViews (database, filter) { 26 | return async (dispatch, getState) => { 27 | dispatch({ type: FETCH_VIEWS_REQUEST, database }); 28 | try { 29 | const dbConn = getCurrentDBConn(getState()); 30 | const views = await dbConn.listViews(filter); 31 | dispatch({ type: FETCH_VIEWS_SUCCESS, database, views }); 32 | } catch (error) { 33 | dispatch({ type: FETCH_VIEWS_FAILURE, error }); 34 | } 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/mui/components/server-filter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import debounce from 'lodash.debounce'; 4 | import Button from '@mui/material/Button'; 5 | import Toolbar from '@mui/material/Toolbar'; 6 | import IconButton from '@mui/material/IconButton'; 7 | import TextField from '@mui/material/TextField'; 8 | import SearchIcon from '@mui/icons-material/Search'; 9 | let delayedCallback=null; 10 | export default function ServerFilter(props){ 11 | React.useEffect(()=>{ 12 | delayedCallback = debounce(props.onFilterChange, 200); 13 | },[]); 14 | 15 | 16 | const onFilterChange=(event)=> { 17 | event.persist(); 18 | delayedCallback(event); 19 | } 20 | return ( 21 | 22 | 23 | 28 | 31 | 37 | 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/bs/actions/schemas.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_SCHEMAS_REQUEST = 'FETCH_SCHEMAS_REQUEST'; 5 | export const FETCH_SCHEMAS_SUCCESS = 'FETCH_SCHEMAS_SUCCESS'; 6 | export const FETCH_SCHEMAS_FAILURE = 'FETCH_SCHEMAS_FAILURE'; 7 | 8 | export function fetchSchemasIfNeeded (database) { 9 | return (dispatch, getState) => { 10 | if (shouldFetchSchemas(getState(), database)) { 11 | dispatch(fetchSchemas(database)); 12 | } 13 | }; 14 | } 15 | 16 | 17 | function shouldFetchSchemas (state, database) { 18 | const schemas = state.schemas; 19 | if (!schemas) return true; 20 | if (schemas.isFetching) return false; 21 | if (!schemas.itemsByDatabase[database]) return true; 22 | return schemas.didInvalidate; 23 | } 24 | 25 | 26 | function fetchSchemas (database) { 27 | return async (dispatch, getState) => { 28 | dispatch({ type: FETCH_SCHEMAS_REQUEST, database }); 29 | try { 30 | const dbConn = getCurrentDBConn(getState()); 31 | const schemas = await dbConn.listSchemas(); 32 | dispatch({ type: FETCH_SCHEMAS_SUCCESS, database, schemas }); 33 | } catch (error) { 34 | dispatch({ type: FETCH_SCHEMAS_FAILURE, error }); 35 | } 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/mui/actions/schemas.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_SCHEMAS_REQUEST = 'FETCH_SCHEMAS_REQUEST'; 5 | export const FETCH_SCHEMAS_SUCCESS = 'FETCH_SCHEMAS_SUCCESS'; 6 | export const FETCH_SCHEMAS_FAILURE = 'FETCH_SCHEMAS_FAILURE'; 7 | 8 | export function fetchSchemasIfNeeded (database) { 9 | return (dispatch, getState) => { 10 | if (shouldFetchSchemas(getState(), database)) { 11 | dispatch(fetchSchemas(database)); 12 | } 13 | }; 14 | } 15 | 16 | 17 | function shouldFetchSchemas (state, database) { 18 | const schemas = state.schemas; 19 | if (!schemas) return true; 20 | if (schemas.isFetching) return false; 21 | if (!schemas.itemsByDatabase[database]) return true; 22 | return schemas.didInvalidate; 23 | } 24 | 25 | 26 | function fetchSchemas (database) { 27 | return async (dispatch, getState) => { 28 | dispatch({ type: FETCH_SCHEMAS_REQUEST, database }); 29 | try { 30 | const dbConn = getCurrentDBConn(getState()); 31 | const schemas = await dbConn.listSchemas(); 32 | dispatch({ type: FETCH_SCHEMAS_SUCCESS, database, schemas }); 33 | } catch (error) { 34 | dispatch({ type: FETCH_SCHEMAS_FAILURE, error }); 35 | } 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/_double.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "double/default-pair"; 5 | @import "double/double-string"; 6 | @import "double/default"; 7 | 8 | @function breakpoint-parse-double($feature, $empty-media, $first) { 9 | $parsed: ''; 10 | $leader: ''; 11 | // If we're forcing 12 | @if not ($empty-media) or not ($first) { 13 | $leader: 'and '; 14 | } 15 | 16 | $first: nth($feature, 1); 17 | $second: nth($feature, 2); 18 | 19 | // If we've got two numbers, we know we need to use the default pair because there are no media queries that has a media feature that is a number 20 | @if type-of($first) == 'number' and type-of($second) == 'number' { 21 | $parsed: breakpoint-parse-default-pair($first, $second); 22 | } 23 | // If they are both strings, we send it through the string parser 24 | @else if type-of($first) == 'string' and type-of($second) == 'string' { 25 | $parsed: breakpoint-parse-double-string($first, $second); 26 | } 27 | // If it's a string/number pair, we parse it as a normal double 28 | @else { 29 | $parsed: breakpoint-parse-double-default($first, $second); 30 | } 31 | 32 | @return $leader + $parsed; 33 | } 34 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/_double.scss: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Import Pieces 3 | ////////////////////////////// 4 | @import "double/default-pair"; 5 | @import "double/double-string"; 6 | @import "double/default"; 7 | 8 | @function breakpoint-parse-double($feature, $empty-media, $first) { 9 | $parsed: ''; 10 | $leader: ''; 11 | // If we're forcing 12 | @if not ($empty-media) or not ($first) { 13 | $leader: 'and '; 14 | } 15 | 16 | $first: nth($feature, 1); 17 | $second: nth($feature, 2); 18 | 19 | // If we've got two numbers, we know we need to use the default pair because there are no media queries that has a media feature that is a number 20 | @if type-of($first) == 'number' and type-of($second) == 'number' { 21 | $parsed: breakpoint-parse-default-pair($first, $second); 22 | } 23 | // If they are both strings, we send it through the string parser 24 | @else if type-of($first) == 'string' and type-of($second) == 'string' { 25 | $parsed: breakpoint-parse-double-string($first, $second); 26 | } 27 | // If it's a string/number pair, we parse it as a normal double 28 | @else { 29 | $parsed: breakpoint-parse-double-default($first, $second); 30 | } 31 | 32 | @return $leader + $parsed; 33 | } 34 | -------------------------------------------------------------------------------- /logger.js: -------------------------------------------------------------------------------- 1 | const path=require("path") 2 | var sqlectron =require('sqlectron-core'); 3 | var config =require(path.join(__dirname,'config.js')); 4 | 5 | // Hack solution to ignore console.error from dtrace imported by bunyan 6 | /* eslint no-console:0 */ 7 | const realConsoleError = console.error; 8 | console.error = () => {}; 9 | const { createLogger } = require('bunyan'); 10 | console.error = realConsoleError; 11 | 12 | 13 | const dataConfig = config.get(); 14 | 15 | const loggerConfig = { 16 | app: 'sqlectron-gui', 17 | name: 'sqlectron-gui', 18 | level: dataConfig.log.level.value, 19 | streams: [], 20 | }; 21 | 22 | if (dataConfig.log.console) { 23 | loggerConfig.streams.push({ stream: process.stdout }); 24 | } 25 | 26 | if (dataConfig.log.file) { 27 | loggerConfig.streams.push({ path: dataConfig.log.path }); 28 | } 29 | // console.log(loggerConfig); 30 | // console.log(loggerConfig.level); 31 | 32 | const logger = createLogger(loggerConfig); 33 | 34 | //Set custom logger for sqlectron-core 35 | sqlectron.setLogger((namespace) => logger.child({ namespace: `sqlectron-core:${namespace}` })); 36 | function mklog(namespace){ 37 | return logger.child({ namespace }); 38 | } 39 | module.exports=mklog; 40 | //export default (namespace) => console; 41 | -------------------------------------------------------------------------------- /src/semantic1/components/message.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import { Transition } from 'semantic-ui-react'; 4 | 5 | export default class Message extends Component { 6 | static propTypes = { 7 | closeable: PropTypes.bool, 8 | type: PropTypes.string, 9 | title: PropTypes.string, 10 | message: PropTypes.string, 11 | preformatted: PropTypes.bool, 12 | }; 13 | constructor() { 14 | super(); 15 | this.state = { visible: true }; 16 | } 17 | onClose() { 18 | //$(this.refs.message).transition('fade'); 19 | this.setState({ visible: false }); 20 | } 21 | 22 | render() { 23 | const { closeable, title, message, type, preformatted } = this.props; 24 | var classtype = `ui message ${type || ''}`; 25 | return ( 26 | 27 |
28 | {closeable && ( 29 | 30 | )} 31 | {title &&
{title}
} 32 | {message && preformatted ?
{message}
:

{message}

} 33 |
34 |
35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/semantic1/containers/ModalAbout.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {Button, Modal } from 'semantic-ui-react'; 3 | var {electron}=window.myremote;// 4 | var config=window.myremote.config.get(); 5 | // console.log(Modal); 6 | export default class App extends React.Component{ 7 | // constructor(props, context) { 8 | // super(props, context); 9 | // // console.log("constructor modal1"); 10 | // } 11 | onClick=()=>{ 12 | // console.log(electron.shell); 13 | electron.shell.openExternal(config.website); 14 | } 15 | render=()=>{ 16 | return 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Version:{config.version}
Author:{config.author.name}
email:{config.author.email}
website:{config.website}
26 |
27 | 28 | 31 | 32 |
; 33 | } 34 | } -------------------------------------------------------------------------------- /public/myremote.js: -------------------------------------------------------------------------------- 1 | // console.log(__dirname); 2 | // console.log(__filename); 3 | // console.log(process); 4 | 5 | var electron=require('electron'); 6 | // console.log(electron); 7 | window.myremote={ 8 | fs:require('fs'), 9 | path:require("path"), 10 | //sqlectron:require("sqlectron-core"), 11 | electron:electron, 12 | remote:electron.remote, 13 | ipcRenderer:electron.ipcRenderer, 14 | shell:electron.shell, 15 | webFrame:electron.webFrame, 16 | clipboard:electron.clipboard 17 | }; 18 | var cp=window.myremote.path.resolve(".") 19 | if (process.argv[0].indexOf("Sqlectron.exe")>0) 20 | { 21 | cp=cp+"/resources/app"; 22 | } 23 | console.log(cp); 24 | 25 | window.myremote.sqlectron=require(cp+"/core/lib"); 26 | window.myremote.createLogger=require(cp+"/logger.js"); 27 | window.myremote.config=require(cp+"/config.js"); 28 | // let configv=null; 29 | // let rconfig=require(cp+"/config.js"); 30 | // window.myremote.config ={ 31 | // get:function(){ 32 | // if (configv===null){ 33 | // configv=rconfig.get(); 34 | // } 35 | // else{ 36 | // return configv; 37 | // } 38 | // } 39 | // }//require(cp+"/config.js"); 40 | window.myremote.csvStringify=require('csv-stringify'); 41 | //console.log(window.myremote); 42 | //todo remove config,logger user ipc 43 | -------------------------------------------------------------------------------- /src/bs/components/react-tabs.scss: -------------------------------------------------------------------------------- 1 | 2 | .ReactTabs.react-tabs { 3 | width: 100%; 4 | position: relative; 5 | } 6 | 7 | .ReactTabs.react-tabs .ReactTabs__TabList { 8 | white-space: nowrap; 9 | } 10 | 11 | .ReactTabs.react-tabs .ReactTabs__TabList .ReactTabs__Tab { 12 | display: inline-block; 13 | } 14 | 15 | #tabs-nav-wrapper { 16 | display: flex; 17 | flex-direction: row; 18 | } 19 | 20 | #tabs-nav-wrapper > .tabs-container { 21 | flex: auto; 22 | overflow: hidden; 23 | position: relative; 24 | width: 100%; 25 | padding-bottom: 3px; 26 | } 27 | 28 | #tabs-nav-wrapper > .tabs-container > ul { 29 | position: relative; 30 | margin: 0; 31 | 32 | .item > .button { 33 | opacity: 0; 34 | transition: opacity .25s ease-in-out; 35 | font-size: 0.5em; 36 | margin: -0.5em -1em 0 1.5em; 37 | } 38 | 39 | .item.active:hover > .button { 40 | opacity: 1; 41 | } 42 | } 43 | 44 | #tabs-nav-wrapper > button { 45 | font-size: 0.75em; 46 | margin: 0; 47 | border-radius: 0; 48 | border-top-left-radius: 5px; 49 | border-top-right-radius: 5px; 50 | } 51 | 52 | #tabs-nav-wrapper button.right.floated.ui.icon.button.mini { 53 | font-size: 0.5em; 54 | margin-left: 0.5em; 55 | } 56 | 57 | .react-tabs #tabs-nav-wrapper [role=tablist] { 58 | border-bottom: none; 59 | } 60 | -------------------------------------------------------------------------------- /src/bs/actions/routines.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_ROUTINES_REQUEST = 'FETCH_ROUTINES_REQUEST'; 5 | export const FETCH_ROUTINES_SUCCESS = 'FETCH_ROUTINES_SUCCESS'; 6 | export const FETCH_ROUTINES_FAILURE = 'FETCH_ROUTINES_FAILURE'; 7 | 8 | 9 | export function fetchRoutinesIfNeeded (database, filter) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchRoutines(getState(), database)) { 12 | dispatch(fetchRoutines(database, filter)); 13 | } 14 | }; 15 | } 16 | 17 | function shouldFetchRoutines (state, database) { 18 | const routines = state.routines; 19 | if (!routines) return true; 20 | if (routines.isFetching) return false; 21 | if (!routines.functionsByDatabase[database]) return true; 22 | if (!routines.proceduresByDatabase[database]) return true; 23 | return routines.didInvalidate; 24 | } 25 | 26 | function fetchRoutines (database, filter) { 27 | return async (dispatch, getState) => { 28 | dispatch({ type: FETCH_ROUTINES_REQUEST, database }); 29 | try { 30 | const dbConn = getCurrentDBConn(getState()); 31 | const routines = await dbConn.listRoutines(filter); 32 | dispatch({ type: FETCH_ROUTINES_SUCCESS, database, routines }); 33 | } catch (error) { 34 | dispatch({ type: FETCH_ROUTINES_FAILURE, error }); 35 | } 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/mui/actions/routines.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_ROUTINES_REQUEST = 'FETCH_ROUTINES_REQUEST'; 5 | export const FETCH_ROUTINES_SUCCESS = 'FETCH_ROUTINES_SUCCESS'; 6 | export const FETCH_ROUTINES_FAILURE = 'FETCH_ROUTINES_FAILURE'; 7 | 8 | 9 | export function fetchRoutinesIfNeeded (database, filter) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchRoutines(getState(), database)) { 12 | dispatch(fetchRoutines(database, filter)); 13 | } 14 | }; 15 | } 16 | 17 | function shouldFetchRoutines (state, database) { 18 | const routines = state.routines; 19 | if (!routines) return true; 20 | if (routines.isFetching) return false; 21 | if (!routines.functionsByDatabase[database]) return true; 22 | if (!routines.proceduresByDatabase[database]) return true; 23 | return routines.didInvalidate; 24 | } 25 | 26 | function fetchRoutines (database, filter) { 27 | return async (dispatch, getState) => { 28 | dispatch({ type: FETCH_ROUTINES_REQUEST, database }); 29 | try { 30 | const dbConn = getCurrentDBConn(getState()); 31 | const routines = await dbConn.listRoutines(filter); 32 | dispatch({ type: FETCH_ROUTINES_SUCCESS, database, routines }); 33 | } catch (error) { 34 | dispatch({ type: FETCH_ROUTINES_FAILURE, error }); 35 | } 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/semantic1/components/EditModal.js: -------------------------------------------------------------------------------- 1 | // import isPlainObject from 'lodash.isplainobject'; 2 | import React, { Component } from 'react'; 3 | import PropTypes from 'proptypes'; 4 | // import classNames from 'classnames'; 5 | import { Modal } from 'semantic-ui-react'; 6 | 7 | export default class PreviewModal extends Component { 8 | static propTypes = { 9 | onCloseClick: PropTypes.func.isRequired, 10 | }; 11 | constructor(props, context) { 12 | super(props, context); 13 | this.state = {}; 14 | } 15 | 16 | render() { 17 | // const selected = this.state.selected || 'plain'; 18 | // const previewValue = this.getPreviewValue(selected); 19 | return ( 20 | 26 | Content Preview 27 | 28 |

{this.props.pos.row}

29 |

{this.props.pos.col}

30 |
31 | 32 |
37 | Close 38 |
39 |
40 |
41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/double/_default.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-parse-double-default($first, $second) { 6 | $feature: ''; 7 | $value: ''; 8 | 9 | @if type-of($first) == 'string' { 10 | $feature: $first; 11 | $value: $second; 12 | } 13 | @else { 14 | $feature: $second; 15 | $value: $first; 16 | } 17 | 18 | // Set Context 19 | $context-setter: private-breakpoint-set-context($feature, $value); 20 | 21 | @if (breakpoint-get('to ems') == true) { 22 | $value: breakpoint-to-base-em($value); 23 | } 24 | 25 | @return '(#{$feature}: #{$value})' 26 | } 27 | <<<<<<< HEAD 28 | ======= 29 | ======= 30 | @function breakpoint-parse-double-default($first, $second) { 31 | $feature: ''; 32 | $value: ''; 33 | 34 | @if type-of($first) == 'string' { 35 | $feature: $first; 36 | $value: $second; 37 | } 38 | @else { 39 | $feature: $second; 40 | $value: $first; 41 | } 42 | 43 | // Set Context 44 | $context-setter: private-breakpoint-set-context($feature, $value); 45 | 46 | @if (breakpoint-get('to ems') == true) { 47 | $value: breakpoint-to-base-em($value); 48 | } 49 | 50 | @return '(#{$feature}: #{$value})' 51 | } 52 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 53 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 54 | -------------------------------------------------------------------------------- /src/bs/actions/indexes.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_INDEXES_REQUEST = 'FETCH_INDEXES_REQUEST'; 5 | export const FETCH_INDEXES_SUCCESS = 'FETCH_INDEXES_SUCCESS'; 6 | export const FETCH_INDEXES_FAILURE = 'FETCH_INDEXES_FAILURE'; 7 | 8 | 9 | export function fetchTableIndexesIfNeeded (database, table) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableIndexes(getState(), database, table)) { 12 | dispatch(fetchTableIndexes(database, table)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableIndexes (state, database, table) { 19 | const indexes = state.indexes; 20 | if (!indexes) return true; 21 | if (indexes.isFetching) return false; 22 | if (!indexes.indexesByTable[database]) return true; 23 | if (!indexes.indexesByTable[database][table]) return true; 24 | return indexes.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableIndexes (database, table) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_INDEXES_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const indexes = await dbConn.listTableIndexes(table); 34 | dispatch({ type: FETCH_INDEXES_SUCCESS, database, table, indexes }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_INDEXES_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/mui/actions/indexes.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_INDEXES_REQUEST = 'FETCH_INDEXES_REQUEST'; 5 | export const FETCH_INDEXES_SUCCESS = 'FETCH_INDEXES_SUCCESS'; 6 | export const FETCH_INDEXES_FAILURE = 'FETCH_INDEXES_FAILURE'; 7 | 8 | 9 | export function fetchTableIndexesIfNeeded (database, table) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableIndexes(getState(), database, table)) { 12 | dispatch(fetchTableIndexes(database, table)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableIndexes (state, database, table) { 19 | const indexes = state.indexes; 20 | if (!indexes) return true; 21 | if (indexes.isFetching) return false; 22 | if (!indexes.indexesByTable[database]) return true; 23 | if (!indexes.indexesByTable[database][table]) return true; 24 | return indexes.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableIndexes (database, table) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_INDEXES_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const indexes = await dbConn.listTableIndexes(table); 34 | dispatch({ type: FETCH_INDEXES_SUCCESS, database, table, indexes }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_INDEXES_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/bs/actions/keys.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_KEYS_REQUEST = 'FETCH_KEYS_REQUEST'; 5 | export const FETCH_KEYS_SUCCESS = 'FETCH_KEYS_SUCCESS'; 6 | export const FETCH_KEYS_FAILURE = 'FETCH_KEYS_FAILURE'; 7 | 8 | 9 | export function fetchTableKeysIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableKeys(getState(), database, table)) { 12 | dispatch(fetchTableKeys(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableKeys (state, database, table) { 19 | const keys = state.keys; 20 | if (!keys) return true; 21 | if (keys.isFetching[database] && keys.isFetching[database][table]) return false; 22 | if (!keys.keysByTable[database]) return true; 23 | if (!keys.keysByTable[database][table]) return true; 24 | return keys.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableKeys (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_KEYS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const tableKeys = await dbConn.getTableKeys(table, schema); 34 | dispatch({ type: FETCH_KEYS_SUCCESS, database, table, tableKeys }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_KEYS_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/mui/actions/keys.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_KEYS_REQUEST = 'FETCH_KEYS_REQUEST'; 5 | export const FETCH_KEYS_SUCCESS = 'FETCH_KEYS_SUCCESS'; 6 | export const FETCH_KEYS_FAILURE = 'FETCH_KEYS_FAILURE'; 7 | 8 | 9 | export function fetchTableKeysIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableKeys(getState(), database, table)) { 12 | dispatch(fetchTableKeys(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableKeys (state, database, table) { 19 | const keys = state.keys; 20 | if (!keys) return true; 21 | if (keys.isFetching[database] && keys.isFetching[database][table]) return false; 22 | if (!keys.keysByTable[database]) return true; 23 | if (!keys.keysByTable[database][table]) return true; 24 | return keys.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableKeys (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_KEYS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const tableKeys = await dbConn.getTableKeys(table, schema); 34 | dispatch({ type: FETCH_KEYS_SUCCESS, database, table, tableKeys }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_KEYS_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/mui/components/confim-modal.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import Dialog from '@mui/material/Dialog'; 4 | import DialogTitle from '@mui/material/DialogTitle'; 5 | import DialogContent from '@mui/material/DialogContent'; 6 | import DialogActions from '@mui/material/DialogActions'; 7 | import Button from '@mui/material/Button'; 8 | import IconButton from '@mui/material/IconButton'; 9 | import CloseIcon from '@mui/icons-material/Close' 10 | import CheckIcon from '@mui/icons-material/Check' 11 | export default function ServerModalForm(props){ 12 | const { title, message } = props; 13 | return ( 14 | 20 | {title} 21 | {message} 22 | 23 | 27 | No 28 | 29 | 30 | 34 | Yes 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /src/bs/utils/file-handler.js: -------------------------------------------------------------------------------- 1 | var { fs }=window.myremote;// from '../../browser/remote'; 2 | var {remote}=window.myremote.electron; 3 | 4 | export function showSaveDialog(filters) { 5 | return new Promise((resolve, reject) => { 6 | remote.dialog.showSaveDialog({ 7 | filters, 8 | }, (fileName) => { 9 | if (fileName) { 10 | return resolve(fileName); 11 | } 12 | 13 | return reject(); 14 | }); 15 | }); 16 | } 17 | 18 | 19 | export function saveFile(fileName, data, encoding = 'utf8') { 20 | return new Promise((resolve, reject) => { 21 | fs.writeFile(fileName, data, encoding, err => { 22 | if (err) { return reject(err); } 23 | return resolve(); 24 | }); 25 | }); 26 | } 27 | 28 | 29 | export function showOpenDialog(filters, defaultPath) { 30 | return new Promise((resolve, reject) => { 31 | remote.dialog.showOpenDialog({ 32 | defaultPath, 33 | filters, 34 | properties: ['openFile'], 35 | }, (fileName) => { 36 | if (fileName) { 37 | return resolve(fileName); 38 | } 39 | 40 | return reject(); 41 | }); 42 | }); 43 | } 44 | 45 | 46 | export function openFile(fileName) { 47 | return new Promise((resolve, reject) => { 48 | fs.readFile(fileName, 'utf8', (err, data) => { 49 | if (err) { return reject(err); } 50 | return resolve(data); 51 | }); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /src/mui/utils/file-handler.js: -------------------------------------------------------------------------------- 1 | const { fs }=window.myremote;// from '../../browser/remote'; 2 | const remote=window.myremote.remote; 3 | 4 | export function showSaveDialog(filters) { 5 | return new Promise((resolve, reject) => { 6 | remote.dialog.showSaveDialogSync({ 7 | filters, 8 | }, (fileName) => { 9 | if (fileName) { 10 | return resolve(fileName); 11 | } 12 | 13 | return reject(); 14 | }); 15 | }); 16 | } 17 | 18 | 19 | export function saveFile(fileName, data, encoding = 'utf8') { 20 | return new Promise((resolve, reject) => { 21 | fs.writeFile(fileName, data, encoding, err => { 22 | if (err) { return reject(err); } 23 | return resolve(); 24 | }); 25 | }); 26 | } 27 | 28 | 29 | export function showOpenDialog(filters, defaultPath) { 30 | return new Promise((resolve, reject) => { 31 | remote.dialog.showOpenDialogSync({ 32 | defaultPath, 33 | filters, 34 | properties: ['openFile'], 35 | }, (fileName) => { 36 | if (fileName) { 37 | return resolve(fileName); 38 | } 39 | 40 | return reject(); 41 | }); 42 | }); 43 | } 44 | 45 | 46 | export function openFile(fileName) { 47 | return new Promise((resolve, reject) => { 48 | fs.readFile(fileName, 'utf8', (err, data) => { 49 | if (err) { return reject(err); } 50 | return resolve(data); 51 | }); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /src/semantic1/menu-handler.js: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | var { ipcRenderer } = window.myremote.electron; // 6 | 7 | export default class MenuHandler { 8 | setMenus(commands) { 9 | if (this.commands) { 10 | this.removeAllMenus(); 11 | } 12 | 13 | Object.keys(commands).forEach(command => 14 | ipcRenderer.on(command, commands[command]) 15 | ); 16 | 17 | this.commands = commands; 18 | } 19 | 20 | removeAllMenus() { 21 | Object.keys(this.commands).forEach(command => 22 | ipcRenderer.removeListener(command, this.commands[command]) 23 | ); 24 | 25 | this.commands = null; 26 | } 27 | } 28 | <<<<<<< HEAD 29 | ======= 30 | ======= 31 | var { ipcRenderer } = window.myremote.electron; // 32 | 33 | export default class MenuHandler { 34 | setMenus(commands) { 35 | if (this.commands) { 36 | this.removeAllMenus(); 37 | } 38 | 39 | Object.keys(commands).forEach(command => 40 | ipcRenderer.on(command, commands[command]) 41 | ); 42 | 43 | this.commands = commands; 44 | } 45 | 46 | removeAllMenus() { 47 | Object.keys(this.commands).forEach(command => 48 | ipcRenderer.removeListener(command, this.commands[command]) 49 | ); 50 | 51 | this.commands = null; 52 | } 53 | } 54 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 55 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 56 | -------------------------------------------------------------------------------- /src/bs/utils/convert.js: -------------------------------------------------------------------------------- 1 | export function rowsValuesToString(rows) { 2 | return rows.map(rowValuesToString); 3 | } 4 | 5 | 6 | export function rowValuesToString(row) { 7 | if (Array.isArray(row)) { 8 | return rowsValuesToString(row); 9 | } 10 | 11 | const parsedRow = {}; 12 | 13 | Object.keys(row).forEach((col) => { 14 | parsedRow[col] = valueToString(row[col]); 15 | }); 16 | 17 | return parsedRow; 18 | } 19 | 20 | 21 | export function valueToString(value) { 22 | if (value === null) { 23 | return 'NULL'; 24 | } 25 | 26 | if (typeof value === 'boolean') { 27 | return value.toString(); 28 | } 29 | 30 | if (!value) { 31 | return String(value); 32 | } 33 | 34 | if (value.toISOString) { 35 | return value.toISOString(); 36 | } 37 | 38 | if (typeof value === 'object') { 39 | if (isArrayBuffer(value)) { 40 | return arrayBufferToString(value); 41 | } 42 | 43 | return JSON.stringify(value); 44 | } 45 | 46 | return String(value); 47 | } 48 | 49 | function arrayBufferToString(buf) { 50 | if (buf.length === 1) { 51 | // Probably is a bit column 52 | return String(buf[0]); 53 | } 54 | return buf.toString('utf-8'); 55 | } 56 | 57 | // reference: 58 | // http://stackoverflow.com/a/21799845/1050818 59 | function isArrayBuffer(value) { 60 | return value && value.buffer instanceof ArrayBuffer && value.byteLength !== undefined; 61 | } 62 | -------------------------------------------------------------------------------- /src/bs/actions/triggers.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_TRIGGERS_REQUEST = 'FETCH_TRIGGERS_REQUEST'; 5 | export const FETCH_TRIGGERS_SUCCESS = 'FETCH_TRIGGERS_SUCCESS'; 6 | export const FETCH_TRIGGERS_FAILURE = 'FETCH_TRIGGERS_FAILURE'; 7 | 8 | 9 | export function fetchTableTriggersIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableTriggers(getState(), database, table)) { 12 | dispatch(fetchTableTriggers(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableTriggers (state, database, table) { 19 | const triggers = state.triggers; 20 | if (!triggers) return true; 21 | if (triggers.isFetching) return false; 22 | if (!triggers.triggersByTable[database]) return true; 23 | if (!triggers.triggersByTable[database][table]) return true; 24 | return triggers.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableTriggers (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_TRIGGERS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const triggers = await dbConn.listTableTriggers(table, schema); 34 | dispatch({ type: FETCH_TRIGGERS_SUCCESS, database, table, triggers }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_TRIGGERS_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/mui/utils/convert.js: -------------------------------------------------------------------------------- 1 | export function rowsValuesToString(rows) { 2 | return rows.map(rowValuesToString); 3 | } 4 | 5 | 6 | export function rowValuesToString(row) { 7 | if (Array.isArray(row)) { 8 | return rowsValuesToString(row); 9 | } 10 | 11 | const parsedRow = {}; 12 | 13 | Object.keys(row).forEach((col) => { 14 | parsedRow[col] = valueToString(row[col]); 15 | }); 16 | 17 | return parsedRow; 18 | } 19 | 20 | 21 | export function valueToString(value) { 22 | if (value === null) { 23 | return 'NULL'; 24 | } 25 | 26 | if (typeof value === 'boolean') { 27 | return value.toString(); 28 | } 29 | 30 | if (!value) { 31 | return String(value); 32 | } 33 | 34 | if (value.toISOString) { 35 | return value.toISOString(); 36 | } 37 | 38 | if (typeof value === 'object') { 39 | if (isArrayBuffer(value)) { 40 | return arrayBufferToString(value); 41 | } 42 | 43 | return JSON.stringify(value); 44 | } 45 | 46 | return String(value); 47 | } 48 | 49 | function arrayBufferToString(buf) { 50 | if (buf.length === 1) { 51 | // Probably is a bit column 52 | return String(buf[0]); 53 | } 54 | return buf.toString('utf-8'); 55 | } 56 | 57 | // reference: 58 | // http://stackoverflow.com/a/21799845/1050818 59 | function isArrayBuffer(value) { 60 | return value && value.buffer instanceof ArrayBuffer && value.byteLength !== undefined; 61 | } 62 | -------------------------------------------------------------------------------- /src/semantic1/components/server-filter.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import debounce from 'lodash.debounce'; 4 | 5 | export default class ServerFilter extends Component { 6 | static propTypes = { 7 | onFilterChange: PropTypes.func.isRequired, 8 | onAddClick: PropTypes.func.isRequired, 9 | onSettingsClick: PropTypes.func.isRequired, 10 | }; 11 | 12 | UNSAFE_componentWillMount() { 13 | this.delayedCallback = debounce(this.props.onFilterChange, 200); 14 | } 15 | 16 | onFilterChange(event) { 17 | event.persist(); 18 | this.delayedCallback(event); 19 | } 20 | 21 | render() { 22 | return ( 23 |
27 | 28 | 33 | 39 | 45 |
46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/mui/actions/triggers.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_TRIGGERS_REQUEST = 'FETCH_TRIGGERS_REQUEST'; 5 | export const FETCH_TRIGGERS_SUCCESS = 'FETCH_TRIGGERS_SUCCESS'; 6 | export const FETCH_TRIGGERS_FAILURE = 'FETCH_TRIGGERS_FAILURE'; 7 | 8 | 9 | export function fetchTableTriggersIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableTriggers(getState(), database, table)) { 12 | dispatch(fetchTableTriggers(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableTriggers (state, database, table) { 19 | const triggers = state.triggers; 20 | if (!triggers) return true; 21 | if (triggers.isFetching) return false; 22 | if (!triggers.triggersByTable[database]) return true; 23 | if (!triggers.triggersByTable[database][table]) return true; 24 | return triggers.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableTriggers (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_TRIGGERS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const triggers = await dbConn.listTableTriggers(table, schema); 34 | dispatch({ type: FETCH_TRIGGERS_SUCCESS, database, table, triggers }); 35 | } catch (error) { 36 | dispatch({ type: FETCH_TRIGGERS_FAILURE, error }); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /src/semantic1/components/footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import UpdateChecker from './update-checker.jsx'; 4 | // import LogStatus from './log-status.jsx'; 5 | var { shell } = window.myremote.electron; 6 | 7 | const STYLE = { 8 | footer: { minHeight: 'auto' }, 9 | status: { paddingLeft: '0.5em' }, 10 | }; 11 | 12 | function onGithubClick(event) { 13 | event.preventDefault(); 14 | shell.openExternal('https://github.com/sqlectron/sqlectron-gui'); 15 | } 16 | 17 | function onShortcutsClick(event) { 18 | event.preventDefault(); 19 | shell.openExternal( 20 | 'https://github.com/sqlectron/sqlectron-gui/wiki/Keyboard-Shortcuts' 21 | ); 22 | } 23 | 24 | const Footer = ({ status }) => ( 25 |
26 |
{status}
27 |
28 |
29 | { 30 | // 31 | } 32 | 33 |
34 | 35 | Github 36 | 37 | 38 | 39 | 40 |
41 |
42 | ); 43 | 44 | Footer.propTypes = { 45 | status: PropTypes.string.isRequired, 46 | }; 47 | 48 | export default Footer; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | [![Slack Status](https://sqlectron.herokuapp.com/badge.svg)](https://sqlectron.herokuapp.com) 4 | [![Build Status](https://travis-ci.org/sqlectron/sqlectron-gui.svg?branch=master)](https://travis-ci.org/sqlectron/sqlectron-gui) 5 | [![Build status](https://ci.appveyor.com/api/projects/status/ajxvrvwqyrc8yr23/branch/master?svg=true)](https://ci.appveyor.com/project/maxcnunes/sqlectron-gui/branch/master) 6 | 7 |

8 | 9 |
10 | A simple and lightweight SQL client with cross database and platform support. 11 |

12 | 13 | #### Demo (version 1.0.0) 14 | ![demo](https://sqlectron.github.io/demos/sqlectron-demo-gui-v1.0.0-small.gif) 15 | 16 | * [Databases](https://github.com/sqlectron/sqlectron-core#current-supported-databases) - List of current supported databases. 17 | * [Download](https://github.com/sqlectron/sqlectron-gui/releases) - Installers, binaries and source. 18 | * [Configuration](docs/app/configuration-file.md) - List of saved servers and custom configurations. 19 | * [App Docs](docs/app) - Helper docs about the app. 20 | * [Terminal](https://github.com/sqlectron/sqlectron-term) - A terminal-based interface of Sqlectron. 21 | * [Contribute](CONTRIBUTING.md) - Details on how you can contribute to Sqlectron. 22 | 23 | #### How to pronounce 24 | 25 | It is pronounced "sequel-eck-tron" - https://translate.google.com/?source=osdd#en/en/sequel-eck-tron 26 | -------------------------------------------------------------------------------- /src/bs/components/server-filter.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import debounce from 'lodash.debounce'; 4 | import Button from '@material-ui/core/Button'; 5 | import TextField from '@material-ui/core/TextField'; 6 | import SearchIcon from '@material-ui/icons/Search'; 7 | export default class ServerFilter extends Component { 8 | static propTypes = { 9 | onFilterChange: PropTypes.func.isRequired, 10 | onAddClick: PropTypes.func.isRequired, 11 | onSettingsClick: PropTypes.func.isRequired, 12 | }; 13 | 14 | UNSAFE_componentWillMount() { 15 | this.delayedCallback = debounce(this.props.onFilterChange, 200); 16 | } 17 | 18 | onFilterChange(event) { 19 | event.persist(); 20 | this.delayedCallback(event); 21 | } 22 | 23 | render() { 24 | return ( 25 |
27 | 28 | 33 | 36 | 42 | 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/bs/reducers/views.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as types from '../actions/views'; 3 | import * as dbTypes from '../actions/databases'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | viewsByDatabase: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_VIEWS_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_VIEWS_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | viewsByDatabase: { 29 | ...state.viewsByDatabase, 30 | [action.database]: action.views, 31 | }, 32 | error: null, 33 | }; 34 | } 35 | case types.FETCH_VIEWS_FAILURE: { 36 | return { 37 | ...state, 38 | isFetching: false, 39 | didInvalidate: true, 40 | error: action.error, 41 | }; 42 | } 43 | case dbTypes.REFRESH_DATABASES: { 44 | return { 45 | ...state, 46 | didInvalidate: true, 47 | }; 48 | } 49 | default : return state; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/mui/reducers/views.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as types from '../actions/views'; 3 | import * as dbTypes from '../actions/databases'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | viewsByDatabase: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_VIEWS_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_VIEWS_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | viewsByDatabase: { 29 | ...state.viewsByDatabase, 30 | [action.database]: action.views, 31 | }, 32 | error: null, 33 | }; 34 | } 35 | case types.FETCH_VIEWS_FAILURE: { 36 | return { 37 | ...state, 38 | isFetching: false, 39 | didInvalidate: true, 40 | error: action.error, 41 | }; 42 | } 43 | case dbTypes.REFRESH_DATABASES: { 44 | return { 45 | ...state, 46 | didInvalidate: true, 47 | }; 48 | } 49 | default : return state; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/mui/components/Ace.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import AceEditor from 'react-ace'; 3 | import 'brace/mode/css'; 4 | import 'brace/theme/github'; 5 | export default function Root(props){ 6 | const [state,setState]=React.useState( { 7 | mode: 'css', 8 | displayAce: 'none', 9 | }); 10 | var d = new Date(); 11 | return ( 12 |
22 | 33 | 47 |
48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/bs/actions/tables.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_TABLES_REQUEST = 'FETCH_TABLES_REQUEST'; 5 | export const FETCH_TABLES_SUCCESS = 'FETCH_TABLES_SUCCESS'; 6 | export const FETCH_TABLES_FAILURE = 'FETCH_TABLES_FAILURE'; 7 | export const SELECT_TABLES_FOR_DIAGRAM = 'SELECT_TABLES_FOR_DIAGRAM'; 8 | 9 | 10 | export function selectTablesForDiagram(tables) { 11 | return { type: SELECT_TABLES_FOR_DIAGRAM, tables }; 12 | } 13 | 14 | 15 | export function fetchTablesIfNeeded (database, filter) { 16 | return (dispatch, getState) => { 17 | if (shouldFetchTables(getState(), database)) { 18 | dispatch(fetchTables(database, filter)); 19 | } 20 | }; 21 | } 22 | 23 | 24 | function shouldFetchTables (state, database) { 25 | const tables = state.tables; 26 | if (!tables) return true; 27 | if (tables.isFetching) return false; 28 | if (!tables.itemsByDatabase[database]) return true; 29 | return tables.didInvalidate; 30 | } 31 | 32 | 33 | function fetchTables (database, filter) { 34 | return async (dispatch, getState) => { 35 | dispatch({ type: FETCH_TABLES_REQUEST, database }); 36 | try { 37 | const dbConn = getCurrentDBConn(getState()); 38 | const tables = await dbConn.listTables(filter); 39 | dispatch({ type: FETCH_TABLES_SUCCESS, database, tables }); 40 | } catch (error) { 41 | dispatch({ type: FETCH_TABLES_FAILURE, error }); 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/mui/actions/tables.js: -------------------------------------------------------------------------------- 1 | import { getCurrentDBConn } from './connections'; 2 | 3 | 4 | export const FETCH_TABLES_REQUEST = 'FETCH_TABLES_REQUEST'; 5 | export const FETCH_TABLES_SUCCESS = 'FETCH_TABLES_SUCCESS'; 6 | export const FETCH_TABLES_FAILURE = 'FETCH_TABLES_FAILURE'; 7 | export const SELECT_TABLES_FOR_DIAGRAM = 'SELECT_TABLES_FOR_DIAGRAM'; 8 | 9 | 10 | export function selectTablesForDiagram(tables) { 11 | return { type: SELECT_TABLES_FOR_DIAGRAM, tables }; 12 | } 13 | 14 | 15 | export function fetchTablesIfNeeded (database, filter) { 16 | return (dispatch, getState) => { 17 | if (shouldFetchTables(getState(), database)) { 18 | dispatch(fetchTables(database, filter)); 19 | } 20 | }; 21 | } 22 | 23 | 24 | function shouldFetchTables (state, database) { 25 | const tables = state.tables; 26 | if (!tables) return true; 27 | if (tables.isFetching) return false; 28 | if (!tables.itemsByDatabase[database]) return true; 29 | return tables.didInvalidate; 30 | } 31 | 32 | 33 | function fetchTables (database, filter) { 34 | return async (dispatch, getState) => { 35 | dispatch({ type: FETCH_TABLES_REQUEST, database }); 36 | try { 37 | const dbConn = getCurrentDBConn(getState()); 38 | const tables = await dbConn.listTables(filter); 39 | dispatch({ type: FETCH_TABLES_SUCCESS, database, tables }); 40 | } catch (error) { 41 | dispatch({ type: FETCH_TABLES_FAILURE, error }); 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/mui/containers/ModalAbout.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Dialog from '@mui/material/Dialog'; 3 | import DialogTitle from '@mui/material/DialogTitle'; 4 | import DialogContent from '@mui/material/DialogContent'; 5 | import DialogActions from '@mui/material/DialogActions'; 6 | var {electron}=window.myremote;// 7 | var config=window.myremote.config.get(); 8 | // console.log(Modal); 9 | export default class App extends React.Component{ 10 | // constructor(props, context) { 11 | // super(props, context); 12 | // // console.log("constructor modal1"); 13 | // } 14 | onClick=()=>{ 15 | // console.log(electron.shell); 16 | electron.shell.openExternal(config.website); 17 | } 18 | render=()=>{ 19 | return 20 | About Sqlectron 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Version:{config.version}
Author:{config.author.name}
email:{config.author.email}
website:{config.website}
29 |
30 | 31 | 34 | 35 |
; 36 | } 37 | } -------------------------------------------------------------------------------- /src/bs/containers/ModalAbout.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogTitle from '@material-ui/core/DialogTitle'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogActions from '@material-ui/core/DialogActions'; 6 | var {electron}=window.myremote;// 7 | var config=window.myremote.config.get(); 8 | // console.log(Modal); 9 | export default class App extends React.Component{ 10 | // constructor(props, context) { 11 | // super(props, context); 12 | // // console.log("constructor modal1"); 13 | // } 14 | onClick=()=>{ 15 | // console.log(electron.shell); 16 | electron.shell.openExternal(config.website); 17 | } 18 | render=()=>{ 19 | return 20 | About Sqlectron 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Version:{config.version}
Author:{config.author.name}
email:{config.author.email}
website:{config.website}
29 |
30 | 31 | 34 | 35 |
; 36 | } 37 | } -------------------------------------------------------------------------------- /src/bs/actions/columns.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_COLUMNS_REQUEST = 'FETCH_COLUMNS_REQUEST'; 5 | export const FETCH_COLUMNS_SUCCESS = 'FETCH_COLUMNS_SUCCESS'; 6 | export const FETCH_COLUMNS_FAILURE = 'FETCH_COLUMNS_FAILURE'; 7 | 8 | 9 | export function fetchTableColumnsIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableColumns(getState(), database, table, schema)) { 12 | dispatch(fetchTableColumns(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableColumns (state, database, table) { 19 | const columns = state.columns; 20 | if (!columns) return true; 21 | if (columns.isFetching[database] && columns.isFetching[database][table]) return false; 22 | if (!columns.columnsByTable[database]) return true; 23 | if (!columns.columnsByTable[database][table]) return true; 24 | return columns.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableColumns (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_COLUMNS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const columns = await dbConn.listTableColumns(table, schema); 34 | console.log(columns); 35 | dispatch({ type: FETCH_COLUMNS_SUCCESS, database, table, columns }); 36 | } catch (error) { 37 | dispatch({ type: FETCH_COLUMNS_FAILURE, error }); 38 | } 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/mui/actions/columns.js: -------------------------------------------------------------------------------- 1 | import { getDBConnByName } from './connections'; 2 | 3 | 4 | export const FETCH_COLUMNS_REQUEST = 'FETCH_COLUMNS_REQUEST'; 5 | export const FETCH_COLUMNS_SUCCESS = 'FETCH_COLUMNS_SUCCESS'; 6 | export const FETCH_COLUMNS_FAILURE = 'FETCH_COLUMNS_FAILURE'; 7 | 8 | 9 | export function fetchTableColumnsIfNeeded (database, table, schema) { 10 | return (dispatch, getState) => { 11 | if (shouldFetchTableColumns(getState(), database, table, schema)) { 12 | dispatch(fetchTableColumns(database, table, schema)); 13 | } 14 | }; 15 | } 16 | 17 | 18 | function shouldFetchTableColumns (state, database, table) { 19 | const columns = state.columns; 20 | if (!columns) return true; 21 | if (columns.isFetching[database] && columns.isFetching[database][table]) return false; 22 | if (!columns.columnsByTable[database]) return true; 23 | if (!columns.columnsByTable[database][table]) return true; 24 | return columns.didInvalidate; 25 | } 26 | 27 | 28 | function fetchTableColumns (database, table, schema) { 29 | return async dispatch => { 30 | dispatch({ type: FETCH_COLUMNS_REQUEST, database, table }); 31 | try { 32 | const dbConn = getDBConnByName(database); 33 | const columns = await dbConn.listTableColumns(table, schema); 34 | console.log(columns); 35 | dispatch({ type: FETCH_COLUMNS_SUCCESS, database, table, columns }); 36 | } catch (error) { 37 | dispatch({ type: FETCH_COLUMNS_FAILURE, error }); 38 | } 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/mui/components/server-list.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import ServerListItem from './server-list-item.jsx'; 4 | import Message from './message.jsx'; 5 | //require('./server-list.scss'); 6 | 7 | export default function ServerList(props){ 8 | // static propTypes = { 9 | // servers: PropTypes.array.isRequired, 10 | // onEditClick: PropTypes.func.isRequired, 11 | // onConnectClick: PropTypes.func.isRequired, 12 | // }; 13 | 14 | const groupItemsInRows=(items)=> { 15 | const itemsPerRow = 4; 16 | return items.reduce((rows, item, index) => { 17 | const position = Math.floor(index / itemsPerRow); 18 | if (!rows[position]) { 19 | rows[position] = []; // eslint-disable-line no-param-reassign 20 | } 21 | 22 | rows[position].push(item); 23 | return rows; 24 | }, []); 25 | } 26 | 27 | const { servers, onEditClick, onConnectClick } = props; 28 | 29 | if (!servers.length) { 30 | return ; 31 | } 32 | let view_servers=servers.map((server,idx)=>{ 33 | return ( onConnectClick(server)} 36 | onEditClick={() => onEditClick(server)} 37 | server={server} 38 | />); 39 | }); 40 | return ( 41 |
42 | {view_servers} 43 |
44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /docs/app/logging.md: -------------------------------------------------------------------------------- 1 | ## Logging 2 | 3 | > **IMPORTANT!** Replace any sensitive data (e.g. password) before including the log data in an issue. 4 | > 5 | > **IMPORTANT!** Disable the log if you are not investigating an issue. It makes the app slower. And with log to file enabled it may saves data to file that you don't want to be saved every time you are using the app. 6 | 7 | Is possible to enable logging by adding the configuration below to your `~/.sqlectron.json`: 8 | 9 | ```js 10 | "log": { 11 | // Show logs in the dev tools panel 12 | // "false" by default in production 13 | "console": true, 14 | 15 | // Save logs into a file 16 | // "false" by default in production 17 | "file": true, 18 | 19 | // Level logging: debug, info, warn, error 20 | // "error" by default in production 21 | "level": "debug", 22 | 23 | // Log file path 24 | // "~/.sqlectron.log" by default in production 25 | "path": "~/.sqlectron.log" 26 | }, 27 | ``` 28 | 29 | The log file is pretty easy to understand by just opening it in a text editor. But if you want an even better way to see that. Is possible to use [bunyan](https://github.com/trentm/node-bunyan) CLI: 30 | 31 | > Requires to have Node and NPM installed 32 | 33 | Install bunyan CLI globally 34 | 35 | ``` 36 | npm install -g bunyan 37 | ``` 38 | 39 | See the logs with a better output through bunyan CLI 40 | 41 | ``` 42 | tail -f ~/.sqlectron.log | bunyan -o short 43 | ``` 44 | or 45 | 46 | ``` 47 | cat ~/.sqlectron.log | bunyan -o short 48 | ``` 49 | -------------------------------------------------------------------------------- /src/mui/containers/ModalEdit.js: -------------------------------------------------------------------------------- 1 | // import isPlainObject from 'lodash.isplainobject'; 2 | import React, { Component } from 'react'; 3 | import PropTypes from 'proptypes'; 4 | // import classNames from 'classnames'; 5 | import Dialog from '@mui/material/Dialog'; 6 | import DialogTitle from '@mui/material/DialogTitle'; 7 | import DialogContent from '@mui/material/DialogContent'; 8 | import DialogActions from '@mui/material/DialogActions'; 9 | 10 | export default function PreviewModal(props){ 11 | // static propTypes = { 12 | // onCloseClick: PropTypes.func.isRequired, 13 | // }; 14 | // constructor(props, context) { 15 | // super(props, context); 16 | // state = {}; 17 | // } 18 | // const [state,setState]=React.useState({}); 19 | // const selected = state.selected || 'plain'; 20 | // const previewValue = getPreviewValue(selected); 21 | return ( 22 | 28 | Content Preview 29 | 30 |

{props.pos.row}

31 |

{props.pos.col}

32 |
33 | 34 |
39 | Close 40 |
41 |
42 |
43 | ); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/triple/_default.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-parse-triple-default($feature, $first, $second) { 6 | 7 | // Sort into min and max 8 | $min: min($first, $second); 9 | $max: max($first, $second); 10 | 11 | // Set Context 12 | $context-setter: private-breakpoint-set-context(min-#{$feature}, $min); 13 | $context-setter: private-breakpoint-set-context(max-#{$feature}, $max); 14 | 15 | // Make them EMs if need be 16 | @if (breakpoint-get('to ems') == true) { 17 | $min: breakpoint-to-base-em($min); 18 | $max: breakpoint-to-base-em($max); 19 | } 20 | 21 | @return '(min-#{$feature}: #{$min}) and (max-#{$feature}: #{$max})'; 22 | } 23 | <<<<<<< HEAD 24 | ======= 25 | ======= 26 | @function breakpoint-parse-triple-default($feature, $first, $second) { 27 | 28 | // Sort into min and max 29 | $min: min($first, $second); 30 | $max: max($first, $second); 31 | 32 | // Set Context 33 | $context-setter: private-breakpoint-set-context(min-#{$feature}, $min); 34 | $context-setter: private-breakpoint-set-context(max-#{$feature}, $max); 35 | 36 | // Make them EMs if need be 37 | @if (breakpoint-get('to ems') == true) { 38 | $min: breakpoint-to-base-em($min); 39 | $max: breakpoint-to-base-em($max); 40 | } 41 | 42 | @return '(min-#{$feature}: #{$min}) and (max-#{$feature}: #{$max})'; 43 | } 44 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 45 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 46 | -------------------------------------------------------------------------------- /src/bs/components/Ace.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import AceEditor from 'react-ace'; 3 | import 'brace/mode/css'; 4 | import 'brace/theme/github'; 5 | export default class Root extends Component { 6 | constructor() { 7 | super(); 8 | this.state = { 9 | mode: 'css', 10 | displayAce: 'none', 11 | }; 12 | } 13 | 14 | render = () => { 15 | var d = new Date(); 16 | return ( 17 |
27 | 38 | 52 |
53 | ); 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/bs/components/EditModal.js: -------------------------------------------------------------------------------- 1 | // import isPlainObject from 'lodash.isplainobject'; 2 | import React, { Component } from 'react'; 3 | import PropTypes from 'proptypes'; 4 | // import classNames from 'classnames'; 5 | import Dialog from '@material-ui/core/Dialog'; 6 | import DialogTitle from '@material-ui/core/DialogTitle'; 7 | import DialogContent from '@material-ui/core/DialogContent'; 8 | import DialogActions from '@material-ui/core/DialogActions'; 9 | 10 | export default class PreviewModal extends Component { 11 | static propTypes = { 12 | onCloseClick: PropTypes.func.isRequired, 13 | }; 14 | constructor(props, context) { 15 | super(props, context); 16 | this.state = {}; 17 | } 18 | 19 | render() { 20 | // const selected = this.state.selected || 'plain'; 21 | // const previewValue = this.getPreviewValue(selected); 22 | return ( 23 | 29 | Content Preview 30 | 31 |

{this.props.pos.row}

32 |

{this.props.pos.col}

33 |
34 | 35 |
40 | Close 41 |
42 |
43 |
44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/semantic1/reducers/tableEdit.js: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | export const SHOW_EDIT = 'SHOW_EDIT'; 6 | export const HIDE_EDIT = 'HIDE_EDIT'; 7 | const INITIAL_STATE = { 8 | show_edit: false, 9 | database:"", 10 | item:"", 11 | }; 12 | 13 | 14 | export default function (state = INITIAL_STATE, action) { 15 | switch (action.type) { 16 | case SHOW_EDIT: { 17 | return { 18 | ...state, 19 | show_edit:true, 20 | database:action.database, 21 | item:action.item, 22 | } 23 | } 24 | case HIDE_EDIT: { 25 | return { 26 | ...state, 27 | show_edit:false, 28 | } 29 | } 30 | default : return state; 31 | } 32 | } 33 | <<<<<<< HEAD 34 | ======= 35 | ======= 36 | export const SHOW_EDIT = 'SHOW_EDIT'; 37 | export const HIDE_EDIT = 'HIDE_EDIT'; 38 | const INITIAL_STATE = { 39 | show_edit: false, 40 | database:"", 41 | item:"", 42 | }; 43 | 44 | 45 | export default function (state = INITIAL_STATE, action) { 46 | switch (action.type) { 47 | case SHOW_EDIT: { 48 | return { 49 | ...state, 50 | show_edit:true, 51 | database:action.database, 52 | item:action.item, 53 | } 54 | } 55 | case HIDE_EDIT: { 56 | return { 57 | ...state, 58 | show_edit:false, 59 | } 60 | } 61 | default : return state; 62 | } 63 | } 64 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 65 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 66 | -------------------------------------------------------------------------------- /src/semantic1/containers/Ace.js~HEAD: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import AceEditor from 'react-ace'; 3 | import 'brace/mode/css'; 4 | import 'brace/theme/github'; 5 | export default class Root extends Component { 6 | constructor() { 7 | super(); 8 | this.state = { 9 | mode: 'css', 10 | displayAce: 'none', 11 | }; 12 | } 13 | 14 | render = () => { 15 | var d = new Date(); 16 | return ( 17 |
27 | 38 | 52 |
53 | ); 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/semantic1/components/require-context.js: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | // export const requireLogos = require('./server-db-client-.*\.png$/); 6 | const cassandraPNG = './server-db-client-cassandra.png'; 7 | const mysqlPNG = './server-db-client-mysql.png'; 8 | const pgPNG = './server-db-client-postgresql.png'; 9 | const sqlitePNG = './server-db-client-sqlite.png'; 10 | const sqlserverPNG = './server-db-client-sqlserver.png'; 11 | 12 | var dic1 = { 13 | cassandra: cassandraPNG, 14 | postgresql: pgPNG, 15 | mysql: mysqlPNG, 16 | sqlite: sqlitePNG, 17 | sqlserver: sqlserverPNG, 18 | }; 19 | export const requireLogos = name => { 20 | return dic1[name]; 21 | }; // require.context('./', false, /server-db-client-.*\.png$/); 22 | <<<<<<< HEAD 23 | ======= 24 | ======= 25 | // export const requireLogos = require('./server-db-client-.*\.png$/); 26 | const cassandraPNG = './server-db-client-cassandra.png'; 27 | const mysqlPNG = './server-db-client-mysql.png'; 28 | const pgPNG = './server-db-client-postgresql.png'; 29 | const sqlitePNG = './server-db-client-sqlite.png'; 30 | const sqlserverPNG = './server-db-client-sqlserver.png'; 31 | 32 | var dic1 = { 33 | cassandra: cassandraPNG, 34 | postgresql: pgPNG, 35 | mysql: mysqlPNG, 36 | sqlite: sqlitePNG, 37 | sqlserver: sqlserverPNG, 38 | }; 39 | export const requireLogos = name => { 40 | return dic1[name]; 41 | }; // require.context('./', false, /server-db-client-.*\.png$/); 42 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 43 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 44 | -------------------------------------------------------------------------------- /src/bs/reducers/indexes.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as types from '../actions/indexes'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | indexesByTable: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_INDEXES_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_INDEXES_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | indexesByTable: { 29 | ...state.indexesByTable, 30 | [action.database]: { 31 | ...state.indexesByTable[action.database], 32 | [action.table]: action.indexes.map(name => ({ name })), 33 | }, 34 | }, 35 | error: null, 36 | }; 37 | } 38 | case types.FETCH_INDEXES_FAILURE: { 39 | return { 40 | ...state, 41 | isFetching: false, 42 | didInvalidate: true, 43 | error: action.error, 44 | }; 45 | } 46 | case dbTypes.REFRESH_DATABASES: { 47 | return { 48 | ...state, 49 | didInvalidate: true, 50 | }; 51 | } 52 | default : return state; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/mui/reducers/indexes.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as types from '../actions/indexes'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | indexesByTable: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_INDEXES_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_INDEXES_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | indexesByTable: { 29 | ...state.indexesByTable, 30 | [action.database]: { 31 | ...state.indexesByTable[action.database], 32 | [action.table]: action.indexes.map(name => ({ name })), 33 | }, 34 | }, 35 | error: null, 36 | }; 37 | } 38 | case types.FETCH_INDEXES_FAILURE: { 39 | return { 40 | ...state, 41 | isFetching: false, 42 | didInvalidate: true, 43 | error: action.error, 44 | }; 45 | } 46 | case dbTypes.REFRESH_DATABASES: { 47 | return { 48 | ...state, 49 | didInvalidate: true, 50 | }; 51 | } 52 | default : return state; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/double/_double-string.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-parse-double-string($first, $second) { 6 | $feature: ''; 7 | $value: ''; 8 | 9 | // Test to see which is the feature and which is the value 10 | @if (breakpoint-string-value($first) == true) { 11 | $feature: $first; 12 | $value: $second; 13 | } 14 | @else if (breakpoint-string-value($second) == true) { 15 | $feature: $second; 16 | $value: $first; 17 | } 18 | @else { 19 | @warn "Neither #{$first} nor #{$second} is a valid media query name."; 20 | } 21 | 22 | // Set Context 23 | $context-setter: private-breakpoint-set-context($feature, $value); 24 | 25 | @return '(#{$feature}: #{$value})'; 26 | <<<<<<< HEAD 27 | ======= 28 | ======= 29 | @function breakpoint-parse-double-string($first, $second) { 30 | $feature: ''; 31 | $value: ''; 32 | 33 | // Test to see which is the feature and which is the value 34 | @if (breakpoint-string-value($first) == true) { 35 | $feature: $first; 36 | $value: $second; 37 | } 38 | @else if (breakpoint-string-value($second) == true) { 39 | $feature: $second; 40 | $value: $first; 41 | } 42 | @else { 43 | @warn "Neither #{$first} nor #{$second} is a valid media query name."; 44 | } 45 | 46 | // Set Context 47 | $context-setter: private-breakpoint-set-context($feature, $value); 48 | 49 | @return '(#{$feature}: #{$value})'; 50 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 51 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 52 | } -------------------------------------------------------------------------------- /src/semantic1/containers/Ace.js~1572c5914a1c2861ea611e07c0f1b245e7281167: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import AceEditor from 'react-ace'; 3 | import 'brace/mode/css'; 4 | import 'brace/theme/github'; 5 | export default class Root extends Component { 6 | constructor() { 7 | super(); 8 | this.state = { 9 | mode: 'css', 10 | displayAce: 'none', 11 | }; 12 | } 13 | 14 | render = () => { 15 | var d = new Date(); 16 | return ( 17 |
27 | 38 | 52 |
53 | ); 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/bs/reducers/triggers.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as types from '../actions/triggers'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | triggersByTable: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_TRIGGERS_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_TRIGGERS_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | triggersByTable: { 29 | ...state.triggersByTable, 30 | [action.database]: { 31 | ...state.triggersByTable[action.database], 32 | [action.table]: action.triggers.map(name => ({ name })), 33 | }, 34 | }, 35 | error: null, 36 | }; 37 | } 38 | case types.FETCH_TRIGGERS_FAILURE: { 39 | return { 40 | ...state, 41 | isFetching: false, 42 | didInvalidate: true, 43 | error: action.error, 44 | }; 45 | } 46 | case dbTypes.REFRESH_DATABASES: { 47 | return { 48 | ...state, 49 | didInvalidate: true, 50 | }; 51 | } 52 | default : return state; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/mui/reducers/triggers.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as types from '../actions/triggers'; 4 | 5 | 6 | const INITIAL_STATE = { 7 | isFetching: false, 8 | didInvalidate: false, 9 | triggersByTable: {}, 10 | }; 11 | 12 | 13 | export default function (state = INITIAL_STATE, action) { 14 | switch (action.type) { 15 | case connTypes.CONNECTION_REQUEST: { 16 | return action.isServerConnection 17 | ? { ...INITIAL_STATE, didInvalidate: true } 18 | : state; 19 | } 20 | case types.FETCH_TRIGGERS_REQUEST: { 21 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 22 | } 23 | case types.FETCH_TRIGGERS_SUCCESS: { 24 | return { 25 | ...state, 26 | isFetching: false, 27 | didInvalidate: false, 28 | triggersByTable: { 29 | ...state.triggersByTable, 30 | [action.database]: { 31 | ...state.triggersByTable[action.database], 32 | [action.table]: action.triggers.map(name => ({ name })), 33 | }, 34 | }, 35 | error: null, 36 | }; 37 | } 38 | case types.FETCH_TRIGGERS_FAILURE: { 39 | return { 40 | ...state, 41 | isFetching: false, 42 | didInvalidate: true, 43 | error: action.error, 44 | }; 45 | } 46 | case dbTypes.REFRESH_DATABASES: { 47 | return { 48 | ...state, 49 | didInvalidate: true, 50 | }; 51 | } 52 | default : return state; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/mui/components/update-checker.jsx: -------------------------------------------------------------------------------- 1 | //import { ipcRenderer, shell } from 'electron'; // eslint-disable-line import/no-unresolved 2 | import React from 'react'; 3 | var { ipcRenderer, shell } = window.myremote.electron; //from '../../browser/remote'; 4 | 5 | const EVENT_KEY = 'sqlectron:update-available'; 6 | //console.log(global); 7 | 8 | const repo = ''; //global.SQLECTRON_CONFIG.repository.url.replace('https://github.com/', ''); 9 | const LATEST_RELEASE_URL = `https://github.com/${repo}/releases/latest`; 10 | 11 | export default function UpdateChecker(props) { 12 | const [state,setState]=React.useState({ 13 | }); 14 | const componentDidMount=()=> { 15 | ipcRenderer.on(EVENT_KEY, onUpdateAvailable); 16 | } 17 | 18 | const componentWillUnmount=()=> { 19 | ipcRenderer.removeListener(EVENT_KEY, onUpdateAvailable); 20 | } 21 | 22 | const onUpdateAvailable=()=> { 23 | setState({ isVisible: true }); 24 | } 25 | 26 | const onUpdateClick=(event)=> { 27 | event.preventDefault(); 28 | shell.openExternal(LATEST_RELEASE_URL); 29 | } 30 | 31 | const isVisible = state && state.isVisible; 32 | if (!isVisible) { 33 | return null; 34 | } 35 | 36 | // TODO: show the latest avaible version 37 | // const currentVersion = `v${PACKAGE_JSON.version}`; 38 | // const availableVersion = '...'; 39 | 40 | return ( 41 | 42 | 43 | Update available 44 | {/*
{APP_VERSION}
*/} 45 |
46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /src/bs/components/update-checker.jsx: -------------------------------------------------------------------------------- 1 | //import { ipcRenderer, shell } from 'electron'; // eslint-disable-line import/no-unresolved 2 | import React, { Component } from 'react'; 3 | var { ipcRenderer, shell } = window.myremote.electron; //from '../../browser/remote'; 4 | 5 | const EVENT_KEY = 'sqlectron:update-available'; 6 | //console.log(global); 7 | 8 | const repo = ''; //global.SQLECTRON_CONFIG.repository.url.replace('https://github.com/', ''); 9 | const LATEST_RELEASE_URL = `https://github.com/${repo}/releases/latest`; 10 | 11 | export default class UpdateChecker extends Component { 12 | componentDidMount() { 13 | ipcRenderer.on(EVENT_KEY, this.onUpdateAvailable.bind(this)); 14 | } 15 | 16 | componentWillUnmount() { 17 | ipcRenderer.removeListener(EVENT_KEY, this.onUpdateAvailable.bind(this)); 18 | } 19 | 20 | onUpdateAvailable() { 21 | this.setState({ isVisible: true }); 22 | } 23 | 24 | onUpdateClick(event) { 25 | event.preventDefault(); 26 | shell.openExternal(LATEST_RELEASE_URL); 27 | } 28 | 29 | render() { 30 | const isVisible = this.state && this.state.isVisible; 31 | if (!isVisible) { 32 | return null; 33 | } 34 | 35 | // TODO: show the latest avaible version 36 | // const currentVersion = `v${PACKAGE_JSON.version}`; 37 | // const availableVersion = '...'; 38 | 39 | return ( 40 | 41 | 42 | Update available 43 | {/*
{APP_VERSION}
*/} 44 |
45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/bs/reducers/config.js: -------------------------------------------------------------------------------- 1 | import * as types from '../actions/config'; 2 | 3 | 4 | const INITIAL_STATE = { 5 | isSaving: false, 6 | isEditing: false, 7 | path: null, 8 | data: null, 9 | error: null, 10 | isLoaded: false, 11 | }; 12 | 13 | 14 | export default function config(state = INITIAL_STATE, action) { 15 | switch (action.type) { 16 | case types.LOAD_CONFIG_SUCCESS: 17 | return { 18 | ...state, 19 | data: action.config, 20 | path: action.path, 21 | isLoaded: true, 22 | }; 23 | case types.LOAD_CONFIG_FAILURE: { 24 | return { 25 | ...state, 26 | error: action.error, 27 | isLoaded: true, 28 | }; 29 | } 30 | case types.START_EDITING_CONFIG: { 31 | return { 32 | ...state, 33 | isSaving: false, 34 | isEditing: true, 35 | }; 36 | } 37 | case types.FINISH_EDITING_CONFIG: { 38 | return { 39 | ...state, 40 | isSaving: false, 41 | isEditing: false, 42 | isLoaded: true, 43 | error: null, 44 | }; 45 | } 46 | case types.SAVE_CONFIG_REQUEST: { 47 | return { 48 | ...state, 49 | isSaving: true, 50 | }; 51 | } 52 | case types.SAVE_CONFIG_SUCCESS: { 53 | return { 54 | data: { 55 | ...state.data, 56 | ...action.config, 57 | }, 58 | isSaving: false, 59 | isEditing:false,//to close modal 60 | isLoaded:true, 61 | error:null, 62 | }; 63 | } 64 | default: 65 | return state; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/mui/reducers/config.js: -------------------------------------------------------------------------------- 1 | import * as types from '../actions/config'; 2 | 3 | 4 | const INITIAL_STATE = { 5 | isSaving: false, 6 | isEditing: false, 7 | path: null, 8 | data: null, 9 | error: null, 10 | isLoaded: false, 11 | }; 12 | 13 | 14 | export default function config(state = INITIAL_STATE, action) { 15 | switch (action.type) { 16 | case types.LOAD_CONFIG_SUCCESS: 17 | return { 18 | ...state, 19 | data: action.config, 20 | path: action.path, 21 | isLoaded: true, 22 | }; 23 | case types.LOAD_CONFIG_FAILURE: { 24 | return { 25 | ...state, 26 | error: action.error, 27 | isLoaded: true, 28 | }; 29 | } 30 | case types.START_EDITING_CONFIG: { 31 | return { 32 | ...state, 33 | isSaving: false, 34 | isEditing: true, 35 | }; 36 | } 37 | case types.FINISH_EDITING_CONFIG: { 38 | return { 39 | ...state, 40 | isSaving: false, 41 | isEditing: false, 42 | isLoaded: true, 43 | error: null, 44 | }; 45 | } 46 | case types.SAVE_CONFIG_REQUEST: { 47 | return { 48 | ...state, 49 | isSaving: true, 50 | }; 51 | } 52 | case types.SAVE_CONFIG_SUCCESS: { 53 | return { 54 | data: { 55 | ...state.data, 56 | ...action.config, 57 | }, 58 | isSaving: false, 59 | isEditing:false,//to close modal 60 | isLoaded:true, 61 | error:null, 62 | }; 63 | } 64 | default: 65 | return state; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/mui/components/footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import UpdateChecker from './update-checker.jsx'; 4 | import Snackbar from '@mui/material/Snackbar'; 5 | import SnackbarContent from '@mui/material/SnackbarContent'; 6 | // import LogStatus from './log-status.jsx'; 7 | var { shell } = window.myremote.electron; 8 | 9 | const STYLE = { 10 | footer: { minHeight: 'auto' }, 11 | status: { paddingLeft: '0.5em' }, 12 | }; 13 | 14 | function onGithubClick(event) { 15 | event.preventDefault(); 16 | shell.openExternal('https://github.com/sqlectron/sqlectron-gui'); 17 | } 18 | 19 | function onShortcutsClick(event) { 20 | event.preventDefault(); 21 | shell.openExternal( 22 | 'https://github.com/sqlectron/sqlectron-gui/wiki/Keyboard-Shortcuts' 23 | ); 24 | } 25 | 26 | const Footer = ({ status }) => ( 27 | 28 | 29 |
{status}
30 |
31 |
32 | { 33 | // 34 | } 35 | 36 |
37 | 38 | Github 39 | 40 | 45 | 46 | 47 |
48 |
49 |
50 | ); 51 | 52 | Footer.propTypes = { 53 | status: PropTypes.string.isRequired, 54 | }; 55 | 56 | export default Footer; 57 | -------------------------------------------------------------------------------- /src/bs/components/footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import UpdateChecker from './update-checker.jsx'; 4 | import Snackbar from '@material-ui/core/Snackbar'; 5 | import SnackbarContent from '@material-ui/core/SnackbarContent'; 6 | // import LogStatus from './log-status.jsx'; 7 | var { shell } = window.myremote.electron; 8 | 9 | const STYLE = { 10 | footer: { minHeight: 'auto' }, 11 | status: { paddingLeft: '0.5em' }, 12 | }; 13 | 14 | function onGithubClick(event) { 15 | event.preventDefault(); 16 | shell.openExternal('https://github.com/sqlectron/sqlectron-gui'); 17 | } 18 | 19 | function onShortcutsClick(event) { 20 | event.preventDefault(); 21 | shell.openExternal( 22 | 'https://github.com/sqlectron/sqlectron-gui/wiki/Keyboard-Shortcuts' 23 | ); 24 | } 25 | 26 | const Footer = ({ status }) => ( 27 | 28 | 29 |
{status}
30 |
31 |
32 | { 33 | // 34 | } 35 | 36 |
37 | 38 | Github 39 | 40 | 45 | 46 | 47 |
48 |
49 |
50 | ); 51 | 52 | Footer.propTypes = { 53 | status: PropTypes.string.isRequired, 54 | }; 55 | 56 | export default Footer; 57 | -------------------------------------------------------------------------------- /src/bs/components/server-list.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import ServerListItem from './server-list-item.jsx'; 4 | import Message from './message.jsx'; 5 | //require('./server-list.scss'); 6 | 7 | export default class ServerList extends Component { 8 | static propTypes = { 9 | servers: PropTypes.array.isRequired, 10 | onEditClick: PropTypes.func.isRequired, 11 | onConnectClick: PropTypes.func.isRequired, 12 | }; 13 | 14 | groupItemsInRows(items) { 15 | const itemsPerRow = 4; 16 | return items.reduce((rows, item, index) => { 17 | const position = Math.floor(index / itemsPerRow); 18 | if (!rows[position]) { 19 | rows[position] = []; // eslint-disable-line no-param-reassign 20 | } 21 | 22 | rows[position].push(item); 23 | return rows; 24 | }, []); 25 | } 26 | 27 | render() { 28 | const { servers, onEditClick, onConnectClick } = this.props; 29 | 30 | if (!servers.length) { 31 | return ; 32 | } 33 | 34 | return ( 35 |
36 | {this.groupItemsInRows(servers).map((row, rowIdx) => ( 37 |
38 | {row.map(server => ( 39 | onConnectClick(server)} 42 | onEditClick={() => onEditClick(server)} 43 | server={server} 44 | /> 45 | ))} 46 |
47 | ))} 48 |
49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/double/_default-pair.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | @function breakpoint-parse-default-pair($first, $second) { 6 | $default: breakpoint-get('default pair'); 7 | $min: ''; 8 | $max: ''; 9 | 10 | // Sort into min and max 11 | $min: min($first, $second); 12 | $max: max($first, $second); 13 | 14 | // Set Context 15 | $context-setter: private-breakpoint-set-context(min-#{$default}, $min); 16 | $context-setter: private-breakpoint-set-context(max-#{$default}, $max); 17 | 18 | // Make them EMs if need be 19 | @if (breakpoint-get('to ems') == true) { 20 | $min: breakpoint-to-base-em($min); 21 | $max: breakpoint-to-base-em($max); 22 | } 23 | 24 | @return '(min-#{$default}: #{$min}) and (max-#{$default}: #{$max})'; 25 | } 26 | <<<<<<< HEAD 27 | ======= 28 | ======= 29 | @function breakpoint-parse-default-pair($first, $second) { 30 | $default: breakpoint-get('default pair'); 31 | $min: ''; 32 | $max: ''; 33 | 34 | // Sort into min and max 35 | $min: min($first, $second); 36 | $max: max($first, $second); 37 | 38 | // Set Context 39 | $context-setter: private-breakpoint-set-context(min-#{$default}, $min); 40 | $context-setter: private-breakpoint-set-context(max-#{$default}, $max); 41 | 42 | // Make them EMs if need be 43 | @if (breakpoint-get('to ems') == true) { 44 | $min: breakpoint-to-base-em($min); 45 | $max: breakpoint-to-base-em($max); 46 | } 47 | 48 | @return '(min-#{$default}: #{$min}) and (max-#{$default}: #{$max})'; 49 | } 50 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 51 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 52 | -------------------------------------------------------------------------------- /src/mui/components/server-db-client-info-modal.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import Dialog from '@mui/material/Dialog'; 4 | import DialogTitle from '@mui/material/DialogTitle'; 5 | import DialogContent from '@mui/material/DialogContent'; 6 | import DialogActions from '@mui/material/DialogActions'; 7 | var { sqlectron } = window.myremote; 8 | const CLIENTS = sqlectron.db.CLIENTS.map(dbClient => ({ 9 | key: dbClient.key, 10 | name: dbClient.name, 11 | })); 12 | 13 | //var { sqlectron }= require('electron').remote; 14 | export default function ServerDBClientInfoModal(props){ 15 | // static propTypes = { 16 | // client: PropTypes.string.isRequired, 17 | // infos: PropTypes.array.isRequired, 18 | // onCloseClick: PropTypes.func.isRequired, 19 | // }; 20 | const { client, infos } = props; 21 | const dbClient = CLIENTS.find(item => item.key === client); 22 | return ( 23 | 30 | {dbClient.name} Query Information 31 | 32 |

33 | Some particularities about queries on {dbClient.name} you should 34 | know: 35 |

36 |
37 | {infos.map((info, idx) => ( 38 |
39 | {info} 40 |
41 | ))} 42 |
43 |
    44 | 45 |
46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /src/bs/AppSql.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | // import AppTest from './AppTest'; 4 | import ServerManagementContainer from './containers/server-management2.jsx'; 5 | import QueryBrowserContainer from './containers/query-browser2.jsx'; 6 | import {Redirect,Router, Route,Switch,Link} from 'react-router-dom' 7 | import configureStore from './store/configure'; 8 | let createHashHistory=require("history").createHashHistory; 9 | // import createBrowserHistory from "history" 10 | const history = createHashHistory({ 11 | hashType: "slash" // the default 12 | }) 13 | const store = configureStore(); 14 | class NoMatch extends Component{ 15 | render=()=>{ 16 | console.log(this.props); 17 | return(
18 | manage 19 |
); 20 | } 21 | } 22 | class NoID extends Component{ 23 | render=()=>{ 24 | console.log(this.props.history.location.pathname); 25 | return(
26 | NoID 27 | manage 28 |
); 29 | } 30 | } 31 | 32 | class Routers extends Component{ 33 | render=()=>{ 34 | return( 35 | 36 | 37 | 38 | ); 39 | } 40 | } 41 | export default class Root extends Component { 42 | render() { 43 | return ( 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/bs/reducers/sqlscripts.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as types from '../actions/sqlscripts'; 3 | 4 | 5 | const INITIAL_STATE = { 6 | isFetching: false, 7 | didInvalidate: false, 8 | scriptsByObject: {}, 9 | }; 10 | 11 | 12 | export default function (state = INITIAL_STATE, action) { 13 | switch (action.type) { 14 | case connTypes.CONNECTION_REQUEST: { 15 | return action.isServerConnection 16 | ? { ...INITIAL_STATE, didInvalidate: true } 17 | : state; 18 | } 19 | case types.GET_SCRIPT_REQUEST: { 20 | return { 21 | ...state, 22 | scriptType: action.scriptType, 23 | isFetching: true, 24 | didInvalidate: false, 25 | error: null, 26 | }; 27 | } 28 | case types.GET_SCRIPT_SUCCESS: { 29 | const scriptsByItem = !state.scriptsByObject[action.database] 30 | ? null 31 | : state.scriptsByObject[action.database][action.item]; 32 | return { 33 | ...state, 34 | isFetching: false, 35 | didInvalidate: false, 36 | error: null, 37 | scriptsByObject: { 38 | ...state.scriptsByObject, 39 | [action.database]: { 40 | ...state.scriptsByObject[action.database], 41 | [action.item]: { 42 | ...scriptsByItem, 43 | objectType: action.objectType, 44 | [action.actionType]: action.script, 45 | }, 46 | }, 47 | }, 48 | }; 49 | } 50 | case types.GET_SCRIPT_FAILURE: { 51 | return { 52 | ...state, 53 | isFetching: false, 54 | didInvalidate: true, 55 | error: action.error, 56 | }; 57 | } 58 | default : return state; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/mui/reducers/sqlscripts.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as types from '../actions/sqlscripts'; 3 | 4 | 5 | const INITIAL_STATE = { 6 | isFetching: false, 7 | didInvalidate: false, 8 | scriptsByObject: {}, 9 | }; 10 | 11 | 12 | export default function (state = INITIAL_STATE, action) { 13 | switch (action.type) { 14 | case connTypes.CONNECTION_REQUEST: { 15 | return action.isServerConnection 16 | ? { ...INITIAL_STATE, didInvalidate: true } 17 | : state; 18 | } 19 | case types.GET_SCRIPT_REQUEST: { 20 | return { 21 | ...state, 22 | scriptType: action.scriptType, 23 | isFetching: true, 24 | didInvalidate: false, 25 | error: null, 26 | }; 27 | } 28 | case types.GET_SCRIPT_SUCCESS: { 29 | const scriptsByItem = !state.scriptsByObject[action.database] 30 | ? null 31 | : state.scriptsByObject[action.database][action.item]; 32 | return { 33 | ...state, 34 | isFetching: false, 35 | didInvalidate: false, 36 | error: null, 37 | scriptsByObject: { 38 | ...state.scriptsByObject, 39 | [action.database]: { 40 | ...state.scriptsByObject[action.database], 41 | [action.item]: { 42 | ...scriptsByItem, 43 | objectType: action.objectType, 44 | [action.actionType]: action.script, 45 | }, 46 | }, 47 | }, 48 | }; 49 | } 50 | case types.GET_SCRIPT_FAILURE: { 51 | return { 52 | ...state, 53 | isFetching: false, 54 | didInvalidate: true, 55 | error: action.error, 56 | }; 57 | } 58 | default : return state; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/bs/components/jointjs-diagram-table.js: -------------------------------------------------------------------------------- 1 | import joint from 'jointjs/dist/joint'; 2 | import bindAll from 'lodash.bindall'; 3 | import template from 'lodash.template'; 4 | if (!$) { 5 | var $ = window.$; 6 | } 7 | 8 | // Custom joint shape representing table/view object 9 | joint.shapes.sqlectron = {}; 10 | joint.shapes.sqlectron.Table = joint.shapes.basic.Rect.extend({ 11 | defaults: joint.util.deepSupplement( 12 | { 13 | type: 'sqlectron.Table', 14 | attrs: { 15 | rect: { stroke: 'none', 'fill-opacity': 0 }, 16 | }, 17 | }, 18 | joint.shapes.basic.Rect.prototype.defaults 19 | ), 20 | }); 21 | 22 | joint.shapes.sqlectron.TableView = joint.dia.ElementView.extend({ 23 | template: '

', 24 | 25 | initialize(...args) { 26 | bindAll(this, 'updateBox'); 27 | joint.dia.ElementView.prototype.initialize.apply(this, args); 28 | this.$box = $(template(this.template)()); 29 | 30 | this.$box.find('span').text(this.model.get('name')); 31 | this.$box.addClass(this.model.get('name')); 32 | 33 | // Update the box position whenever the underlying model changes. 34 | this.model.on('change', this.updateBox, this); 35 | 36 | this.updateBox(); 37 | }, 38 | render(...args) { 39 | joint.dia.ElementView.prototype.render.apply(this, args); 40 | this.paper.$el.prepend(this.$box); 41 | return this; 42 | }, 43 | updateBox() { 44 | // Set the position and dimension of the box so that it covers the JointJS element. 45 | const bbox = this.model.getBBox(); 46 | this.$box.css({ 47 | width: bbox.width, 48 | height: bbox.height, 49 | left: bbox.x, 50 | top: bbox.y, 51 | transform: `rotate(${this.model.get('angle') || 0}deg)`, 52 | }); 53 | }, 54 | }); 55 | -------------------------------------------------------------------------------- /src/mui/components/jointjs-diagram-table.js: -------------------------------------------------------------------------------- 1 | import joint from 'jointjs/dist/joint'; 2 | import bindAll from 'lodash.bindall'; 3 | import template from 'lodash.template'; 4 | if (!$) { 5 | var $ = window.$; 6 | } 7 | 8 | // Custom joint shape representing table/view object 9 | joint.shapes.sqlectron = {}; 10 | joint.shapes.sqlectron.Table = joint.shapes.basic.Rect.extend({ 11 | defaults: joint.util.deepSupplement( 12 | { 13 | type: 'sqlectron.Table', 14 | attrs: { 15 | rect: { stroke: 'none', 'fill-opacity': 0 }, 16 | }, 17 | }, 18 | joint.shapes.basic.Rect.prototype.defaults 19 | ), 20 | }); 21 | 22 | joint.shapes.sqlectron.TableView = joint.dia.ElementView.extend({ 23 | template: '

', 24 | 25 | initialize(...args) { 26 | bindAll(this, 'updateBox'); 27 | joint.dia.ElementView.prototype.initialize.apply(this, args); 28 | this.$box = $(template(this.template)()); 29 | 30 | this.$box.find('span').text(this.model.get('name')); 31 | this.$box.addClass(this.model.get('name')); 32 | 33 | // Update the box position whenever the underlying model changes. 34 | this.model.on('change', this.updateBox, this); 35 | 36 | this.updateBox(); 37 | }, 38 | render(...args) { 39 | joint.dia.ElementView.prototype.render.apply(this, args); 40 | this.paper.$el.prepend(this.$box); 41 | return this; 42 | }, 43 | updateBox() { 44 | // Set the position and dimension of the box so that it covers the JointJS element. 45 | const bbox = this.model.getBBox(); 46 | this.$box.css({ 47 | width: bbox.width, 48 | height: bbox.height, 49 | left: bbox.x, 50 | top: bbox.y, 51 | transform: `rotate(${this.model.get('angle') || 0}deg)`, 52 | }); 53 | }, 54 | }); 55 | -------------------------------------------------------------------------------- /src/semantic1/AppSql.js~HEAD: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | // import AppTest from './AppTest'; 4 | import ServerManagementContainer from './containers/server-management2.jsx'; 5 | import QueryBrowserContainer from './containers/query-browser2.jsx'; 6 | import {Redirect,Router, Route,Switch,Link} from 'react-router-dom' 7 | import configureStore from './store/configure'; 8 | // import createHashHistory from "history/createHashHistory"; 9 | let createHashHistory=require("history").createHashHistory 10 | // import createBrowserHistory from "history" 11 | const history = createHashHistory({ 12 | hashType: "slash" // the default 13 | }) 14 | const store = configureStore(); 15 | class NoMatch extends Component{ 16 | render=()=>{ 17 | console.log(this.props); 18 | return(
19 | manage 20 |
); 21 | } 22 | } 23 | class NoID extends Component{ 24 | render=()=>{ 25 | console.log(this.props.history.location.pathname); 26 | return(
27 | NoID 28 | manage 29 |
); 30 | } 31 | } 32 | 33 | class Routers extends Component{ 34 | render=()=>{ 35 | return( 36 | 37 | 38 | 39 | ); 40 | } 41 | } 42 | export default class Root extends Component { 43 | render() { 44 | return ( 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/semantic1/components/server-list.css: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | #server-list { 6 | /** 7 | * 1 card per row 8 | */ 9 | /** 10 | * 2 cards per row 11 | */ 12 | /** 13 | * 4 cards per row 14 | */ 15 | } 16 | #server-list .ui.cards > .card { 17 | width: 100%; 18 | } 19 | #server-list .ui.cards { 20 | margin-left: -1em; 21 | margin-right: -1em; 22 | } 23 | #server-list .ui.cards > .card { 24 | width: calc( 50% - 2em ); 25 | margin-left: 1em; 26 | margin-right: 1em; 27 | } 28 | #server-list .ui.cards { 29 | margin-left: -0.75em; 30 | margin-right: -0.75em; 31 | } 32 | #server-list .ui.cards > .card { 33 | width: calc( 25% - 1.5em ); 34 | margin-left: 0.75em; 35 | margin-right: 0.75em; 36 | } 37 | #server-list .card .content .header, #server-list .card .content .meta { 38 | word-break: break-all; 39 | } 40 | <<<<<<< HEAD 41 | ======= 42 | ======= 43 | #server-list { 44 | /** 45 | * 1 card per row 46 | */ 47 | /** 48 | * 2 cards per row 49 | */ 50 | /** 51 | * 4 cards per row 52 | */ 53 | } 54 | #server-list .ui.cards > .card { 55 | width: 100%; 56 | } 57 | #server-list .ui.cards { 58 | margin-left: -1em; 59 | margin-right: -1em; 60 | } 61 | #server-list .ui.cards > .card { 62 | width: calc( 50% - 2em ); 63 | margin-left: 1em; 64 | margin-right: 1em; 65 | } 66 | #server-list .ui.cards { 67 | margin-left: -0.75em; 68 | margin-right: -0.75em; 69 | } 70 | #server-list .ui.cards > .card { 71 | width: calc( 25% - 1.5em ); 72 | margin-left: 0.75em; 73 | margin-right: 0.75em; 74 | } 75 | #server-list .card .content .header, #server-list .card .content .meta { 76 | word-break: break-all; 77 | } 78 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 79 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 80 | -------------------------------------------------------------------------------- /src/semantic1/components/breakpoint/parsers/_single.scss: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | ======= 3 | <<<<<<< HEAD 4 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 5 | ////////////////////////////// 6 | // Import Pieces 7 | ////////////////////////////// 8 | @import "single/default"; 9 | 10 | @function breakpoint-parse-single($feature, $empty-media, $first) { 11 | $parsed: ''; 12 | $leader: ''; 13 | // If we're forcing 14 | @if not ($empty-media) or not ($first) { 15 | $leader: 'and '; 16 | } 17 | 18 | // If it's a single feature that can stand alone, we let it 19 | @if (breakpoint-single-string($feature)) { 20 | $parsed: $feature; 21 | // Set Context 22 | $context-setter: private-breakpoint-set-context($feature, $feature); 23 | } 24 | // If it's not a stand alone feature, we pass it off to the default handler. 25 | @else { 26 | $parsed: breakpoint-parse-default($feature); 27 | } 28 | 29 | @return $leader + '(' + $parsed + ')'; 30 | } 31 | <<<<<<< HEAD 32 | ======= 33 | ======= 34 | ////////////////////////////// 35 | // Import Pieces 36 | ////////////////////////////// 37 | @import "single/default"; 38 | 39 | @function breakpoint-parse-single($feature, $empty-media, $first) { 40 | $parsed: ''; 41 | $leader: ''; 42 | // If we're forcing 43 | @if not ($empty-media) or not ($first) { 44 | $leader: 'and '; 45 | } 46 | 47 | // If it's a single feature that can stand alone, we let it 48 | @if (breakpoint-single-string($feature)) { 49 | $parsed: $feature; 50 | // Set Context 51 | $context-setter: private-breakpoint-set-context($feature, $feature); 52 | } 53 | // If it's not a stand alone feature, we pass it off to the default handler. 54 | @else { 55 | $parsed: breakpoint-parse-default($feature); 56 | } 57 | 58 | @return $leader + '(' + $parsed + ')'; 59 | } 60 | >>>>>>> 1572c5914a1c2861ea611e07c0f1b245e7281167 61 | >>>>>>> f60390a2b01ae0ba09cd516dcf60d1ed723adb45 62 | -------------------------------------------------------------------------------- /src/bs/components/breakpoint/parsers/resolution/_resolution.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-make-resolutions($resolution) { 2 | $length: length($resolution); 3 | 4 | $output: (); 5 | 6 | @if $length == 2 { 7 | $feature: ''; 8 | $value: ''; 9 | 10 | // Find which is number 11 | @if type-of(nth($resolution, 1)) == 'number' { 12 | $value: nth($resolution, 1); 13 | } 14 | @else { 15 | $value: nth($resolution, 2); 16 | } 17 | 18 | // Determine min/max/standard 19 | @if index($resolution, 'min-resolution') { 20 | $feature: 'min-'; 21 | } 22 | @else if index($resolution, 'max-resolution') { 23 | $feature: 'max-'; 24 | } 25 | 26 | $standard: '(#{$feature}resolution: #{$value})'; 27 | 28 | // If we're not dealing with dppx, 29 | @if unit($value) != 'dppx' { 30 | $base: 96dpi; 31 | @if unit($value) == 'dpcm' { 32 | $base: 243.84dpcm; 33 | } 34 | // Write out feature tests 35 | $webkit: ''; 36 | $moz: ''; 37 | $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / $base})'; 38 | $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / $base})'; 39 | // Append to output 40 | $output: append($output, $standard, space); 41 | $output: append($output, $webkit, space); 42 | $output: append($output, $moz, space); 43 | } 44 | @else { 45 | $webkit: ''; 46 | $moz: ''; 47 | $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / 1dppx})'; 48 | $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / 1dppx})'; 49 | $fallback: '(#{$feature}resolution: #{$value / 1dppx * 96dpi})'; 50 | // Append to output 51 | $output: append($output, $standard, space); 52 | $output: append($output, $webkit, space); 53 | $output: append($output, $moz, space); 54 | $output: append($output, $fallback, space); 55 | } 56 | 57 | } 58 | 59 | @return $output; 60 | } 61 | -------------------------------------------------------------------------------- /src/mui/components/breakpoint/parsers/resolution/_resolution.scss: -------------------------------------------------------------------------------- 1 | @function breakpoint-make-resolutions($resolution) { 2 | $length: length($resolution); 3 | 4 | $output: (); 5 | 6 | @if $length == 2 { 7 | $feature: ''; 8 | $value: ''; 9 | 10 | // Find which is number 11 | @if type-of(nth($resolution, 1)) == 'number' { 12 | $value: nth($resolution, 1); 13 | } 14 | @else { 15 | $value: nth($resolution, 2); 16 | } 17 | 18 | // Determine min/max/standard 19 | @if index($resolution, 'min-resolution') { 20 | $feature: 'min-'; 21 | } 22 | @else if index($resolution, 'max-resolution') { 23 | $feature: 'max-'; 24 | } 25 | 26 | $standard: '(#{$feature}resolution: #{$value})'; 27 | 28 | // If we're not dealing with dppx, 29 | @if unit($value) != 'dppx' { 30 | $base: 96dpi; 31 | @if unit($value) == 'dpcm' { 32 | $base: 243.84dpcm; 33 | } 34 | // Write out feature tests 35 | $webkit: ''; 36 | $moz: ''; 37 | $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / $base})'; 38 | $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / $base})'; 39 | // Append to output 40 | $output: append($output, $standard, space); 41 | $output: append($output, $webkit, space); 42 | $output: append($output, $moz, space); 43 | } 44 | @else { 45 | $webkit: ''; 46 | $moz: ''; 47 | $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / 1dppx})'; 48 | $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / 1dppx})'; 49 | $fallback: '(#{$feature}resolution: #{$value / 1dppx * 96dpi})'; 50 | // Append to output 51 | $output: append($output, $standard, space); 52 | $output: append($output, $webkit, space); 53 | $output: append($output, $moz, space); 54 | $output: append($output, $fallback, space); 55 | } 56 | 57 | } 58 | 59 | @return $output; 60 | } 61 | -------------------------------------------------------------------------------- /src/semantic1/components/server-db-client-info-modal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'proptypes'; 3 | import { Modal } from 'semantic-ui-react'; 4 | var { sqlectron } = window.myremote; 5 | const CLIENTS = sqlectron.db.CLIENTS.map(dbClient => ({ 6 | key: dbClient.key, 7 | name: dbClient.name, 8 | })); 9 | 10 | //var { sqlectron }= require('electron').remote; 11 | export default class ServerDBClientInfoModal extends Component { 12 | static propTypes = { 13 | client: PropTypes.string.isRequired, 14 | infos: PropTypes.array.isRequired, 15 | onCloseClick: PropTypes.func.isRequired, 16 | }; 17 | 18 | componentDidMount() { 19 | // $(this.refs.infoModal).modal({ 20 | // closable: true, 21 | // detachable: false, 22 | // allowMultiple: true, 23 | // observeChanges: true, 24 | // onHidden: () => this.props.onCloseClick(), 25 | // }).modal('show'); 26 | } 27 | 28 | componentWillUnmount() { 29 | //$(this.refs.infoModal).modal('hide'); 30 | } 31 | 32 | render() { 33 | const { client, infos } = this.props; 34 | const dbClient = CLIENTS.find(item => item.key === client); 35 | return ( 36 | 43 | {dbClient.name} Query Information 44 | 45 |

46 | Some particularities about queries on {dbClient.name} you should 47 | know: 48 |

49 |
50 | {infos.map((info, idx) => ( 51 |
52 | {info} 53 |
54 | ))} 55 |
56 |
    57 | 58 | 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/bs/store/configure.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import thunkMiddleware from 'redux-thunk'; 3 | import rootReducer from '../reducers'; 4 | import { createLogger } from 'redux-logger' 5 | const middlewares = [thunkMiddleware]; 6 | 7 | /* eslint global-require:0 */ 8 | var config=window.myremote.config.get(); 9 | const isLogConsoleEnabled = config.log.console; 10 | const isLogFileEnabled = config.log.file; 11 | 12 | if (isLogConsoleEnabled || isLogFileEnabled) { 13 | const loggerConfig = { 14 | level: config.log.level, 15 | collapsed: true, 16 | }; 17 | 18 | const mainLogger = isLogFileEnabled ? window.myremote.createLogger('renderer:redux') : null; 19 | 20 | loggerConfig.logger = {}; 21 | 22 | for (const method in console) { // eslint-disable-line no-restricted-syntax 23 | if (typeof console[method] === 'function') { // eslint-disable-line no-console 24 | loggerConfig.logger[method] = function levelFn(...args) { 25 | if (isLogConsoleEnabled) { 26 | const m = method === 'debug' ? 'log' : method; 27 | console[m].apply(console, args); // eslint-disable-line no-console 28 | } 29 | 30 | if (isLogFileEnabled) { 31 | // log on file only messages with error 32 | // otherwise is too much private information 33 | // the user would need to remove to issue a bug 34 | const lastArg = args[args.length - 1]; 35 | if (lastArg && lastArg.error) { 36 | mainLogger.error('Error', lastArg.error); 37 | mainLogger.error('Error Stack', lastArg.error.stack); 38 | } 39 | } 40 | }; 41 | } 42 | } 43 | 44 | middlewares.push(createLogger(loggerConfig)); 45 | } 46 | 47 | 48 | const createStoreWithMiddleware = applyMiddleware( 49 | ...middlewares 50 | )(createStore); 51 | 52 | 53 | export default function configureStore(initialState) { 54 | const store = createStoreWithMiddleware(rootReducer, initialState); 55 | return store; 56 | } 57 | -------------------------------------------------------------------------------- /src/mui/AppSql.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Provider } from 'react-redux'; 3 | // import AppTest from './AppTest'; 4 | import App from './containers/app.jsx'; 5 | import ServerManagementContainer from './containers/server-management.jsx'; 6 | import QueryBrowserContainer from './containers/query-browser.jsx'; 7 | // import {Redirect,Router, Route,Switch,Link} from 'react-router-dom' 8 | import {HashRouter as Router,BrowserRouter,Routes, Route,Link} from 'react-router-dom' 9 | import configureStore from './store/configure'; 10 | // let createHashHistory=require("history").createHashHistory; 11 | import {injectGlobal} from '@emotion/css'; 12 | injectGlobal` 13 | body{ 14 | margin: 0px; 15 | padding: 0; 16 | border: 0; 17 | background: #c0c0c0; }` 18 | // import createBrowserHistory from "history" 19 | // const history = createHashHistory({ 20 | // hashType: "slash" // the default 21 | // }) 22 | const store = configureStore(); 23 | class NoMatch extends Component{ 24 | render=()=>{ 25 | console.log(this.props); 26 | return(
    27 | manage 28 |
    ); 29 | } 30 | } 31 | class NoID extends Component{ 32 | render=()=>{ 33 | console.log(this.props.history.location.pathname); 34 | return(
    35 | NoID 36 | manage 37 |
    ); 38 | } 39 | } 40 | 41 | class Routers extends Component{ 42 | render=()=>{ 43 | return( 44 | } /> 45 | } /> 46 | }/> 47 | ); 48 | } 49 | } 50 | export default class Root extends Component { 51 | render() { 52 | return ( 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | ); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/bs/reducers/schemas.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as queryTypes from '../actions/queries'; 4 | import * as types from '../actions/schemas'; 5 | 6 | 7 | const INITIAL_STATE = { 8 | isFetching: false, 9 | didInvalidate: false, 10 | itemsByDatabase: {}, 11 | selectedTablesForDiagram: [], 12 | }; 13 | 14 | 15 | const COMMANDS_TRIGER_REFRESH = ['CREATE_SCHEMA', 'DROP_SCHEMA']; 16 | 17 | 18 | export default function (state = INITIAL_STATE, action) { 19 | switch (action.type) { 20 | case connTypes.CONNECTION_REQUEST: { 21 | return action.isServerConnection 22 | ? { ...INITIAL_STATE, didInvalidate: true } 23 | : state; 24 | } 25 | case types.FETCH_SCHEMAS_REQUEST: { 26 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 27 | } 28 | case types.FETCH_SCHEMAS_SUCCESS: { 29 | return { 30 | ...state, 31 | isFetching: false, 32 | didInvalidate: false, 33 | itemsByDatabase: { 34 | ...state.itemsByDatabase, 35 | [action.database]: action.schemas.map(name => ({ name })), 36 | }, 37 | error: null, 38 | }; 39 | } 40 | case types.FETCH_SCHEMAS_FAILURE: { 41 | return { 42 | ...state, 43 | isFetching: false, 44 | didInvalidate: true, 45 | error: action.error, 46 | }; 47 | } 48 | case queryTypes.EXECUTE_QUERY_SUCCESS: { 49 | return { 50 | ...state, 51 | didInvalidate: action.results 52 | .some(({ command }) => COMMANDS_TRIGER_REFRESH.includes(command)), 53 | }; 54 | } 55 | case dbTypes.REFRESH_DATABASES: { 56 | return { 57 | ...state, 58 | didInvalidate: true, 59 | }; 60 | } 61 | case dbTypes.CLOSE_DATABASE_DIAGRAM: { 62 | return { 63 | ...state, 64 | selectedSchemasForDiagram: null, 65 | }; 66 | } 67 | default : return state; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/mui/reducers/schemas.js: -------------------------------------------------------------------------------- 1 | import * as connTypes from '../actions/connections'; 2 | import * as dbTypes from '../actions/databases'; 3 | import * as queryTypes from '../actions/queries'; 4 | import * as types from '../actions/schemas'; 5 | 6 | 7 | const INITIAL_STATE = { 8 | isFetching: false, 9 | didInvalidate: false, 10 | itemsByDatabase: {}, 11 | selectedTablesForDiagram: [], 12 | }; 13 | 14 | 15 | const COMMANDS_TRIGER_REFRESH = ['CREATE_SCHEMA', 'DROP_SCHEMA']; 16 | 17 | 18 | export default function (state = INITIAL_STATE, action) { 19 | switch (action.type) { 20 | case connTypes.CONNECTION_REQUEST: { 21 | return action.isServerConnection 22 | ? { ...INITIAL_STATE, didInvalidate: true } 23 | : state; 24 | } 25 | case types.FETCH_SCHEMAS_REQUEST: { 26 | return { ...state, isFetching: true, didInvalidate: false, error: null }; 27 | } 28 | case types.FETCH_SCHEMAS_SUCCESS: { 29 | return { 30 | ...state, 31 | isFetching: false, 32 | didInvalidate: false, 33 | itemsByDatabase: { 34 | ...state.itemsByDatabase, 35 | [action.database]: action.schemas.map(name => ({ name })), 36 | }, 37 | error: null, 38 | }; 39 | } 40 | case types.FETCH_SCHEMAS_FAILURE: { 41 | return { 42 | ...state, 43 | isFetching: false, 44 | didInvalidate: true, 45 | error: action.error, 46 | }; 47 | } 48 | case queryTypes.EXECUTE_QUERY_SUCCESS: { 49 | return { 50 | ...state, 51 | didInvalidate: action.results 52 | .some(({ command }) => COMMANDS_TRIGER_REFRESH.includes(command)), 53 | }; 54 | } 55 | case dbTypes.REFRESH_DATABASES: { 56 | return { 57 | ...state, 58 | didInvalidate: true, 59 | }; 60 | } 61 | case dbTypes.CLOSE_DATABASE_DIAGRAM: { 62 | return { 63 | ...state, 64 | selectedSchemasForDiagram: null, 65 | }; 66 | } 67 | default : return state; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/bs/actions/config.js: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep'; 2 | var { config, sqlectron }=window.myremote; 3 | export const LOAD_CONFIG_REQUEST = 'LOAD_CONFIG_REQUEST'; 4 | export const LOAD_CONFIG_SUCCESS = 'LOAD_CONFIG_SUCCESS'; 5 | export const LOAD_CONFIG_FAILURE = 'LOAD_CONFIG_FAILURE'; 6 | export const SAVE_CONFIG_REQUEST = 'SAVE_CONFIG_REQUEST'; 7 | export const SAVE_CONFIG_SUCCESS = 'SAVE_CONFIG_SUCCESS'; 8 | export const SAVE_CONFIG_FAILURE = 'SAVE_CONFIG_FAILURE'; 9 | export const START_EDITING_CONFIG = 'START_EDITING_CONFIG'; 10 | export const FINISH_EDITING_CONFIG = 'FINISH_EDITING_CONFIG'; 11 | 12 | export function loadConfig() { 13 | return async dispatch => { 14 | dispatch({ type: LOAD_CONFIG_REQUEST }); 15 | try { 16 | //console.log("loadConfig"); 17 | const forceCleanCache = true; 18 | const configPath = await sqlectron.config.path(); 19 | //console.log(configPath); 20 | const remoteConfig = await config.get(forceCleanCache); 21 | //console.log(remoteConfig); 22 | 23 | // Remove any "reference" to the remote IPC object 24 | const configData = cloneDeep(remoteConfig); 25 | 26 | dispatch({ type: LOAD_CONFIG_SUCCESS, config: configData, path: configPath }); 27 | } catch (error) { 28 | // console.log(error); 29 | dispatch({ type: LOAD_CONFIG_FAILURE, error }); 30 | } 31 | }; 32 | } 33 | 34 | 35 | export function saveConfig(configData) { 36 | // console.log("saveConfig"); 37 | return async dispatch => { 38 | dispatch({ type: SAVE_CONFIG_REQUEST }); 39 | try { 40 | // console.log(configData); 41 | await sqlectron.config.saveSettings(configData); 42 | dispatch({ type: SAVE_CONFIG_SUCCESS, config: configData }); 43 | } catch (error) { 44 | dispatch({ type: SAVE_CONFIG_FAILURE, error }); 45 | } 46 | }; 47 | } 48 | 49 | 50 | export function startEditing(id) { 51 | return { type: START_EDITING_CONFIG, id }; 52 | } 53 | 54 | 55 | export function finishEditing() { 56 | return { type: FINISH_EDITING_CONFIG }; 57 | } 58 | -------------------------------------------------------------------------------- /src/mui/actions/config.js: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep'; 2 | var { config, sqlectron }=window.myremote; 3 | export const LOAD_CONFIG_REQUEST = 'LOAD_CONFIG_REQUEST'; 4 | export const LOAD_CONFIG_SUCCESS = 'LOAD_CONFIG_SUCCESS'; 5 | export const LOAD_CONFIG_FAILURE = 'LOAD_CONFIG_FAILURE'; 6 | export const SAVE_CONFIG_REQUEST = 'SAVE_CONFIG_REQUEST'; 7 | export const SAVE_CONFIG_SUCCESS = 'SAVE_CONFIG_SUCCESS'; 8 | export const SAVE_CONFIG_FAILURE = 'SAVE_CONFIG_FAILURE'; 9 | export const START_EDITING_CONFIG = 'START_EDITING_CONFIG'; 10 | export const FINISH_EDITING_CONFIG = 'FINISH_EDITING_CONFIG'; 11 | 12 | export function loadConfig() { 13 | return async dispatch => { 14 | dispatch({ type: LOAD_CONFIG_REQUEST }); 15 | try { 16 | //console.log("loadConfig"); 17 | const forceCleanCache = true; 18 | const configPath = await sqlectron.config.path(); 19 | //console.log(configPath); 20 | const remoteConfig = await config.get(forceCleanCache); 21 | //console.log(remoteConfig); 22 | 23 | // Remove any "reference" to the remote IPC object 24 | const configData = cloneDeep(remoteConfig); 25 | 26 | dispatch({ type: LOAD_CONFIG_SUCCESS, config: configData, path: configPath }); 27 | } catch (error) { 28 | // console.log(error); 29 | dispatch({ type: LOAD_CONFIG_FAILURE, error }); 30 | } 31 | }; 32 | } 33 | 34 | 35 | export function saveConfig(configData) { 36 | // console.log("saveConfig"); 37 | return async dispatch => { 38 | dispatch({ type: SAVE_CONFIG_REQUEST }); 39 | try { 40 | // console.log(configData); 41 | await sqlectron.config.saveSettings(configData); 42 | dispatch({ type: SAVE_CONFIG_SUCCESS, config: configData }); 43 | } catch (error) { 44 | dispatch({ type: SAVE_CONFIG_FAILURE, error }); 45 | } 46 | }; 47 | } 48 | 49 | 50 | export function startEditing(id) { 51 | return { type: START_EDITING_CONFIG, id }; 52 | } 53 | 54 | 55 | export function finishEditing() { 56 | return { type: FINISH_EDITING_CONFIG }; 57 | } 58 | -------------------------------------------------------------------------------- /src/mui/store/configure.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import thunkMiddleware from 'redux-thunk'; 3 | import rootReducer from '../reducers'; 4 | import { createLogger } from 'redux-logger' 5 | const middlewares = [thunkMiddleware]; 6 | 7 | /* eslint global-require:0 */ 8 | console.log(window.myremote.config) 9 | var config=window.myremote.config.get(); 10 | const isLogConsoleEnabled = config.log.console; 11 | const isLogFileEnabled = config.log.file; 12 | 13 | if (isLogConsoleEnabled || isLogFileEnabled) { 14 | const loggerConfig = { 15 | level: config.log.level, 16 | collapsed: true, 17 | }; 18 | 19 | const mainLogger = isLogFileEnabled ? window.myremote.createLogger('renderer:redux') : null; 20 | 21 | loggerConfig.logger = {}; 22 | 23 | for (const method in console) { // eslint-disable-line no-restricted-syntax 24 | if (typeof console[method] === 'function') { // eslint-disable-line no-console 25 | loggerConfig.logger[method] = function levelFn(...args) { 26 | if (isLogConsoleEnabled) { 27 | const m = method === 'debug' ? 'log' : method; 28 | console[m].apply(console, args); // eslint-disable-line no-console 29 | } 30 | 31 | if (isLogFileEnabled) { 32 | // log on file only messages with error 33 | // otherwise is too much private information 34 | // the user would need to remove to issue a bug 35 | const lastArg = args[args.length - 1]; 36 | if (lastArg && lastArg.error) { 37 | mainLogger.error('Error', lastArg.error); 38 | mainLogger.error('Error Stack', lastArg.error.stack); 39 | } 40 | } 41 | }; 42 | } 43 | } 44 | 45 | middlewares.push(createLogger(loggerConfig)); 46 | } 47 | 48 | 49 | const createStoreWithMiddleware = applyMiddleware( 50 | ...middlewares 51 | )(createStore); 52 | 53 | 54 | export default function configureStore(initialState) { 55 | const store = createStoreWithMiddleware(rootReducer, initialState); 56 | return store; 57 | } 58 | --------------------------------------------------------------------------------