initial commit

This commit is contained in:
José Conde
2023-03-14 18:29:01 +01:00
parent a13c963a75
commit a22c74393f
41 changed files with 42730 additions and 1132 deletions

36
app/config.js Normal file
View File

@ -0,0 +1,36 @@
const fs = require('fs-extra');
const path = require('path');
const { app } = require('electron');
const userDataPath = app.getPath('userData');
const CONFIG_FILE_NAME = 'timesheet-config.json';
const configPath = path.join(userDataPath, CONFIG_FILE_NAME);
function initializeConfig() {
const initial = require('./config.json');
saveConfig(initial);
}
function saveConfig(config) {
console.log('Saving: ' + JSON.stringify(config));
fs.writeJSONSync(configPath, config, {
encoding: 'utf-8',
spaces: 2
});
}
function getConfig() {
if (!fs.existsSync(configPath)) {
initializeConfig();
}
const options = fs.readJSONSync(configPath, 'utf-8');
return options;
}
function setConfig(config) {
saveConfig(config);
}
module.exports = {
getConfig,
setConfig
};

6
app/config.json Normal file
View File

@ -0,0 +1,6 @@
{
"secondsToReload": 60,
"cutDay": 6,
"cutHour": 4,
"timezone": "America/Denver"
}

18
app/dist/index.html vendored Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Salud y Vida PA | Timesheet - 1.5.0</title>
<script type="module" crossorigin src="./assets/index.680f16a8.js"></script>
<link rel="stylesheet" href="./assets/index.6a5e126f.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

1
app/dist/vite.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

33
app/index.htm_ Normal file
View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src *;">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Fire Sale</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<section class="controls">
<button id="new-file">New File</button>
<button id="open-file">Open File</button>
<button id="save-markdown" disabled>Save File</button>
<button id="revert" disabled>Revert</button>
<button id="save-html">Save HTML</button>
<button id="show-file" disabled>Show File</button>
<button id="open-in-default" disabled>Open in Default Application</button>
</section>
<section class="content">
<label for="markdown" hidden>Markdown Content</label>
<textarea class="raw-markdown" id="markdown"></textarea>
<div class="rendered-html" id="html"></div>
</section>
</body>
<script src="./renderer.js"></script>
</html>

34
app/index.html Normal file
View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<title>Hello from Electron renderer!</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
<p id="info"></p>
<section class="controls">
<button id="new-file">New File</button>
<button id="open-file">Open File</button>
<button id="save-markdown" disabled>Save File</button>
<button id="revert" disabled>Revert</button>
<button id="save-html">Save HTML</button>
<button id="show-file" disabled>Show File</button>
<button id="open-in-default" disabled>Open in Default Application</button>
</section>
<section class="content">
<label for="markdown" hidden>Markdown Content</label>
<textarea class="raw-markdown" id="markdown"></textarea>
<div class="rendered-html" id="html"></div>
</section>
</body>
<script src="./renderer.js"></script>
</html>

57
app/main.js Normal file
View File

@ -0,0 +1,57 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const { post } = require('./request')
const { deputyUrl, deputyToken } = require('../env.json');
const { getConfig, setConfig } = require('./config');
function createWindow() {
const mainWindow = new BrowserWindow({
width: 1440,
height: 900,
show: false,
icon: path.join(__dirname, 'favicon-32x32.png'),
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
allowRunningInsecureContent: true,
}
});
ipcMain.handle('getTimesheet', async(event, body) => {
try {
const { apitoken } = getConfig();
const token = apitoken || deputyToken;
return await post(deputyUrl, body, { Authorization: `OAuth ${token}` });
} catch (err) {
console.log('err :>> ', err);
}
});
ipcMain.handle('getAppConfig', () => {
const config = getConfig();
return {... { apitoken: deputyToken }, ...config };
});
ipcMain.handle('setAppConfig', (event, config) => {
return setConfig(config);
})
mainWindow.maximize();
mainWindow.removeMenu();
mainWindow.loadFile(path.join(__dirname, '..', 'ui', 'dist', 'index.html'));
// Open the DevTools.
// mainWindow.webContents.openDevTools();
mainWindow.show();
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
})
});
app.on('window-all-closed', function() {
if (process.platform !== 'darwin') app.quit()
});

16
app/preload.js Normal file
View File

@ -0,0 +1,16 @@
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('IS_ELECTRON', true);
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
app: () => '1.2.2',
});
contextBridge.exposeInMainWorld('services', {
getTimesheet: (body) => ipcRenderer.invoke('getTimesheet', body),
getConfig: () => ipcRenderer.invoke('getAppConfig'),
setConfig: config => ipcRenderer.invoke('setAppConfig', config),
});

7
app/renderer.js Normal file
View File

@ -0,0 +1,7 @@
const func = async() => {
const response = window.versions.app
console.log(response);
window.title += ` ${window.versions.app}`;
}
func();

64
app/request.js Normal file
View File

@ -0,0 +1,64 @@
const { net } = require('electron');
async function get(url, headers) {
return request({ url, method: 'GET', headers })
}
async function post(url, body, headers) {
return request({ url, method: 'POST', headers }, body)
}
async function request(options, body) {
return new Promise((resolve, reject) => {
const responseBody = [];
let responseHeaders;
let responseStatus;
const request = net.request(options);
request.on('response', (response) => {
responseStatus = response.statusCode;
responseHeaders = response.headers;
response.on('data', (chunk) => {
if (chunk) {
responseBody.push(`${chunk}`);
}
});
response.on('end', () => {
resolve({
status: responseStatus,
headers: responseHeaders,
body: parseReponseBody(responseBody),
});
});
response.on('aborted', () => console.log('request aborted'));
response.on('error', (error) => reject(error));
});
request.on('error', (error) => reject(error));
request.setHeader('Content-Type', 'application/json');
if (['POST'].includes(options.method.toUpperCase())) {
request.write(JSON.stringify(body), 'utf-8')
}
request.end();
});
}
function parseReponseBody(body) {
if (Array.isArray(body)) {
if (body.length) {
return JSON.parse(body.join(''));
}
}
}
module.exports = {
get,
post
};

99
app/style.css Normal file
View File

@ -0,0 +1,99 @@
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
}
body {
margin: 0;
padding: 0;
position: absolute;
}
body,
input {
font: menu;
}
textarea,
input,
div,
button {
outline: none;
margin: 0;
}
.controls {
background-color: rgb(217, 241, 238);
padding: 10px 10px 10px 10px;
}
button {
font-size: 14px;
background-color: rgb(181, 220, 216);
border: none;
padding: 0.5em 1em;
}
button:hover {
background-color: rgb(156, 198, 192);
}
button:active {
background-color: rgb(144, 182, 177);
}
button:disabled {
background-color: rgb(196, 204, 202);
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
min-width: 100vw;
position: relative;
}
.content {
height: 100vh;
display: flex;
}
.raw-markdown,
.rendered-html {
min-height: 100%;
max-width: 50%;
flex-grow: 1;
padding: 1em;
overflow: scroll;
font-size: 16px;
}
.raw-markdown {
border: 5px solid rgb(238, 252, 250);
;
background-color: rgb(238, 252, 250);
font-family: monospace;
}
.raw-markdown.drag-over {
background-color: rgb(181, 220, 216);
border-color: rgb(75, 160, 151);
}
.raw-markdown.drag-error {
background-color: rgba(170, 57, 57, 1);
border-color: rgba(255, 170, 170, 1);
}