mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-01-18 21:17:59 +00:00
Added a nice welcome screen for first-time users
This commit is contained in:
parent
9f2445e596
commit
e7ff075744
@ -49,3 +49,8 @@ Feel free to contact me if you have questions! [Send an e-mail.](mailto:romein@v
|
|||||||
## Author and license
|
## Author and license
|
||||||
|
|
||||||
© [Romein van Buren](mailto:romein@vburen.nl) 2023. The source code and compiled binaries are released under the GNU GPLv3 license — see [LICENSE](./LICENSE) for the full license text.
|
© [Romein van Buren](mailto:romein@vburen.nl) 2023. The source code and compiled binaries are released under the GNU GPLv3 license — see [LICENSE](./LICENSE) for the full license text.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* Icons are from [Feather Icons](https://feathericons.com/) by [Cole Bemis](https://github.com/colebemis).
|
||||||
|
* Vector drawings come from [unDraw](https://undraw.co/).
|
||||||
|
195
frontend/.eslintrc.json
Normal file
195
frontend/.eslintrc.json
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
{
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:svelte/recommended"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"svelte",
|
||||||
|
"import"
|
||||||
|
],
|
||||||
|
"overrides": [{
|
||||||
|
"files": "*.svelte",
|
||||||
|
"rules": {
|
||||||
|
"no-inner-declarations": 0,
|
||||||
|
"svelte/no-inner-declarations": [
|
||||||
|
"error",
|
||||||
|
"functions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"rules": {
|
||||||
|
"no-undef": [
|
||||||
|
"error",
|
||||||
|
{ "typeof": true }
|
||||||
|
],
|
||||||
|
"require-atomic-updates": 0,
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
2,
|
||||||
|
{ "SwitchCase": 1 }
|
||||||
|
],
|
||||||
|
"strict": 0,
|
||||||
|
"quotes": [ "error", "single" ],
|
||||||
|
"semi": [ "warn", "always" ],
|
||||||
|
"accessor-pairs": "error",
|
||||||
|
"array-bracket-spacing": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"arrow-body-style": [
|
||||||
|
"error",
|
||||||
|
"as-needed",
|
||||||
|
{ "requireReturnForObjectLiteral": true }
|
||||||
|
],
|
||||||
|
"arrow-parens": [ "error", "as-needed" ],
|
||||||
|
"arrow-spacing": "error",
|
||||||
|
"block-spacing": [ "error", "always" ],
|
||||||
|
"comma-dangle": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"arrays": "always-multiline",
|
||||||
|
"objects": "always-multiline",
|
||||||
|
"imports": "never",
|
||||||
|
"exports": "never",
|
||||||
|
"functions": "never"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"comma-spacing": "error",
|
||||||
|
"computed-property-spacing": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"generator-star-spacing": "error",
|
||||||
|
"id-blacklist": "error",
|
||||||
|
"id-match": "error",
|
||||||
|
"jsx-quotes": "error",
|
||||||
|
"keyword-spacing": "error",
|
||||||
|
"key-spacing": [
|
||||||
|
"warn",
|
||||||
|
{ "beforeColon": false }
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"no-unused-vars": "warn",
|
||||||
|
"no-alert": "error",
|
||||||
|
"no-caller": "error",
|
||||||
|
"no-confusing-arrow": [
|
||||||
|
"error",
|
||||||
|
{ "allowParens": true }
|
||||||
|
],
|
||||||
|
"no-console": "off",
|
||||||
|
"no-div-regex": "error",
|
||||||
|
"no-duplicate-imports": "error",
|
||||||
|
"no-extend-native": "error",
|
||||||
|
"no-extra-label": "error",
|
||||||
|
"no-fallthrough": "off",
|
||||||
|
"no-floating-decimal": "error",
|
||||||
|
"no-implicit-coercion": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"boolean": false,
|
||||||
|
"number": false,
|
||||||
|
"string": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-inner-declarations": [
|
||||||
|
"error",
|
||||||
|
"functions"
|
||||||
|
],
|
||||||
|
"no-iterator": "error",
|
||||||
|
"no-label-var": "error",
|
||||||
|
"no-lone-blocks": "error",
|
||||||
|
"no-new-object": "error",
|
||||||
|
"no-new-require": "error",
|
||||||
|
"no-new-wrappers": "error",
|
||||||
|
"no-restricted-globals": [
|
||||||
|
"error",
|
||||||
|
"event",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"no-restricted-imports": "error",
|
||||||
|
"no-restricted-modules": "error",
|
||||||
|
"no-restricted-syntax": "error",
|
||||||
|
"no-script-url": "error",
|
||||||
|
"no-self-compare": "error",
|
||||||
|
"no-sequences": "error",
|
||||||
|
"no-shadow-restricted-names": "error",
|
||||||
|
"no-spaced-func": "error",
|
||||||
|
"no-trailing-spaces": "error",
|
||||||
|
"no-unmodified-loop-condition": "error",
|
||||||
|
"no-useless-constructor": "error",
|
||||||
|
"no-whitespace-before-property": "error",
|
||||||
|
"no-with": "error",
|
||||||
|
"object-curly-spacing": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"require-yield": "error",
|
||||||
|
"semi-spacing": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"space-before-blocks": "error",
|
||||||
|
"space-before-function-paren": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"space-in-parens": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"space-infix-ops": "error",
|
||||||
|
"space-unary-ops": "error",
|
||||||
|
"template-curly-spacing": "error",
|
||||||
|
"curly": 2,
|
||||||
|
"brace-style": [
|
||||||
|
"error",
|
||||||
|
"stroustrup"
|
||||||
|
],
|
||||||
|
"wrap-iife": [
|
||||||
|
"error",
|
||||||
|
"any"
|
||||||
|
],
|
||||||
|
"yield-star-spacing": "error",
|
||||||
|
"multiline-ternary": [
|
||||||
|
"warn",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"no-nested-ternary": "error",
|
||||||
|
"svelte/html-quotes": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"prefer": "double",
|
||||||
|
"dynamic": { "quoted": false }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"svelte/no-useless-mustaches": "warn",
|
||||||
|
"svelte/require-store-reactive-access": "warn",
|
||||||
|
"svelte/no-reactive-literals": "error",
|
||||||
|
"svelte/html-closing-bracket-spacing": "warn",
|
||||||
|
"svelte/indent": "warn",
|
||||||
|
"svelte/max-attributes-per-line": [
|
||||||
|
"warn",
|
||||||
|
{ "multiline": 1, "singleline": 5 }
|
||||||
|
],
|
||||||
|
"svelte/mustache-spacing": "warn",
|
||||||
|
"svelte/no-extra-reactive-curlies": "error",
|
||||||
|
"svelte/no-spaces-around-equal-signs-in-attribute": "warn",
|
||||||
|
"svelte/prefer-class-directive": "warn",
|
||||||
|
"svelte/shorthand-attribute": "warn",
|
||||||
|
"svelte/shorthand-directive": "warn",
|
||||||
|
"svelte/spaced-html-comment": "warn",
|
||||||
|
"svelte/no-at-html-tags": 0
|
||||||
|
}
|
||||||
|
}
|
2687
frontend/package-lock.json
generated
2687
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -19,15 +19,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
||||||
"eslint": "^8.41.0",
|
"eslint": "^8.41.0",
|
||||||
"eslint-config-nodejs": "github:johbog/eslint-config-nodejs",
|
|
||||||
"eslint-config-svelte3": "github:johbog/eslint-config-svelte3",
|
|
||||||
"svelte": "^3.59.1",
|
"svelte": "^3.59.1",
|
||||||
"vite": "^3.0.0"
|
"vite": "^3.0.0"
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"nodejs",
|
|
||||||
"svelte3"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
31b52e0807538bc37610b6879820037f
|
d933a4e16d5bb0132361eef3b5d3ba22
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 27 KiB |
@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import BlankState from '$components/blankstate.svelte';
|
||||||
import ContextMenu from '$components/contextmenu.svelte';
|
import ContextMenu from '$components/contextmenu.svelte';
|
||||||
import { connections } from '$lib/stores/connections';
|
import { connections } from '$lib/stores/connections';
|
||||||
import contextMenu from '$lib/stores/contextmenu';
|
import contextMenu from '$lib/stores/contextmenu';
|
||||||
@ -7,7 +8,8 @@
|
|||||||
import About from '$organisms/about.svelte';
|
import About from '$organisms/about.svelte';
|
||||||
import Connection from '$organisms/connection/index.svelte';
|
import Connection from '$organisms/connection/index.svelte';
|
||||||
import Settings from '$organisms/settings/index.svelte';
|
import Settings from '$organisms/settings/index.svelte';
|
||||||
import { EventsOn } from '$wails/runtime';
|
import { EventsEmit, EventsOn } from '$wails/runtime';
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
|
||||||
const hosts = {};
|
const hosts = {};
|
||||||
const activeHostKey = '';
|
const activeHostKey = '';
|
||||||
@ -15,11 +17,18 @@
|
|||||||
let activeCollKey = '';
|
let activeCollKey = '';
|
||||||
let settingsModalOpen = false;
|
let settingsModalOpen = false;
|
||||||
let aboutModalOpen = false;
|
let aboutModalOpen = false;
|
||||||
|
let connectionManager;
|
||||||
|
let showWelcomeScreen = false;
|
||||||
|
|
||||||
$: host = hosts[activeHostKey];
|
$: host = hosts[activeHostKey];
|
||||||
$: connection = $connections[activeHostKey];
|
$: connection = $connections[activeHostKey];
|
||||||
$: database = connection?.databases[activeDbKey];
|
$: showWelcomeScreen = !Object.keys(hosts).length;
|
||||||
$: collection = database?.collections?.[activeCollKey];
|
|
||||||
|
async function createFirstHost() {
|
||||||
|
showWelcomeScreen = false;
|
||||||
|
await tick();
|
||||||
|
connectionManager.createHost();
|
||||||
|
}
|
||||||
|
|
||||||
EventsOn('OpenPrefrences', () => settingsModalOpen = true);
|
EventsOn('OpenPrefrences', () => settingsModalOpen = true);
|
||||||
EventsOn('OpenAboutModal', () => aboutModalOpen = true);
|
EventsOn('OpenAboutModal', () => aboutModalOpen = true);
|
||||||
@ -31,8 +40,14 @@
|
|||||||
<div class="titlebar"></div>
|
<div class="titlebar"></div>
|
||||||
|
|
||||||
{#if $applicationInited}
|
{#if $applicationInited}
|
||||||
<main class:empty={!host || !connection}>
|
<main class:empty={showWelcomeScreen}>
|
||||||
<Connection {hosts} bind:activeCollKey bind:activeDbKey {activeHostKey} />
|
{#if showWelcomeScreen}
|
||||||
|
<BlankState label="Welcome to Rolens!" image="/logo.png" pale={false} big={true}>
|
||||||
|
<button class="btn" on:click={createFirstHost}>Add your first host</button>
|
||||||
|
</BlankState>
|
||||||
|
{:else}
|
||||||
|
<Connection {hosts} {activeHostKey} bind:activeCollKey bind:activeDbKey bind:this={connectionManager} />
|
||||||
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{#key $contextMenu}
|
{#key $contextMenu}
|
||||||
@ -59,6 +74,9 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template: 1fr / minmax(300px, 0.3fr) 1fr;
|
grid-template: 1fr / minmax(300px, 0.3fr) 1fr;
|
||||||
}
|
}
|
||||||
|
main.empty {
|
||||||
|
grid-template: 1fr / 1fr;
|
||||||
|
}
|
||||||
#root.platform-darwin main {
|
#root.platform-darwin main {
|
||||||
height: calc(100vh - var(--darwin-titlebar-height));
|
height: calc(100vh - var(--darwin-titlebar-height));
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
<script>
|
<script>
|
||||||
export let label = 'No items';
|
export let label = 'No items';
|
||||||
export let image = '/empty.svg';
|
export let image = '/empty.svg';
|
||||||
|
export let pale = true;
|
||||||
|
export let big = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="blankstate">
|
<div class="blankstate" class:pale class:big>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<img src={image} alt="">
|
<img src={image} alt="" />
|
||||||
<p>{label}</p>
|
<p>{label}</p>
|
||||||
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -14,20 +17,38 @@
|
|||||||
.blankstate {
|
.blankstate {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100px;
|
height: 150px;
|
||||||
width: auto;
|
width: auto;
|
||||||
filter: grayscale(1);
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 2rem;
|
margin: 2.85rem 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blankstate :global(.btn) {
|
||||||
|
font-size: 1.35rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.big p {
|
||||||
|
font-size: 1.9rem;
|
||||||
|
line-height: 1.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pale img {
|
||||||
|
filter: grayscale(1);
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.pale p {
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.inner > :global(*:first-child) {
|
.inner > :global(*:first-child) {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -98,6 +99,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
header .title {
|
header .title {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
hosts = await Hosts();
|
hosts = await Hosts();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createHost() {
|
export function createHost() {
|
||||||
hostDetailKey = '';
|
hostDetailKey = '';
|
||||||
showHostDetail = true;
|
showHostDetail = true;
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@
|
|||||||
showHostDetail = true;
|
showHostDetail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createDatabase() {
|
export async function createDatabase() {
|
||||||
const name = await EnterText('Create a database', 'Enter the database name. Note: databases in MongoDB do not exist until they have a collection and an item. Your new database will not persist on the server; fill it to have it created.');
|
const name = await EnterText('Create a database', 'Enter the database name. Note: databases in MongoDB do not exist until they have a collection and an item. Your new database will not persist on the server; fill it to have it created.');
|
||||||
if (name) {
|
if (name) {
|
||||||
$connections[activeHostKey].databases[name] = { collections: {} };
|
$connections[activeHostKey].databases[name] = { collections: {} };
|
||||||
@ -59,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCollection() {
|
export async function createCollection() {
|
||||||
const name = await EnterText('Create a collection', 'Note: collections in MongoDB do not exist until they have at least one item. Your new collection will not persist on the server; fill it to have it created.');
|
const name = await EnterText('Create a collection', 'Note: collections in MongoDB do not exist until they have at least one item. Your new collection will not persist on the server; fill it to have it created.');
|
||||||
if (name) {
|
if (name) {
|
||||||
$connections[activeHostKey].databases[activeDbKey].collections[name] = {};
|
$connections[activeHostKey].databases[activeDbKey].collections[name] = {};
|
||||||
|
Loading…
Reference in New Issue
Block a user