Skip to content

Commit

Permalink
Merge pull request #33 from dblens/upgrade/pg
Browse files Browse the repository at this point in the history
allow users to disconnect form a database
  • Loading branch information
soorajshankar authored Feb 23, 2022
2 parents 267e156 + c49064b commit 770573b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 21 deletions.
30 changes: 29 additions & 1 deletion src/components/MainScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import React, { useState } from 'react';
/* eslint-disable no-alert */
/* eslint-disable no-restricted-globals */
import React, { useEffect, useState } from 'react';
import electron from 'electron';
import DbSession from '../sessions/DbSession';
import OverviewScreen from './Overview/OverviewScreen';
import SqlScreen from './SqlScreen';
Expand All @@ -7,6 +10,7 @@ import TableScreen from './TableScreen';
import Titlebar from './Titlebar';
import ErdContainer from './ERD/ErdContainer';
import SettingsContainer from './Settings/SettingsContainer';
import { useAppState } from '../state/AppProvider';

interface MainScreenProps {
session: DbSession;
Expand All @@ -18,6 +22,30 @@ const MainScreen: React.FC<MainScreenProps> = ({
session,
}: MainScreenProps) => {
const [selectedTab, setSelectedTab] = useState('OVERVIEW');
const [, dispatch] = useAppState();

const disconnect = async () => {
if (confirm('Are you sure want to disconnect from the database?')) {
const { status } = await electron.ipcRenderer.invoke('disconnect');
if (status === 'DISCONNECTED') {
dispatch({
type: 'CLEAR_SESSION',
});
}
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const escFunction = (e: KeyboardEvent) => {
if (e.code === 'Escape' && session) {
disconnect();
}
};
useEffect(() => {
document.addEventListener('keydown', escFunction, false);
return () => {
document.removeEventListener('keydown', escFunction, false);
};
}, [escFunction]);

return (
<div className="w-screen h-screen max-h-screen text-gray-800 focus:font-bold focus:outline-none">
Expand Down
35 changes: 33 additions & 2 deletions src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/* eslint-disable no-alert */
/* eslint-disable no-restricted-globals */
import React from 'react';
import electron from 'electron';
import ReactTooltip from 'react-tooltip';
import { useAppState } from '../state/AppProvider';

interface SidebarProps {
selectedTab: string;
Expand Down Expand Up @@ -49,9 +54,35 @@ const Sidebar: React.FC<SidebarProps> = ({
selectedTab,
setSelectedTab,
}: SidebarProps) => {
const [, dispatch] = useAppState();

const disconnect = async () => {
if (confirm('Are you sure want to disconnect from the database?')) {
const { status } = await electron.ipcRenderer.invoke('disconnect');
if (status === 'DISCONNECTED') {
dispatch({
type: 'CLEAR_SESSION',
});
}
}
};
return (
<div className="bg-gray-900 text-gray-100 w-12 pt-8 flex flex-col border border-gray-700 text-xs">
<button type="button" className="mb-4">
<div className="bg-gray-900 text-gray-100 w-12 flex flex-col border border-gray-700 text-xs">
<button
type="button"
className="m-2 text-sm text-green-600 font-bold animate-ping"
onClick={disconnect}
data-tip
data-for="btn-disconnect"
>
<span role="img" aria-label="app-icon" className="p-2 font-mono">
</span>
</button>
<ReactTooltip id="btn-disconnect" type="dark" place="right">
<span>Click to Disconnect from the database</span>
</ReactTooltip>
<button type="button" className="mb-4 pt-4">
<span
role="img"
aria-label="app-icon"
Expand Down
12 changes: 8 additions & 4 deletions src/electron/DBHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { BrowserWindow } from 'electron';
import { IpcMainInvokeEvent } from 'electron/main';
import { Client, ClientBase } from 'pg';

const connections: Record<
string,
{ client: ClientBase; window: BrowserWindow }
> = {};
let connections: Record<string, { client: ClientBase; window: BrowserWindow }> =
{};

export const connectDB = async ({
window,
Expand Down Expand Up @@ -46,6 +44,12 @@ export const connectDB = async ({
return { status: 'FAILED', uuid };
};

export const disconnectDB = async () => {
connections = {};

return { status: 'DISCONNECTED' };
};

export const sqlExecute = async (
_: IpcMainInvokeEvent,
{ uuid = '', sql = 'SELECT NOW();' } = {}
Expand Down
43 changes: 29 additions & 14 deletions src/main.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import path from 'path';
import { app, BrowserWindow, shell, ipcMain, screen } from 'electron';
import {
app,
BrowserWindow,
shell,
ipcMain,
screen,
dialog,
IpcMainEvent,
} from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import { connectDB, sqlExecute } from './electron/DBHandler';

import MenuBuilder from './menu';
import { IpcMainEvent } from 'electron/main';
import { dialog } from 'electron';
import fs from 'fs';
import MenuBuilder from './menu';
import { connectDB, disconnectDB, sqlExecute } from './electron/DBHandler';

const { format } = require('@fast-csv/format');

export default class AppUpdater {
Expand Down Expand Up @@ -160,7 +166,7 @@ app.on('activate', () => {
if (mainWindow === null) createWindow();
});

ipcMain.on('ExportCSV', (_: IpcMainEvent, params: any) => {
ipcMain.on('ExportCSV', (_: IpcMainEvent, params) => {
const { fileName, data } = params;

dialog
Expand All @@ -172,27 +178,29 @@ ipcMain.on('ExportCSV', (_: IpcMainEvent, params: any) => {
filters: [{ name: 'CSV files', extensions: ['csv'] }],
properties: [],
})
.then((file: any) => {
.then((file: Electron.SaveDialogReturnValue) => {
// Stating whether dialog operation was cancelled or not.
console.log(file.canceled);
if (!file.canceled) {
let items: unknown[] = [];
const items: unknown[] = [];

const stream = format({ headers: true });
const fileName = file.filePath.toString();
const csvFile = fs.createWriteStream(fileName);
const filePath = file?.filePath?.toString() ?? '/Downloads';
const csvFile = fs.createWriteStream(filePath);
stream.pipe(csvFile);
data.forEach((el: Record<string, any>, i: number) => {
const parsed: Record<string, any> = {};
Object.entries(el).forEach(([key, value]: [any, any]) => {
data.forEach((el: Record<string, unknown>, i: number) => {
const parsed: Record<string, unknown> = {};
Object.entries(el).forEach(([key, value]: [string, unknown]) => {
parsed[key] =
typeof value === 'object' ? JSON.stringify(value) : value;
});
items.push(parsed);
stream.write(items[i]);
});
stream.end();
return 1;
}
return 0;
})
.catch((err) => {
console.log(err);
Expand All @@ -209,6 +217,13 @@ ipcMain.handle('connect', async (_, params) => {
return res;
});

ipcMain.handle('disconnect', async () => {
console.log('disconnect');
// console.log(JSON.stringify({ params }, null, 2));
const res = await disconnectDB();
return res;
});

ipcMain.handle('SQL_EXECUTE', sqlExecute);

// Define custom protocol handler.
Expand Down
3 changes: 3 additions & 0 deletions src/state/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface AppState {

export type AppStateActions =
| { type: 'SET_SESSION'; payload: DbSession }
| { type: 'CLEAR_SESSION' }
| { type: 'SET_HISTORY'; payload: HistoryType[] }
| { type: 'ADD_HISTORY'; payload: HistoryType }
| { type: 'REMOVE_HISTORY'; payload: number }
Expand All @@ -29,6 +30,8 @@ export function appReducer(
switch (action.type) {
case 'SET_SESSION':
return { ...state, session: action.payload };
case 'CLEAR_SESSION':
return { ...state, session: undefined };
case 'SET_HISTORY':
return { ...state, history: action.payload };
case 'ADD_HISTORY':
Expand Down

0 comments on commit 770573b

Please sign in to comment.