1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-06-28 05:25:11 +00:00

46 Commits

Author SHA1 Message Date
4001614d49 Merge 01405b49ef into 21089009b4 2024-08-04 12:46:20 +02:00
21089009b4 Update Actions dependencies 2024-08-04 12:43:55 +02:00
1551a5073b Upgrade actions/upload-artifact to v4 2024-08-04 12:38:14 +02:00
e54a39bb3e Update CI platforms 2024-08-04 12:37:35 +02:00
949d609167 Update vulnerable dependencies 2024-08-04 12:23:55 +02:00
3ac85342bd Add favicons, compress logo 2024-06-25 15:10:35 +02:00
c14894fb31 Make sure WebP files are copied over to doc site 2024-06-25 15:05:17 +02:00
27ebbbc898 Replace PNG screenshots with WebP ones 2024-06-25 15:03:22 +02:00
9ce6a58afc It is 2024 (quite a while, actually) 2024-06-25 10:49:47 +02:00
ca5cdc203a Replaced hasMongoDump with hasMongoShell 2024-06-25 10:47:03 +02:00
01405b49ef Bump vite from 3.2.7 to 3.2.10 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 3.2.7 to 3.2.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v3.2.10/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v3.2.10/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-03 18:40:17 +00:00
132df17ff7 Updated readme on shell scripts 2023-12-23 14:45:17 +01:00
8a1f170121 Prepare v0.3.0 2023-12-23 14:20:12 +01:00
b04d0b324a Add modal transitions 2023-12-23 14:17:39 +01:00
4e68bf324c Correctly open settings & about dialogs 2023-12-23 14:10:48 +01:00
3a325fe064 Run CI using Node.js v18 2023-12-23 13:20:51 +01:00
9f9ba2de6a Updated ci_bundle script 2023-12-23 13:08:56 +01:00
42993b28e9 Generate DMG images for macOS instead of placing .app in tarball 2023-12-23 13:02:38 +01:00
6af1f4a028 Upgrade Go to 1.21 2023-12-23 12:28:27 +01:00
fca08479e8 Add startup animation 2023-12-23 12:05:46 +01:00
d90d5bcf63 Updated tab bar animation 2023-12-23 11:54:10 +01:00
421bde13f5 Upgrade Wails to 2.7.1 2023-12-23 11:51:35 +01:00
fd1340f9e4 Add nice loading indicator to the host tree 2023-12-22 17:05:32 +01:00
426b0b8468 Slightly modified icons in grid 2023-12-22 16:33:10 +01:00
990c1d3d00 Add padding for field inputs 2023-12-22 16:25:18 +01:00
79417fcaa3 Updated readme slightly 2023-12-22 16:04:13 +01:00
7687b094c8 Changed os.ModePerm (777) file permissions to 644 and 755 2023-12-22 16:00:54 +01:00
773bcf65fd Add option to save shell output 2023-12-22 15:56:00 +01:00
82b8f1e300 Remove path prefix for website 2023-12-22 15:36:12 +01:00
3a5bee4a81 Added CNAME for Rolens website 2023-12-22 15:29:08 +01:00
ef9318576a Removed Zenity dependency 2023-12-22 15:26:29 +01:00
208db82ba7 Update packages 2023-12-22 15:10:56 +01:00
ddb3fefae5 Bump golang.org/x/crypto from 0.1.0 to 0.17.0 (#67)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.1.0
to 0.17.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9d2ee975ef"><code>9d2ee97</code></a>
ssh: implement strict KEX protocol changes</li>
<li><a
href="4e5a26183e"><code>4e5a261</code></a>
ssh: close net.Conn on all NewServerConn errors</li>
<li><a
href="152cdb1503"><code>152cdb1</code></a>
x509roots/fallback: update bundle</li>
<li><a
href="fdfe1f8531"><code>fdfe1f8</code></a>
ssh: defer channel window adjustment</li>
<li><a
href="b8ffc16e10"><code>b8ffc16</code></a>
blake2b: drop Go 1.6, Go 1.8 compatibility</li>
<li><a
href="7e6fbd82c8"><code>7e6fbd8</code></a>
ssh: wrap errors from client handshake</li>
<li><a
href="bda2f3f5cf"><code>bda2f3f</code></a>
argon2: avoid clobbering BP</li>
<li><a
href="325b735346"><code>325b735</code></a>
ssh/test: skip TestSSHCLIAuth on Windows</li>
<li><a
href="1eadac50a5"><code>1eadac5</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="b2d7c26edb"><code>b2d7c26</code></a>
ssh: add (*Client).DialContext method</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/crypto/compare/v0.1.0...v0.17.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/crypto&package-manager=go_modules&previous-version=0.1.0&new-version=0.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/garraflavatra/rolens/network/alerts).

</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Romein van Buren <romein@vburen.nl>
2023-12-22 15:04:44 +01:00
5b35172db9 Update screen shot 2023-12-22 14:38:20 +01:00
7f2adb2df2 Bump required Go version to 1.20 2023-12-22 14:15:46 +01:00
2040a356fd Finish sliding active tab indicator 2023-12-22 14:04:38 +01:00
9eac9ae935 Add sliding active tab indicator 2023-12-22 14:02:58 +01:00
d1b1c7daa5 UI improvements 2023-12-22 13:30:05 +01:00
db5a526e07 Bump postcss from 8.4.27 to 8.4.31 in /frontend (#64)
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.27 to
8.4.31.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.4.31</h2>
<ul>
<li>Fixed <code>\r</code> parsing to fix CVE-2023-44270.</li>
</ul>
<h2>8.4.30</h2>
<ul>
<li>Improved source map performance (by <a
href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
</ul>
<h2>8.4.29</h2>
<ul>
<li>Fixed <code>Node#source.offset</code> (by <a
href="https://github.com/idoros"><code>@​idoros</code></a>).</li>
<li>Fixed docs (by <a
href="https://github.com/coliff"><code>@​coliff</code></a>).</li>
</ul>
<h2>8.4.28</h2>
<ul>
<li>Fixed <code>Root.source.end</code> for better source map (by <a
href="https://github.com/romainmenke"><code>@​romainmenke</code></a>).</li>
<li>Fixed <code>Result.root</code> types when <code>process()</code> has
no parser.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.4.31</h2>
<ul>
<li>Fixed <code>\r</code> parsing to fix CVE-2023-44270.</li>
</ul>
<h2>8.4.30</h2>
<ul>
<li>Improved source map performance (by Romain Menke).</li>
</ul>
<h2>8.4.29</h2>
<ul>
<li>Fixed <code>Node#source.offset</code> (by Ido Rosenthal).</li>
<li>Fixed docs (by Christian Oliff).</li>
</ul>
<h2>8.4.28</h2>
<ul>
<li>Fixed <code>Root.source.end</code> for better source map (by Romain
Menke).</li>
<li>Fixed <code>Result.root</code> types when <code>process()</code> has
no parser.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="90208de880"><code>90208de</code></a>
Release 8.4.31 version</li>
<li><a
href="58cc860b4c"><code>58cc860</code></a>
Fix carrier return parsing</li>
<li><a
href="4fff8e4cdc"><code>4fff8e4</code></a>
Improve pnpm test output</li>
<li><a
href="cd43ed1232"><code>cd43ed1</code></a>
Update dependencies</li>
<li><a
href="caa916bdcb"><code>caa916b</code></a>
Update dependencies</li>
<li><a
href="8972f76923"><code>8972f76</code></a>
Typo</li>
<li><a
href="11a5286f78"><code>11a5286</code></a>
Typo</li>
<li><a
href="45c5501777"><code>45c5501</code></a>
Release 8.4.30 version</li>
<li><a
href="bc3c341f58"><code>bc3c341</code></a>
Update linter</li>
<li><a
href="b2be58a2eb"><code>b2be58a</code></a>
Merge pull request <a
href="https://redirect.github.com/postcss/postcss/issues/1881">#1881</a>
from romainmenke/improve-sourcemap-performance--phil...</li>
<li>Additional commits viewable in <a
href="https://github.com/postcss/postcss/compare/8.4.27...8.4.31">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=postcss&package-manager=npm_and_yarn&previous-version=8.4.27&new-version=8.4.31)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/garraflavatra/rolens/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-08 20:51:31 +02:00
621af884b5 Centered modal 2023-08-27 15:25:37 +02:00
a01c56ab69 Fixed selected item highlighting bug in grid 2023-08-26 20:39:47 +02:00
1b834de091 Updated host menu items 2023-08-26 20:27:44 +02:00
70245bd38b Point to wails doctor documentation 2023-08-26 20:24:19 +02:00
9be36fda7f Corrected some imports 2023-08-07 18:28:21 +02:00
4370672d60 Lint code 2023-08-07 18:21:45 +02:00
7cebafeff3 Use yeslint! as configuration for ESLint 2023-08-07 17:51:30 +02:00
110 changed files with 1147 additions and 777 deletions

View File

@ -1,10 +1,8 @@
name: CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
- push
- pull_request
jobs:
build:
@ -16,22 +14,23 @@ jobs:
platform:
- windows-2019
- windows-2022
- macos-11
- macos-12
- macos-13
- macos-14
- ubuntu-20.04
- ubuntu-22.04
go-version: [1.18]
node-version: [16]
- ubuntu-24.04
go-version: [ 1.21 ]
node-version: [ 18 ]
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache-dependency-path: go.sum
@ -48,7 +47,7 @@ jobs:
run: sudo apt-get install gtk+-3.0 webkit2gtk-4.0
- name: Set up Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
@ -67,7 +66,7 @@ jobs:
run: ./build/linux/ci_generate.sh "${{ matrix.platform }}"
- name: Upload generated binaries
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: rolens-${{ matrix.platform }}
path: releases/*
@ -94,7 +93,7 @@ jobs:
run: build/ci_bundle.sh
- name: Upload the bundle as an artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: rolens-bundle
path: bundle

View File

@ -22,24 +22,26 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
- name: Setup Pages
uses: actions/configure-pages@v3
uses: actions/configure-pages@v5
- name: Install dependencies
run: cd website; npm ci
run: npm ci
working-directory: website
- name: Build site
run: cd website; npm run build
run: npm run build
working-directory: website
- name: Upload built website
uses: actions/upload-pages-artifact@v1
uses: actions/upload-pages-artifact@v3
with:
path: ./website-dist
@ -54,4 +56,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4

View File

@ -1,19 +1,17 @@
name: Linter
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
- push
- pull_request
jobs:
eslint:
name: Run ESlint
name: Run ESLint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install dependencies
run: npm ci

View File

@ -6,7 +6,7 @@
"editor.tabSize": 4,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"editor.suggest.snippetsPreventQuickSuggestions": false
},

View File

@ -1,4 +1,4 @@
## [Unreleased]
## [v0.3.0]
New features:
@ -12,6 +12,9 @@ Patches:
* Preserve state after switching to another tab (#56).
* Find view: ask for confirmation before negligently deleting documents when the user has clicked the '-' button (#58).
* Set a deadline for counting documents, and added a button to count documents if the deadline has been exceeded.
* Changed os.ModePerm (777) file permissions to 644 and 755.
* UI improvements.
* Bumped minimum reqiured Go version from 1.18 to 1.20.
Bugfixes:
@ -52,3 +55,4 @@ Initial release.
[v0.2.0]: https://github.com/garraflavatra/rolens/releases/tag/v0.2.0
[v0.2.1]: https://github.com/garraflavatra/rolens/releases/tag/v0.2.1
[v0.2.2]: https://github.com/garraflavatra/rolens/releases/tag/v0.2.2
[v0.3.0]: https://github.com/garraflavatra/rolens/releases/tag/v0.3.0

View File

@ -8,7 +8,7 @@ Robust, blazing-fast, comprehensive, yet simple [MongoDB](https://www.mongodb.co
## Why another MongoDB client?
This project arose from all flaws of similar tools many of which are slow, complicated, heavy, and fairly unwieldy. They mostly require a reasonably high level of knowledge on how to operate the program.
This project arose from all flaws of similar tools many of which are slow, complicated, heavy, and fairly unwieldy. They mostly require quite a high level of knowledge on how to operate the program.
**Rolens aims to be the intuitive, lightweight counterpart of these overengineered tools.**
@ -17,7 +17,7 @@ This project arose from all flaws of similar tools many of which are slow, compl
- [x] **Low overhead**: Typical query results against a local database are returned whithin milliseconds.
- [x] **Intuitive interface**: You know MongoDB? You know Rolens.
![Impression of Rolens's interface](./docs/images/home-impression.png)
![Impression of Rolens's interface](./docs/images/home-impression.webp)
This project is heavily inspired by the excellent [MongoHub](https://github.com/bububa/MongoHub-Mac) application, which sadly has not been updated since 2011.
@ -62,6 +62,7 @@ At this point, Rolens is comparable to MongoHub regarding features. It cannot ha
* Database management
- See stats
- Create dumps with `mongodump`
- Write and execute shell scripts
* Collections
- See stats
- Find, insert, update, & remove
@ -75,11 +76,10 @@ At this point, Rolens is comparable to MongoHub regarding features. It cannot ha
## Wishlist
* User management
* Shell _([under development](https://github.com/garraflavatra/rolens/pull/44))_
## 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) 2022-2024. The source code and compiled binaries are released under the GNU GPLv3 license — see [`LICENSE`](./LICENSE) for the full license text.
## Credits

View File

@ -50,18 +50,18 @@ function isNullish(val) {
return val === undefined || val === null;
}
// Check that Go ^1.18 is installed.
// Check that Go ^1.20 is installed.
try {
const goMinorVersion = /go1\.([0-9][0-9])/.exec(
execSync('go version').toString()
)?.pop();
if (isNullish(goMinorVersion) || (parseInt(goMinorVersion) < 18)) {
if (isNullish(goMinorVersion) || (parseInt(goMinorVersion) < 20)) {
throw new Error();
}
} catch {
missingDependencies.push({ name: 'Go ^1.18 ^16', url: 'https://go.dev/doc/install' });
missingDependencies.push({ name: 'Go ^1.20', url: 'https://go.dev/doc/install' });
}
// Check that Node.js ^16 is installed.

View File

@ -12,12 +12,12 @@
# - ubuntu-22.04
#
# Bundles to choose from:
# - rolens-macos-11-amd64.tar.gz
# - rolens-macos-11-arm64.tar.gz
# - rolens-macos-12-amd64.tar.gz
# - rolens-macos-12-arm64.tar.gz
# - rolens-macos-13-amd64.tar.gz
# - rolens-macos-13-arm64.tar.gz
# - rolens-macos-11-amd64.zip
# - rolens-macos-11-arm64.zip
# - rolens-macos-12-amd64.zip
# - rolens-macos-12-arm64.zip
# - rolens-macos-13-amd64.zip
# - rolens-macos-13-arm64.zip
# - rolens-ubuntu-20.04-amd64.tar.gz
# - rolens-ubuntu-22.04-amd64.tar.gz
# - rolens-windows-2019-amd64.zip
@ -32,8 +32,8 @@ version=$(<./build/version.txt)
mkdir bundle
# macOS apps
mv artifacts/*/rolens-macos-11-amd64.tar.gz "bundle/rolens-$version-macos-11+-amd64.tar.gz"
mv artifacts/*/rolens-macos-11-arm64.tar.gz "bundle/rolens-$version-macos-11+-arm64.tar.gz"
mv artifacts/*/rolens-macos-11-amd64.zip "bundle/rolens-$version-macos-11+-amd64.zip"
mv artifacts/*/rolens-macos-11-arm64.zip "bundle/rolens-$version-macos-11+-arm64.zip"
# Windows installers
mv artifacts/*/rolens-windows-2019-amd64-installer.zip "bundle/rolens-$version-windows-10+-amd64-installer.zip"

View File

@ -13,48 +13,27 @@ cat > build/darwin/dmg_settings.json << EOF
"background": "$(pwd)/build/darwin/dmg_background.png",
"icon-size": 100,
"window": {
"size": { "width": 155, "height": 250 },
"position": { "x": 360, "y": 360 }
"size": { "width": 750, "height": 400 }
},
"contents": [
{ "x": 750, "y": 500, "type": "link", "path": "/Applications" },
{ "x": 595, "y": 250, "type": "file", "path": "$(pwd)/build/bin/Rolens.app" }
{ "x": 600, "y": 175, "type": "link", "path": "/Applications" },
{ "x": 150, "y": 175, "type": "file", "path": "$(pwd)/build/bin/Rolens.app" }
]
}
EOF
# AMD/Intel
wails build -platform darwin/amd64
# create-dmg \
# --volname Rolens \
# --window-size 155 250 \
# --volicon build/appicon.png \
# --eula LICENSE \
# --app-drop-link 750 500 \
# --icon-size 100 \
# --background build/darwin/dmg_background.png \
# --add-file Rolens.app build/bin/Rolens.app 595 250 \
# build/bin/Rolens.dmg emptydir
# appdmg build/darwin/dmg_settings.json build/bin/Rolens.dmg
tar -czvf releases/rolens-$1-amd64.tar.gz --directory build/bin Rolens.app
appdmg build/darwin/dmg_settings.json build/bin/Rolens.dmg
zip -j releases/rolens-$1-amd64.zip build/bin/Rolens.dmg
# Cleanup
rm -rf build/bin/Rolens.app
rm -rf build/bin/Rolens.dmg
# ARM/AppleM1
wails build -platform darwin/arm64
# create-dmg \
# --volname Rolens \
# --window-size 155 250 \
# --volicon build/appicon.png \
# --eula LICENSE \
# --app-drop-link 750 500 \
# --icon-size 100 \
# --background build/darwin/dmg_background.png \
# --add-file Rolens.app build/bin/Rolens.app 595 250 \
# build/bin/Rolens.dmg emptydir
# appdmg build/darwin/dmg_settings.json build/bin/Rolens.dmg
tar -czvf releases/rolens-$1-arm64.tar.gz --directory build/bin Rolens.app
appdmg build/darwin/dmg_settings.json build/bin/Rolens.dmg
zip -j releases/rolens-$1-arm64.zip build/bin/Rolens.dmg
# Cleanup
rm -rf build/bin/Rolens.app

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -28,5 +28,5 @@ Feel free to contact me if you have questions! Send an e-mail to romein@vburen.n
Author and license
------------------
© Romein van Buren 2023. The source code and compiled binaries are released
© Romein van Buren 2022-2024. The source code and compiled binaries are released
under the GNU GPLv3 license — see LICENSE for the full license text.

View File

@ -3,7 +3,7 @@ title: Colophon
order: 900
---
Rolens is © [Romein van Buren](mailto:romein@vburen.nl) 2023. The source code and compiled binaries are released under the GNU GPLv3 license — see [`LICENSE`](https://github.com/garraflavatra/rolens/blob/main/LICENSE) for the full license text.
Rolens is © [Romein van Buren](mailto:romein@vburen.nl) 2022-2024. The source code and compiled binaries are released under the GNU GPLv3 license — see [`LICENSE`](https://github.com/garraflavatra/rolens/blob/main/LICENSE) for the full license text.
## Credits

View File

@ -8,9 +8,9 @@ If you just want to install Rolens, please refer to the [installation document](
## Prerequisites
Rolens is written in Go, so you should download the Go compiler from [the download page](https://go.dev/dl/). The minimum version required is 1.18. You can confirm whether it's installed correctly by running `go version` and checking that it outputs something similar to `go1.18.2`.
Rolens is written in Go, so you should download the Go compiler from [the download page](https://go.dev/dl/). The minimum version required is 1.20. You can confirm whether it's installed correctly by running `go version` and checking that it outputs something similar to `go1.20.4` or higher.
Furthermore, you need to have [Wails ^3.1](https://wails.io/docs/gettingstarted/installation) installed: `go install github.com/wailsapp/wails/v2/cmd/wails@latest`. Wails may have platform-specific dependencies; you can consult `wails doctor` to find out what dependencies Wails needs and how to install them.
Furthermore, you need to have [Wails ^3.1](https://wails.io/docs/gettingstarted/installation) installed: `go install github.com/wailsapp/wails/v2/cmd/wails@latest`. Wails may have platform-specific dependencies; you can consult [`wails doctor`](https://wails.io/docs/reference/cli#doctor) to find out what dependencies Wails needs and how to install them.
In order to compile the frontend, [Node.js](https://nodejs.org/en/download) ^16.0 and the [npm](https://npmjs.com) package manager ^8.0 (included in Node.js) are required. To confirm the installed versions of those tools, execute `node -v` and `npm -v`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 KiB

BIN
docs/images/shell.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -15,7 +15,7 @@ This project arose from all flaws of similar tools many of which are slow, compl
- **Low overhead**: Typical query results against a local database are returned whithin milliseconds.
- **Intuitive interface**: You know MongoDB? You know Rolens.
![Impression of Rolens's interface](./images/home-impression.png)
![Impression of Rolens's interface](./images/home-impression.webp)
This project is heavily inspired by the excellent [MongoHub](https://github.com/bububa/MongoHub-Mac) application, which sadly has not been updated since 2011.

View File

@ -7,14 +7,6 @@
</head>
<body>
<div id="app"></div>
<div id="app-loading">
<div class="ring">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div id="dialogoutlets"></div>
<script src="./src/main.js" type="module"></script>
</body>

View File

@ -16,11 +16,12 @@
"date-fns": "^2.30.0"
},
"devDependencies": {
"@garraflavatra/yeslint": "^1.0.0",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"eslint": "^8.43.0",
"eslint-config-svelte3": "github:johbog/eslint-config-svelte3",
"svelte": "^3.59.1",
"vite": "^3.2.7"
"vite": "^3.2.10"
}
},
"node_modules/@babel/runtime": {
@ -212,6 +213,24 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@garraflavatra/yeslint": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@garraflavatra/yeslint/-/yeslint-1.0.0.tgz",
"integrity": "sha512-LvpQq+buhjjGMtzdzgj5iFCOG9ZGvbgOsFMvtRCYiqpzzNjhXsfO4IGUrJuVL+AwWUzNPJNTzKI5OyQZbh07Jg==",
"dev": true,
"dependencies": {
"eslint-plugin-import": "^2.27.5"
},
"peerDependencies": {
"eslint": "^7.9.0 || ^8.0.0",
"eslint-plugin-svelte": "^2.32.4"
},
"peerDependenciesMeta": {
"eslint-plugin-svelte": {
"optional": true
}
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
@ -654,6 +673,18 @@
"node": ">= 8"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@ -1349,20 +1380,22 @@
}
},
"node_modules/eslint-plugin-svelte": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.30.0.tgz",
"integrity": "sha512-2/qj0BJsfM0U2j4EjGb7iC/0nbUvXx1Gn78CdtyuXpi/rSomLPCPwnsZsloXMzlt6Xwe8LBlpRvZObSKEHLP5A==",
"version": "2.32.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.32.4.tgz",
"integrity": "sha512-VJ12i2Iogug1jvhwxSlognnfGj76P5gks/V4pUD4SCSVQOp14u47MNP0zAG8AQR3LT0Fi1iUvIFnY4l9z5Rwbg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@jridgewell/sourcemap-codec": "^1.4.14",
"debug": "^4.3.1",
"esutils": "^2.0.3",
"known-css-properties": "^0.27.0",
"known-css-properties": "^0.28.0",
"postcss": "^8.4.5",
"postcss-load-config": "^3.1.4",
"postcss-safe-parser": "^6.0.0",
"svelte-eslint-parser": "^0.30.0"
"postcss-selector-parser": "^6.0.11",
"semver": "^7.5.3",
"svelte-eslint-parser": "^0.32.2"
},
"engines": {
"node": "^14.17.0 || >=16.0.0"
@ -1372,7 +1405,7 @@
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0-0",
"svelte": "^3.37.0 || ^4.0.0-0"
"svelte": "^3.37.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"svelte": {
@ -1380,6 +1413,21 @@
}
}
},
"node_modules/eslint-plugin-svelte/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/eslint-scope": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
@ -2157,9 +2205,9 @@
}
},
"node_modules/known-css-properties": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz",
"integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==",
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz",
"integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==",
"dev": true
},
"node_modules/levn": {
@ -2205,6 +2253,18 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/magic-string": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
@ -2245,10 +2305,16 @@
"dev": true
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@ -2423,9 +2489,9 @@
"dev": true
},
"node_modules/postcss": {
"version": "8.4.20",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"dev": true,
"funding": [
{
@ -2435,10 +2501,14 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"nanoid": "^3.3.4",
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
@ -2491,6 +2561,41 @@
"postcss": "^8.3.3"
}
},
"node_modules/postcss-scss": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz",
"integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss-scss"
}
],
"engines": {
"node": ">=12.0"
},
"peerDependencies": {
"postcss": "^8.4.19"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.13",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -2655,9 +2760,9 @@
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@ -2831,14 +2936,16 @@
}
},
"node_modules/svelte-eslint-parser": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.30.0.tgz",
"integrity": "sha512-H0Cn2TKr70DU9p/Gb04CfwtS7eK28MYumrHYPaDNkIFbfwGDLADpbERBn7u8G1Rcm2RMr2/mL6mq0J2e8iKFlA==",
"version": "0.32.2",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.32.2.tgz",
"integrity": "sha512-Ok9D3A4b23iLQsONrjqtXtYDu5ZZ/826Blaw2LeFZVTg1pwofKDG4mz3/GYTax8fQ0plRGHI6j+d9VQYy5Lo/A==",
"dev": true,
"dependencies": {
"eslint-scope": "^7.0.0",
"eslint-visitor-keys": "^3.0.0",
"espree": "^9.0.0"
"espree": "^9.0.0",
"postcss": "^8.4.25",
"postcss-scss": "^4.0.6"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -2847,7 +2954,7 @@
"url": "https://github.com/sponsors/ota-meshi"
},
"peerDependencies": {
"svelte": "^3.37.0 || ^4.0.0-0"
"svelte": "^3.37.0 || ^4.0.0"
},
"peerDependenciesMeta": {
"svelte": {
@ -2947,10 +3054,16 @@
"punycode": "^2.1.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"node_modules/vite": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz",
"integrity": "sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==",
"version": "3.2.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.10.tgz",
"integrity": "sha512-Dx3olBo/ODNiMVk/cA5Yft9Ws+snLOXrhLtrI3F4XLt4syz2Yg8fayZMWScPKoz12v5BUv7VEmQHnsfpY80fYw==",
"dev": true,
"dependencies": {
"esbuild": "^0.15.9",
@ -3081,6 +3194,12 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
@ -3248,6 +3367,15 @@
"integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
"dev": true
},
"@garraflavatra/yeslint": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@garraflavatra/yeslint/-/yeslint-1.0.0.tgz",
"integrity": "sha512-LvpQq+buhjjGMtzdzgj5iFCOG9ZGvbgOsFMvtRCYiqpzzNjhXsfO4IGUrJuVL+AwWUzNPJNTzKI5OyQZbh07Jg==",
"dev": true,
"requires": {
"eslint-plugin-import": "^2.27.5"
}
},
"@humanwhocodes/config-array": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
@ -3567,6 +3695,12 @@
"which": "^2.0.1"
}
},
"cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true
},
"date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@ -4007,20 +4141,33 @@
}
},
"eslint-plugin-svelte": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.30.0.tgz",
"integrity": "sha512-2/qj0BJsfM0U2j4EjGb7iC/0nbUvXx1Gn78CdtyuXpi/rSomLPCPwnsZsloXMzlt6Xwe8LBlpRvZObSKEHLP5A==",
"version": "2.32.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.32.4.tgz",
"integrity": "sha512-VJ12i2Iogug1jvhwxSlognnfGj76P5gks/V4pUD4SCSVQOp14u47MNP0zAG8AQR3LT0Fi1iUvIFnY4l9z5Rwbg==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@jridgewell/sourcemap-codec": "^1.4.14",
"debug": "^4.3.1",
"esutils": "^2.0.3",
"known-css-properties": "^0.27.0",
"known-css-properties": "^0.28.0",
"postcss": "^8.4.5",
"postcss-load-config": "^3.1.4",
"postcss-safe-parser": "^6.0.0",
"svelte-eslint-parser": "^0.30.0"
"postcss-selector-parser": "^6.0.11",
"semver": "^7.5.3",
"svelte-eslint-parser": "^0.32.2"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"eslint-scope": {
@ -4563,9 +4710,9 @@
"dev": true
},
"known-css-properties": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz",
"integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==",
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz",
"integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==",
"dev": true
},
"levn": {
@ -4599,6 +4746,15 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"magic-string": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
@ -4630,9 +4786,9 @@
"dev": true
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"dev": true
},
"natural-compare": {
@ -4757,12 +4913,12 @@
"dev": true
},
"postcss": {
"version": "8.4.20",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"dev": true,
"requires": {
"nanoid": "^3.3.4",
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
@ -4784,6 +4940,23 @@
"dev": true,
"requires": {}
},
"postcss-scss": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz",
"integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==",
"dev": true,
"requires": {}
},
"postcss-selector-parser": {
"version": "6.0.13",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
"dev": true,
"requires": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
}
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -4880,9 +5053,9 @@
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
},
"shebang-command": {
@ -5004,14 +5177,16 @@
"dev": true
},
"svelte-eslint-parser": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.30.0.tgz",
"integrity": "sha512-H0Cn2TKr70DU9p/Gb04CfwtS7eK28MYumrHYPaDNkIFbfwGDLADpbERBn7u8G1Rcm2RMr2/mL6mq0J2e8iKFlA==",
"version": "0.32.2",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.32.2.tgz",
"integrity": "sha512-Ok9D3A4b23iLQsONrjqtXtYDu5ZZ/826Blaw2LeFZVTg1pwofKDG4mz3/GYTax8fQ0plRGHI6j+d9VQYy5Lo/A==",
"dev": true,
"requires": {
"eslint-scope": "^7.0.0",
"eslint-visitor-keys": "^3.0.0",
"espree": "^9.0.0"
"espree": "^9.0.0",
"postcss": "^8.4.25",
"postcss-scss": "^4.0.6"
}
},
"svelte-hmr": {
@ -5086,10 +5261,16 @@
"punycode": "^2.1.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"vite": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz",
"integrity": "sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==",
"version": "3.2.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.10.tgz",
"integrity": "sha512-Dx3olBo/ODNiMVk/cA5Yft9Ws+snLOXrhLtrI3F4XLt4syz2Yg8fayZMWScPKoz12v5BUv7VEmQHnsfpY80fYw==",
"dev": true,
"requires": {
"esbuild": "^0.15.9",
@ -5159,6 +5340,12 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",

View File

@ -17,23 +17,20 @@
"date-fns": "^2.30.0"
},
"devDependencies": {
"@garraflavatra/yeslint": "^1.0.0",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"eslint": "^8.43.0",
"eslint-config-svelte3": "github:johbog/eslint-config-svelte3",
"svelte": "^3.59.1",
"vite": "^3.2.7"
"vite": "^3.2.10"
},
"eslintConfig": {
"extends": "svelte3",
"ignorePatterns": ["dist", "wailsjs"],
"extends": "./node_modules/@garraflavatra/yeslint/configs/svelte.js",
"ignorePatterns": [
"dist",
"wailsjs"
],
"rules": {
"svelte/html-quotes": [
"warn",
{
"prefer": "double",
"dynamic": { "quoted": false }
}
],
"svelte/no-useless-mustaches": "off",
"svelte/no-extra-reactive-curlies": "off"
}

View File

@ -1 +1 @@
7fc6d7b66151030191ded7136d96970e
015746ba33749cd2864cd336088387ef

View File

@ -1,17 +1,15 @@
<script>
import BlankState from '$components/blankstate.svelte';
import ContextMenu from '$components/contextmenu.svelte';
import dialogs from '$lib/dialogs';
import contextMenu from '$lib/stores/contextmenu';
import environment from '$lib/stores/environment';
import hostTree from '$lib/stores/hosttree';
import applicationInited from '$lib/stores/inited';
import windowTitle from '$lib/stores/windowtitle';
import Connection from '$organisms/connection/index.svelte';
import { EventsOn } from '$wails/runtime';
import { tick } from 'svelte';
import AboutDialog from './dialogs/about.svelte';
import SettingsDialog from './dialogs/settings/index.svelte';
import { fly } from 'svelte/transition';
import BlankState from '$components/blankstate.svelte';
import Connection from '$organisms/connection/index.svelte';
import ContextMenu from '$components/contextmenu.svelte';
import contextMenu from '$lib/stores/contextmenu.js';
import hostTree from '$lib/stores/hosttree.js';
import applicationInited from '$lib/stores/inited.js';
import windowTitle from '$lib/stores/windowtitle.js';
let showWelcomeScreen = undefined;
@ -28,26 +26,15 @@
await tick();
hostTree.newHost();
}
function showAboutDialog() {
dialogs.new(AboutDialog);
}
function showSettings() {
dialogs.new(SettingsDialog);
}
EventsOn('OpenPreferences', showSettings);
EventsOn('OpenAboutModal', showAboutDialog);
</script>
<svelte:window on:contextmenu|preventDefault />
<div id="root" class="platform-{$environment?.platform}">
<div id="root">
<div class="titlebar">{$windowTitle}</div>
{#if $applicationInited && (showWelcomeScreen !== undefined)}
<main class:empty={showWelcomeScreen}>
<main class:empty={showWelcomeScreen} in:fly={{ y: 10 }}>
{#if showWelcomeScreen}
<BlankState label="Welcome to Rolens!" image="/logo.png" pale={false} big={true}>
<button class="button" on:click={createFirstHost}>Add your first host</button>
@ -65,30 +52,23 @@
<style>
.titlebar {
height: 0;
background-color: #00002a;
height: var(--titlebar-height);
--wails-draggable: drag;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
#root.platform-darwin .titlebar {
height: var(--darwin-titlebar-height);
background-color: #ddd;
}
main {
height: 100vh;
height: calc(100vh - var(--titlebar-height));
display: grid;
grid-template: 1fr / minmax(300px, 0.3fr) 1fr;
}
main.empty {
grid-template: 1fr / 1fr;
}
#root.platform-darwin main {
height: calc(100vh - var(--darwin-titlebar-height));
}
main > :global(*) {
overflow: auto;
@ -98,12 +78,4 @@
main > :global(.addressbar) {
grid-column: 1 / 3;
}
.databaselist {
overflow: scroll;
}
.button.create {
margin-top: 0.5rem;
}
</style>

View File

@ -50,7 +50,7 @@
<svelte:window on:keydown={keydown} />
{#if items && position}
<div class="backdrop" on:pointerdown={close}></div>
<div class="backdrop" on:pointerdown={close} />
<nav>
<ul class="contextmenu" role="" style:left="{position[0]}px" style:top="{position[1]}px">
{#each items as item, index}
@ -101,7 +101,7 @@
text-align: left;
}
button.selected {
background-color: #00008b;
background-color: var(--selection);
color: #fff;
}

View File

@ -40,7 +40,7 @@
});
</script>
<div bind:this={editorParent} class="editor"></div>
<div bind:this={editorParent} class="editor" />
<style>
.editor {

View File

@ -1,5 +1,5 @@
<script>
import { daysAbbr, months } from '$lib/constants';
import { daysAbbr, months } from '$lib/constants.js';
import { addDays, getWeek, isDate, isSameDay, startOfWeek } from 'date-fns';
import { onMount } from 'svelte';
import Clock from '../clock.svelte';
@ -97,7 +97,7 @@
<table class="calendar">
<thead>
<tr>
<th></th>
<th />
{#each daysAbbr as dayName}
<th>{dayName}</th>
{/each}
@ -173,7 +173,7 @@
padding-bottom: 8px;
}
.calendar .day button.active {
background-color: #00008b;
background-color: var(--selection);
color: #fff;
}
.calendar .day button.notinmonth {

View File

@ -1,16 +1,22 @@
<script>
import { OpenDirectory } from '$wails/go/ui/UI';
import { ChooseDirectory } from '$wails/go/app/App.js';
export let value = '';
export let id = '';
export let title = 'Choose a directory';
async function selectDir() {
value = await OpenDirectory(title) || value;
value = await ChooseDirectory(title) || value;
}
</script>
<input type="text" on:pointerdown={selectDir} readonly {id} {value} />
<input
type="text"
on:pointerdown={selectDir}
readonly
{id}
{value}
/>
<style>
input {

View File

@ -1,6 +1,6 @@
<script>
import input from '$lib/actions/input';
import { canBeObjectId, numericInputTypes } from '$lib/mongo';
import input from '$lib/actions/input.js';
import { canBeObjectId, numericInputTypes } from '$lib/mongo/index.js';
import { ObjectId } from 'bson';
import { onMount } from 'svelte';
import Datepicker from './datepicker.svelte';
@ -70,7 +70,12 @@
<div class="forminput {type}">
<div class="field">
{#if type === 'string'}
<input type="text" bind:value use:input={{ type, onValid, onInvalid, mandatory, autofocus }} autocomplete="off" spellcheck="false" />
<input
type="text"
bind:value
use:input={{ type, onValid, onInvalid, mandatory, autofocus }}
autocomplete="off"
spellcheck="false" />
{:else if type === 'objectid'}
<input
type="text"
@ -79,7 +84,11 @@
use:input={{ type, onValid, onInvalid, mandatory, autofocus }}
/>
{:else if numericInputTypes.includes(type)}
<input type="number" bind:value use:input={{ type, onValid, onInvalid, mandatory, autofocus }} />
<input
type="number"
bind:value
use:input={{ type, onValid, onInvalid, mandatory, autofocus }}
/>
{:else if type === 'bool'}
<select bind:value on:change={selectChange} bind:this={selectInput}>
<option value={undefined} disabled={mandatory}>Unset</option>
@ -98,18 +107,38 @@
<Icon name="edit" />
</button>
{/if}
<button class="button-small" type="button" title="Generate random object id" on:click={generateObjectId}>
<button
class="button-small"
type="button"
title="Generate random object id"
on:click={generateObjectId}
>
<Icon name="reload" />
</button>
{:else if type === 'date'}
<button class="button-small" type="button" title="Edit date" on:click={() => showDatepicker = true}>
<button
class="button-small"
type="button"
title="Edit date"
on:click={() => showDatepicker = true}
>
<Icon name="edit" />
</button>
<button class="button-small" type="button" title="Set date to now" on:click={() => value = new Date()}>
<button
class="button-small"
type="button"
title="Set date to now"
on:click={() => value = new Date()}
>
<Icon name="o" />
</button>
{/if}
<button class="button-small" type="button" title="Reset field to default value" on:click={() => value = undefined}>
<button
class="button-small"
type="button"
title="Reset field to default value"
on:click={() => value = undefined}
>
<Icon name="trash" />
</button>
</div>

View File

@ -7,9 +7,7 @@
export let editor = undefined;
export let readonly = false;
const extensions = [
javascript(),
];
const extensions = [ javascript() ];
onMount(() => {
editor.dispatch({

View File

@ -1,6 +1,6 @@
<script>
import { pathsAreEqual, resolveKeypath, setValue } from '$lib/objects';
import contextMenu from '$lib/stores/contextmenu';
import { pathsAreEqual, resolveKeypath, setValue } from '$lib/objects.js';
import contextMenu from '$lib/stores/contextmenu.js';
import { createEventDispatcher } from 'svelte';
import FormInput from '$components/editors/forminput.svelte';
import Icon from '$components/icon.svelte';
@ -52,7 +52,10 @@
return obj;
}
else if ((typeof obj === 'object') && (obj !== null)) {
return Object.entries(obj).map(([ k, item ]) => {
return Object.entries(obj).map(([
k,
item,
]) => {
return { ...item, [key]: k };
});
}
@ -67,7 +70,10 @@
}
activeKey = itemKey;
activePath = [ ...path.slice(0, level), itemKey ];
activePath = [
...path.slice(0, level),
itemKey,
];
dispatch('select', { level, itemKey, index, path: activePath });
}
@ -126,12 +132,17 @@
</script>
{#each _items as item, index}
{@const selected = canSelect && pathsAreEqual(activePath, [
...path,
item[key],
])}
<tr
on:click={() => select(item[key], index)}
on:dblclick={() => doubleClick(item[key], index)}
on:contextmenu|preventDefault={evt => showContextMenu(evt, item)}
class:selectable={canSelect}
class:selected={canSelect && pathsAreEqual(activePath, [ ...path, item[key] ])}
class:selected
class:striped
>
{#if !hideChildrenToggles}
@ -145,6 +156,10 @@
<Icon name={childrenOpen[item[key]] ? 'chev-d' : 'chev-r'} />
</button>
{/if}
{#if item.loading}
<span class="spinner" style:margin-left="{level * 10}px" />
{/if}
</td>
{/if}
@ -157,7 +172,11 @@
{#each columns as column, columnIndex}
<td class:right={column.right} title={keypathProxies[index][column.key]}>
{#if column.inputType}
<FormInput {column} bind:value={keypathProxies[index][column.key]} bind:valid={validity[columnIndex]} />
<FormInput
{column}
bind:value={keypathProxies[index][column.key]}
bind:valid={validity[columnIndex]}
/>
{:else}
<div class="value" style:margin-left="{level * 10}px">
{formatValue(keypathProxies[index][column.key])}
@ -168,7 +187,12 @@
{#if canRemoveItems}
<td class="has-button">
<button class="button-small" type="button" on:click|stopPropagation={() => removeItem(index, item[key])} on:dblclick|stopPropagation>
<button
class="button-small"
type="button"
on:click|stopPropagation={() => removeItem(index, item[key])}
on:dblclick|stopPropagation
>
<Icon name="x" />
</button>
</td>
@ -184,7 +208,10 @@
{hideChildrenToggles}
{canSelect}
{canRemoveItems}
path={[ ...path, item[key] ]}
path={[
...path,
item[key],
]}
items={item.children}
level={level + 1}
bind:activePath
@ -203,28 +230,41 @@
cursor: pointer;
}
tr.selectable.selected td {
background-color: #00008b !important;
color: #fff;
background-color: var(--selection) !important;
}
td {
padding: 2px;
padding: 4px 2px;
text-overflow: ellipsis;
}
td.has-toggle {
width: 20px;
position: relative;
width: 1.5em;
}
td.has-toggle .spinner {
position: absolute;
top: 0.3em;
left: 0.22em;
width: 1em;
height: 1em;
border: 1px solid var(--primary);
border-radius: 50px;
border-top-color: transparent;
border-left-color: transparent;
animation: .6s linear 0 spin;
animation-iteration-count: infinite;
}
td.has-icon {
padding: 0;
width: 17px;
width: 1.5em;
}
td.has-icon :global(svg) {
width: 13px;
height: 13px;
width: 1em;
height: 1em;
}
td .value {
height: 15px;
height: 1.2em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -232,14 +272,13 @@
}
button.toggle {
color: inherit;
margin: 2px 0 0 3px;
padding: 0;
margin: 0;
vertical-align: top;
color: inherit;
}
button.toggle :global(svg) {
width: 13px;
height: 13px;
width: 0.9em;
height: 0.9em;
vertical-align: top;
}

View File

@ -57,17 +57,17 @@
<thead>
<tr>
{#if !hideChildrenToggles}
<th class="has-toggle"></th>
<th class="has-toggle" />
{/if}
<th class="has-icon"></th>
<th class="has-icon" />
{#each columns as column}
<th scope="col">{column.title || ''}</th>
{/each}
{#if canRemoveItems}
<th class="has-button"></th>
<th class="has-button" />
{/if}
</tr>
</thead>

View File

@ -1,5 +1,5 @@
<script>
import { isBsonBuiltin } from '$lib/mongo';
import { isBsonBuiltin } from '$lib/mongo/index.js';
import { isDate } from 'date-fns';
import Grid from './grid.svelte';
@ -22,7 +22,6 @@
].filter(c => !!c);
$: if (data) {
// items = dissectObject(data).map(item => ({ ...item, menu: getRootMenu(item.key, item) }));
items = [];
if (Array.isArray(data)) {

View File

@ -11,31 +11,28 @@
</script>
<style>
@keyframes spinning {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
svg {
transition: transform 0.25s;
will-change: transform;
width: 1.2em;
height: 1.2em;
}
svg.spinning {
animation: spinning 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
animation: spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
:global(.field) svg {
width: 13px;
height: 13px;
width: 1em;
height: 1em;
margin-right: 2px;
}
:global(.button) svg {
height: 13px;
height: 1em;
width: auto;
vertical-align: bottom;
}
:global(.blankstate .button) svg {
height: 17px;
height: 1.25em;
vertical-align: -3px;
margin-right: 4px;
}

View File

@ -3,8 +3,9 @@
</script>
<script>
import { Beep } from '$wails/go/ui/UI';
import { createEventDispatcher } from 'svelte';
import { fade, fly } from 'svelte/transition';
import { Beep } from '$wails/go/ui/UI.js';
import Icon from './icon.svelte';
export let show = true;
@ -35,6 +36,7 @@
}
function close() {
show = false;
dispatch('close');
}
</script>
@ -42,8 +44,8 @@
<svelte:window on:keydown={keydown} />
{#if show}
<div class="modal outer" on:pointerdown|self={Beep}>
<div class="inner" style:max-width={width || '80vw'}>
<div class="modal outer" on:pointerdown|self={Beep} transition:fade={{ duration: 200 }}>
<div class="inner" style:max-width={width || '80vw'} transition:fly={{ y: 20, duration: 200 }}>
{#if title}
<header>
<div class="title">{title}</div>
@ -73,19 +75,14 @@
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
margin: 0;
padding-top: 50px;
padding: 2rem;
--wails-draggable: drag;
}
:global(#root.platform-darwin) .outer {
margin-top: var(--darwin-titlebar-height);
}
.inner {
max-height: 80vh;
background-color: #fff;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
margin: auto;
width: 100%;
border-radius: var(--radius);
display: flex;

View File

@ -1,5 +1,5 @@
<script>
import { looseJsonIsValid } from '$lib/strings';
import { looseJsonIsValid } from '$lib/strings.js';
import { EJSON } from 'bson';
import { createEventDispatcher, onDestroy } from 'svelte';
import Icon from './icon.svelte';

View File

@ -1,40 +1,61 @@
<script>
import { createEventDispatcher, onMount } from 'svelte';
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
import Icon from './icon.svelte';
export let tabs = [];
export let selectedKey = '';
export let canAddTab = false;
export let multiline = false;
export let compact = true;
const dispatch = createEventDispatcher();
const maxPixelsPerMultilineTab = 120;
const activeIndicatorLeft = tweened(0, { easing: cubicOut, duration: 400 });
const activeIndicatorRight = tweened(0, { easing: cubicOut, duration: 400 });
const liElements = {};
let navEl;
let pixelsPerTab = 0;
$: tabs && navEl && updateMeasurements();
function updateMeasurements() {
pixelsPerTab = (navEl.offsetWidth ?? 0) / tabs.length;
}
function select(tabKey) {
selectedKey = tabKey;
dispatch('select', tabKey);
}
function moveActiveIndicator(target = liElements[selectedKey]) {
if (!compact) {
return;
}
const navRect = navEl.getBoundingClientRect();
const itemRect = target.getBoundingClientRect();
$activeIndicatorLeft = itemRect.x - navRect.x;
$activeIndicatorRight = navRect.right - itemRect.right;
}
onMount(() => {
window.addEventListener('resize', updateMeasurements);
if (selectedKey) {
moveActiveIndicator(liElements[selectedKey]);
}
});
</script>
<nav class="tabs" class:multiline={multiline || (pixelsPerTab < maxPixelsPerMultilineTab)} bind:this={navEl}>
<svelte:window on:resize={() => moveActiveIndicator()} />
<nav class="tabs" class:compact bind:this={navEl}>
<ul>
{#each tabs as tab (tab.key)}
<li class:active={tab.key === selectedKey}>
<li
class="tab"
class:active={tab.key === selectedKey}
class:closable={tab.closable}
bind:this={liElements[tab.key]}
on:mouseenter={event => moveActiveIndicator(event.target)}
on:mouseleave={() => moveActiveIndicator()}
>
<button class="tab" on:click={() => select(tab.key)}>
{#if tab.icon} <Icon name={tab.icon} /> {/if}
<span class="label">{tab.title}</span>
</button>
{#if tab.closable}
<button class="button-small" on:click={() => dispatch('closeTab', tab.key)}>
<Icon name="x" />
@ -44,39 +65,42 @@
{/each}
{#if canAddTab}
<li class="tab add">
<button class="tab" on:click={() => dispatch('addTab')}>
<li>
<button class="button-small" on:click={() => dispatch('addTab')}>
<Icon name="+" />
</button>
</li>
{/if}
</ul>
{#if compact}
<span
class="activeindicator"
style:left="{$activeIndicatorLeft}px"
style:right="{$activeIndicatorRight}px"
/>
{/if}
</nav>
<style>
nav {
position: relative;
}
ul {
overflow-x: auto;
display: flex;
list-style: none;
}
li {
display: inline-block;
flex: 1;
position: relative;
}
li.add {
flex: 0 1;
}
.tabs :global(svg) {
width: 13px;
height: 13px;
nav.tabs :global(svg) {
vertical-align: bottom;
}
li.active :global(svg) {
color: #fff;
}
button.tab {
width: 100%;
@ -96,20 +120,50 @@
border-right: 1px solid #ccc;
}
li.active button.tab {
color: #fff;
background-color: #00008b;
border-color: #00008b;
background-color: var(--selection);
border-color: var(--primary);
cursor: not-allowed;
}
nav.tabs.multiline button.tab .label {
display: block;
margin-top: 4px;
button.tab .label {
margin-top: 5px;
display: inline-block;
}
.button-small {
nav.tabs .button-small {
margin: 12px 0 0 4px;
}
li.closable .button-small {
display: none;
position: absolute;
top: 0;
right: 7px;
top: 7px;
}
li.closable.active {
padding-right: 20px;
}
li.closable.active .button-small {
display: block;
}
nav.tabs.compact {
border-bottom: 1px solid #aaa;
}
nav.tabs.compact li {
border-bottom: 2px solid transparent;
}
nav.tabs.compact button.tab {
border: none;
color: inherit;
background-color: transparent;
}
.activeindicator {
display: block;
position: absolute;
bottom: -1px;
height: 2px;
background-color: var(--primary);
}
</style>

View File

@ -1,7 +1,7 @@
<script>
import Modal from '$components/modal.svelte';
import alink from '$lib/actions/alink';
import environment from '$lib/stores/environment';
import alink from '$lib/actions/alink.js';
import environment from '$lib/stores/environment.js';
</script>
<Modal width="400px" title=" " on:close>
@ -19,7 +19,7 @@
<hr />
<div class="info">
<p class="copy">© Romein van Buren, 2023.</p>
<p class="copy">© Romein van Buren, 2022-2024.</p>
<p>
<a href="https://garraflavatra.github.io/rolens/" use:alink>Documentation</a> |
<a href="https://github.com/garraflavatra/rolens" use:alink>GitHub</a> |
@ -30,6 +30,10 @@
</Modal>
<style>
.brand, .info {
line-height: 1.2;
}
.brand {
display: flex;
align-items: center;
@ -40,9 +44,9 @@
flex: 0 1 125px;
}
.brand .title {
font-size: 2.25rem;
font-size: 2.25em;
font-weight: 600;
line-height: 2.5rem;
margin-bottom: .25em;
}
.brand .title .version {
font-size: 80%;
@ -51,7 +55,6 @@
}
.brand .description {
font-size: 1.5rem;
line-height: 1.6rem;
}
hr {
@ -60,7 +63,6 @@
.info {
font-size: 1.25rem;
line-height: 1.25rem;
margin: 0 1rem 1rem;
text-align: center;
}

View File

@ -1,8 +1,8 @@
<script>
import DirectoryChooser from '$components/editors/directorychooser.svelte';
import Modal from '$components/modal.svelte';
import input from '$lib/actions/input';
import settings from '$lib/stores/settings';
import input from '$lib/actions/input.js';
import settings from '$lib/stores/settings.js';
</script>
<Modal title="Preferences" on:close>
@ -15,7 +15,13 @@
<label for="defaultSort">Default sort query</label>
<label class="field">
<input type="text" class="code" bind:value={$settings.defaultSort} id="defaultSort" use:input={{ type: 'json' }} />
<input
type="text"
class="code"
bind:value={$settings.defaultSort}
id="defaultSort"
use:input={{ type: 'json' }}
/>
</label>
<label for="autosubmitQuery">Autosubmit query</label>

View File

@ -1,4 +1,4 @@
import { BrowserOpenURL } from '$wails/runtime/runtime';
import { BrowserOpenURL } from '$wails/runtime/runtime.js';
export default function alink(node) {
node.addEventListener('click', e => {

View File

@ -1,4 +1,4 @@
import environment from '$lib/stores/environment';
import environment from '$lib/stores/environment.js';
import { get } from 'svelte/store';
export function controlKeyDown(event) {

View File

@ -1,6 +1,6 @@
import { isInt } from '$lib/math';
import { canBeObjectId, int32, int64, uint64 } from '$lib/mongo';
import { jsonLooseParse } from '$lib/strings';
import { isInt } from '$lib/math.js';
import { canBeObjectId, int32, int64, uint64 } from '$lib/mongo/index.js';
import { jsonLooseParse } from '$lib/strings.js';
export default function input(node, { autofocus, type, onValid, onInvalid, mandatory } = {
autofocus: false,

View File

@ -1,4 +1,4 @@
import { AskConfirmation } from '$wails/go/app/App';
import { AskConfirmation } from '$wails/go/app/App.js';
import InputDialog from '../dialogs/input.svelte';
function newDialog(dialogComponent, data = {}) {
@ -6,11 +6,17 @@ function newDialog(dialogComponent, data = {}) {
outlet.className = 'dialogoutlet';
document.getElementById('dialogoutlets').appendChild(outlet);
const instance = new dialogComponent({ target: outlet, props: data });
const instance = new dialogComponent({
target: outlet,
intro: true,
props: data,
});
instance.$close = function() {
instance.$destroy();
outlet.remove();
setTimeout(() => {
instance.$destroy();
outlet.remove();
}, 200);
};
instance.$on('close', instance.$close);

View File

@ -1,5 +1,5 @@
<script>
import { locales } from '$lib/mongo';
import { locales } from './index.js';
const defaultCollation = {
locale: 'en_US',

View File

@ -1,27 +0,0 @@
import { StartProgressBar, StopProgressBar } from '$wails/go/ui/UI';
let taskCounter = 0;
export function startProgress(taskDescription = 'Loading…') {
const taskIndex = ++taskCounter;
let started = false;
const debouncer = setTimeout(() => {
StartProgressBar(taskIndex, taskDescription);
started = true;
}, 150);
const task = {
id: taskIndex,
description: taskDescription,
end: () => {
clearTimeout(debouncer);
if (started) {
StopProgressBar(taskIndex);
}
},
};
return task;
}

View File

@ -1,4 +1,4 @@
import { Environment } from '$wails/go/app/App';
import { Environment } from '$wails/go/app/App.js';
import { writable } from 'svelte/store';
const { set, subscribe } = writable({});
@ -11,5 +11,10 @@ async function reload() {
reload();
subscribe(env => {
// @ts-ignore
document.body.dataset.platform = env?.platform;
});
const environment = { reload, subscribe };
export default environment;

View File

@ -1,9 +1,8 @@
import dialogs from '$lib/dialogs';
import { startProgress } from '$lib/progress';
import dialogs from '$lib/dialogs.js';
import { get, writable } from 'svelte/store';
import applicationInited from './inited';
import queries from './queries';
import windowTitle from './windowtitle';
import applicationInited from './inited.js';
import queries from './queries.js';
import windowTitle from './windowtitle.js';
import ExportDialog from '$organisms/connection/collection/dialogs/export.svelte';
import IndexDetailDialog from '$organisms/connection/collection/dialogs/indexdetail.svelte';
@ -30,7 +29,7 @@ import {
RemoveHost,
RenameCollection,
TruncateCollection
} from '$wails/go/app/App';
} from '$wails/go/app/App.js';
const { set, subscribe } = writable({});
const getValue = () => get({ subscribe });
@ -40,7 +39,11 @@ async function refresh() {
const hosts = await Hosts();
const hostTree = getValue();
for (const [ hostKey, hostDetails ] of Object.entries(hosts)) {
for (const [
hostKey,
hostDetails,
] of Object.entries(hosts)) {
hostTree[hostKey] = hostTree[hostKey] || {};
const host = hostTree[hostKey];
host.key = hostKey;
@ -48,6 +51,9 @@ async function refresh() {
host.uri = hostDetails.uri;
host.open = async function() {
host.loading = true;
set(hostTree);
const {
databases: dbNames,
status,
@ -70,7 +76,10 @@ async function refresh() {
host.databases[dbKey] = host.databases[dbKey] || {};
}
for (const [ dbKey, database ] of Object.entries(host.databases)) {
for (const [
dbKey,
database,
] of Object.entries(host.databases)) {
if (!database.new && !dbNames.includes(dbKey)) {
delete host.databases[dbKey];
continue;
@ -83,6 +92,9 @@ async function refresh() {
delete database.new;
database.open = async function() {
database.loading = true;
set(hostTree);
const { collections: collNames, stats, statsError } = await OpenDatabase(hostKey, dbKey);
database.stats = stats;
database.statsError = statsError;
@ -95,7 +107,10 @@ async function refresh() {
database.collections[collKey] = database.collections[collKey] || {};
}
for (const [ collKey, collection ] of Object.entries(database.collections)) {
for (const [
collKey,
collection,
] of Object.entries(database.collections)) {
if (!collection.new && !collNames.includes(collKey)) {
delete database.collections[collKey];
continue;
@ -121,10 +136,8 @@ async function refresh() {
collection.rename = async function() {
const newCollKey = await dialogs.enterText('Rename collection', `Enter a new name for collection ${collKey}.`, collKey);
if (newCollKey && (newCollKey !== collKey)) {
const progress = startProgress(`Renaming collection "${collKey}" to "${newCollKey}"…`);
const ok = await RenameCollection(hostKey, dbKey, collKey, newCollKey);
await database.open();
progress.end();
return ok;
}
};
@ -155,7 +168,13 @@ async function refresh() {
const dialog = dialogs.new(ExportDialog, { collection, query });
return new Promise(resolve => {
dialog.$on('export', async event => {
const success = await PerformFindExport(hostKey, dbKey, collKey, JSON.stringify(event.detail.exportInfo));
const success = await PerformFindExport(
hostKey,
dbKey,
collKey,
JSON.stringify(event.detail.exportInfo)
);
if (success) {
dialog.$close();
resolve();
@ -230,10 +249,17 @@ async function refresh() {
return new Promise(resolve => {
dialog.$on('create', async event => {
const newIndexName = await CreateIndex(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(event.detail.index));
const newIndexName = await CreateIndex(
collection.hostKey,
collection.dbKey,
collection.key,
JSON.stringify(event.detail.index)
);
if (newIndexName) {
dialog.$close();
}
resolve(newIndexName);
});
});
@ -266,6 +292,8 @@ async function refresh() {
await refresh();
windowTitle.setSegments(dbKey, host.name, 'Rolens');
database.loading = false;
set(hostTree);
};
database.dump = function() {
@ -305,6 +333,8 @@ async function refresh() {
}
await refresh();
host.loading = false;
set(hostTree);
};
host.executeShellScript = async function(script) {

View File

@ -1,6 +1,6 @@
import { derived } from 'svelte/store';
import environment from './environment';
import applicationSettings from './settings';
import environment from './environment.js';
import applicationSettings from './settings.js';
let alreadyInited = false;

View File

@ -1,4 +1,4 @@
import { RemoveQuery, SavedQueries, SaveQuery, UpdateQueries } from '$wails/go/app/App';
import { RemoveQuery, SavedQueries, SaveQuery, UpdateQueries } from '$wails/go/app/App.js';
import { get, writable } from 'svelte/store';
const { set, subscribe } = writable({});

View File

@ -1,4 +1,4 @@
import { Settings, UpdateSettings } from '$wails/go/app/App';
import { Settings, UpdateSettings } from '$wails/go/app/App.js';
import { writable } from 'svelte/store';
const { set, subscribe } = writable({});

View File

@ -1,4 +1,4 @@
import { ReportSharedStateVariable } from '$wails/go/app/App';
import { ReportSharedStateVariable } from '$wails/go/app/App.js';
import { writable } from 'svelte/store';
function sharedStateStore(name) {

View File

@ -1,6 +1,6 @@
import dialogs from '$lib/dialogs';
import dialogs from '$lib/dialogs.js';
import ViewConfigDialog from '$organisms/connection/collection/dialogs/viewconfig.svelte';
import { UpdateViewStore, Views } from '$wails/go/app/App';
import { UpdateViewStore, Views } from '$wails/go/app/App.js';
import { get, writable } from 'svelte/store';
const { set, subscribe } = writable({});

View File

@ -1,4 +1,4 @@
import { WindowSetTitle } from '$wails/runtime/runtime';
import { WindowSetTitle } from '$wails/runtime/runtime.js';
import { writable } from 'svelte/store';
const { set, subscribe } = writable('Rolens');

View File

@ -1,15 +1,20 @@
import './styles/loading.css';
import './styles/reset.css';
import './styles/style.css';
import { LogError } from '$wails/runtime';
import { EventsOn, LogError } from '$wails/runtime/runtime.js';
import dialogs from '$lib/dialogs.js';
import App from './app.svelte';
import AboutDialog from './dialogs/about.svelte';
import SettingsDialog from './dialogs/settings/index.svelte';
window.addEventListener('unhandledrejection', event => {
LogError('Unhandled JS rejection: ' + event.reason);
});
// @ts-ignore Argument IS correct.
EventsOn('global.about', () => dialogs.new(AboutDialog));
EventsOn('global.settings', () => dialogs.new(SettingsDialog));
const app = new App({ target: document.getElementById('app') });
export default app;

View File

@ -3,11 +3,11 @@
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import ObjectEditor from '$components/editors/objecteditor.svelte';
import { aggregationStageDocumentationURL, aggregationStages } from '$lib/mongo';
import { aggregationStageDocumentationURL, aggregationStages } from '$lib/mongo/index.js';
import Collation from '$lib/mongo/collation.svelte';
import { jsonLooseParse, looseJsonIsValid } from '$lib/strings';
import { Aggregate } from '$wails/go/app/App';
import { BrowserOpenURL } from '$wails/runtime/runtime';
import { jsonLooseParse, looseJsonIsValid } from '$lib/strings.js';
import { Aggregate } from '$wails/go/app/App.js';
import { BrowserOpenURL } from '$wails/runtime/runtime.js';
import { onMount } from 'svelte';
export let collection;

View File

@ -2,8 +2,8 @@
import FormInput from '$components/editors/forminput.svelte';
import Hint from '$components/hint.svelte';
import Icon from '$components/icon.svelte';
import { inputTypes } from '$lib/mongo';
import { resolveKeypath, setValue } from '$lib/objects';
import { inputTypes } from '$lib/mongo/index.js';
import { resolveKeypath, setValue } from '$lib/objects.js';
export let item = {};
export let view = {};
@ -50,7 +50,12 @@
</span>
</div>
<div class="input">
<FormInput {column} bind:value={keypathProxy[column.key]} bind:valid={validity[column.key]} autofocus={index === 0} />
<FormInput
{column}
bind:value={keypathProxy[column.key]}
bind:valid={validity[column.key]}
autofocus={index === 0}
/>
</div>
</label>
{:else}

View File

@ -1,9 +1,9 @@
<script>
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import input from '$lib/actions/input';
import hostTree from '$lib/stores/hosttree';
import { createEventDispatcher, onMount } from 'svelte';
import input from '$lib/actions/input.js';
import hostTree from '$lib/stores/hosttree.js';
import { createEventDispatcher } from 'svelte';
export let host = {};
export let dbKey = '';

View File

@ -1,7 +1,7 @@
<script>
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import views from '$lib/stores/views';
import views from '$lib/stores/views.js';
import { createEventDispatcher } from 'svelte';
export let collection;
@ -16,7 +16,7 @@
}
</script>
<Modal title="Export results" width="450px" on:close>
<Modal title="Export results" width="500px" on:close>
<form on:submit|preventDefault={submit}>
<label class="field">
<span class="label">Export</span>
@ -40,7 +40,10 @@
<label class="field">
<span class="label">View to use</span>
<select bind:value={exportInfo.viewKey}>
{#each Object.entries(views.forCollection(collection.hostKey, collection.dbKey, collection.key)) as [ key, { name } ]}
{#each Object.entries(views.forCollection(collection.hostKey, collection.dbKey, collection.key)) as [
key,
{ name },
]}
<option value={key}>{name}</option>
{/each}
</select>

View File

@ -1,7 +1,7 @@
<script>
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import input from '$lib/actions/input';
import input from '$lib/actions/input.js';
import { createEventDispatcher } from 'svelte';
export let collection;
@ -27,7 +27,12 @@
<form on:submit|preventDefault={create}>
<label class="field name">
<span class="label">Name</span>
<input type="text" placeholder="Optional" bind:value={index.name} use:input={{ autofocus: true }} />
<input
type="text"
placeholder="Optional"
bind:value={index.name}
use:input={{ autofocus: true }}
/>
</label>
<div class="toggles">
@ -62,8 +67,9 @@
<div class="row">
<label class="field">
<span class="label">Key</span>
<input type="text" placeholder="_id" bind:value={rule.key}>
<input type="text" placeholder="_id" bind:value={rule.key} />
</label>
<label class="field">
<select bind:value={rule.sort}>
<option value={1}>Ascending</option>
@ -71,6 +77,7 @@
<option value="hashed" disabled={index.model.length > 1}>Hashed</option>
</select>
</label>
<button type="button" class="button danger" on:click={() => removeRule(ruleIndex)} disabled={index.model.length < 2}>
<Icon name="-" />
</button>
@ -85,6 +92,7 @@
<button class="button" on:click={addRule} disabled={index.model.some(r => r.sort === 'hashed')}>
<Icon name="+" /> Add rule
</button>
<button class="button" on:click={create} disabled={!index.model.length || index.model.some(r => !r.key)}>
<Icon name="+" /> Create index
</button>

View File

@ -3,9 +3,9 @@
import Hint from '$components/hint.svelte';
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import input from '$lib/actions/input';
import hostTree from '$lib/stores/hosttree';
import queries from '$lib/stores/queries';
import input from '$lib/actions/input.js';
import hostTree from '$lib/stores/hosttree.js';
import queries from '$lib/stores/queries.js';
import { createEventDispatcher } from 'svelte';
export let queryToSave = undefined;
@ -71,7 +71,7 @@
<input type="text" bind:value={queryToSave.name} use:input={{ autofocus: true }} />
</label>
<label class="field">
<textarea bind:value={queryToSave.remarks} placeholder="Remarks…" use:input></textarea>
<textarea bind:value={queryToSave.remarks} placeholder="Remarks…" use:input />
</label>
{/if}

View File

@ -2,9 +2,9 @@
import Icon from '$components/icon.svelte';
import Modal from '$components/modal.svelte';
import TabBar from '$components/tabbar.svelte';
import input from '$lib/actions/input';
import { randomString } from '$lib/math';
import views from '$lib/stores/views';
import input from '$lib/actions/input.js';
import { randomString } from '$lib/math.js';
import views from '$lib/stores/views.js';
export let collection;
export let firstItem = {};
@ -114,7 +114,12 @@
{#key collection.viewKey}
<label class="field">
<span class="label">View name</span>
<input type="text" use:input={{ autofocus: true }} bind:value={$views[collection.viewKey].name} disabled={collection.viewKey === 'list'} />
<input
type="text"
use:input={{ autofocus: true }}
bind:value={$views[collection.viewKey].name}
disabled={collection.viewKey === 'list'}
/>
</label>
{/key}
<label class="field">
@ -128,7 +133,11 @@
{#if $views[collection.viewKey].type === 'list'}
<div class="flex">
<input type="checkbox" id="hideObjectIndicators" bind:checked={$views[collection.viewKey].hideObjectIndicators} />
<input
type="checkbox"
id="hideObjectIndicators"
bind:checked={$views[collection.viewKey].hideObjectIndicators}
/>
<label for="hideObjectIndicators">
Hide object indicators ({'{...}'} and [...]) in list view and show nothing instead
</label>
@ -185,16 +194,41 @@
</span>
</label>
<button class="button" type="button" on:click={() => addColumn(columnIndex)} title="Add column before this one">
<button
class="button"
type="button"
on:click={() => addColumn(columnIndex)}
title="Add column before this one"
>
<Icon name="+" />
</button>
<button class="button" type="button" on:click={() => moveColumn(columnIndex, -1)} disabled={columnIndex === 0} title="Move column one position up">
<button
class="button"
type="button"
on:click={() => moveColumn(columnIndex, -1)}
disabled={columnIndex === 0}
title="Move column one position up"
>
<Icon name="chev-u" />
</button>
<button class="button" type="button" on:click={() => moveColumn(columnIndex, 1)} disabled={columnIndex === $views[collection.viewKey].columns.length - 1} title="Move column one position down">
<button
class="button"
type="button"
on:click={() => moveColumn(columnIndex, 1)}
disabled={columnIndex === $views[collection.viewKey].columns.length - 1}
title="Move column one position down"
>
<Icon name="chev-d" />
</button>
<button class="button danger" type="button" on:click={() => removeColumn(columnIndex)} title="Remove this column">
<button
class="button danger"
type="button"
on:click={() => removeColumn(columnIndex)}
title="Remove this column"
>
<Icon name="x" />
</button>
</div>
@ -202,10 +236,16 @@
<p>No columns yet</p>
{/each}
</div>
<button class="button" on:click={addColumn}>
<Icon name="+" /> Add column
</button>
<button class="button" on:click={addSuggestedColumns} disabled={!Object.keys(firstItem || {}).length}>
<button
class="button"
on:click={addSuggestedColumns}
disabled={!Object.keys(firstItem || {}).length}
>
<Icon name="zap" /> Add suggested columns
</button>
{/if}

View File

@ -3,14 +3,13 @@
import Icon from '$components/icon.svelte';
import ObjectGrid from '$components/grid/objectgrid.svelte';
import ObjectViewer from '$components/objectviewer.svelte';
import input from '$lib/actions/input';
import dialogs from '$lib/dialogs';
import { deepClone } from '$lib/objects';
import { startProgress } from '$lib/progress';
import applicationSettings from '$lib/stores/settings';
import views from '$lib/stores/views';
import { convertLooseJson, stringCouldBeID } from '$lib/strings';
import { CountItems, FindItems, RemoveItemById, UpdateFoundDocument } from '$wails/go/app/App';
import input from '$lib/actions/input.js';
import dialogs from '$lib/dialogs.js';
import { deepClone } from '$lib/objects.js';
import applicationSettings from '$lib/stores/settings.js';
import views from '$lib/stores/views.js';
import { convertLooseJson, stringCouldBeID } from '$lib/strings.js';
import { CountItems, FindItems, RemoveItemById, UpdateFoundDocument } from '$wails/go/app/App.js';
import { EJSON } from 'bson';
export let collection;
@ -36,7 +35,11 @@
let objectViewerSuccessMessage = '';
let viewsForCollection = {};
// $: code = `db.${collection.key}.find(${form.query || '{}'}${form.fields && form.fields !== '{}' ? `, ${form.fields}` : ''}).sort(${form.sort})${form.skip ? `.skip(${form.skip})` : ''}${form.limit ? `.limit(${form.limit})` : ''};`;
// $: code = `db.${collection.key}.find(${form.query || '{}'}${form.fields &&
// form.fields !== '{}' ? `, ${form.fields}` : ''}).sort(${form.sort})
// ${form.skip ? `.skip(${form.skip})` : ''}${form.limit ? `
// .limit(${form.limit})` : ''};`;
$: lastPage = (submittedForm.limit && result?.results?.length) ? Math.max(0, Math.ceil((result.total - submittedForm.limit) / submittedForm.limit)) : 0;
$: activePage = (submittedForm.limit && submittedForm.skip && result?.results?.length) ? submittedForm.skip / submittedForm.limit : 0;
@ -55,13 +58,17 @@
querying = `Querying ${collection.key}…`;
activePath = [];
const newResult = await FindItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify({
fields: convertLooseJson(form.fields || defaults.fields),
limit: form.limit ?? defaults.limit,
query: convertLooseJson(form.query) || defaults.query,
skip: form.skip ?? defaults.skip,
sort: convertLooseJson(form.sort) || defaults.sort,
}));
const newResult = await FindItems(
collection.hostKey,
collection.dbKey,
collection.key, JSON.stringify({
fields: convertLooseJson(form.fields || defaults.fields),
limit: form.limit ?? defaults.limit,
query: convertLooseJson(form.query) || defaults.query,
skip: form.skip ?? defaults.skip,
sort: convertLooseJson(form.sort) || defaults.sort,
})
);
if (newResult) {
newResult.results = newResult.results?.map(s => EJSON.parse(s, { relaxed: false }));
@ -137,7 +144,14 @@
if (!sure) {
return;
}
const ok = await RemoveItemById(collection.hostKey, collection.dbKey, collection.key, activePath[0]);
const ok = await RemoveItemById(
collection.hostKey,
collection.dbKey,
collection.key,
activePath[0]
);
if (ok) {
await submitQuery();
}
@ -163,7 +177,6 @@
}
async function saveDocument(event) {
const progress = startProgress('Performing update…');
const success = await UpdateFoundDocument(
collection.hostKey,
collection.dbKey,
@ -176,8 +189,6 @@
objectViewerSuccessMessage = 'Document has been saved!';
submitQuery();
}
progress.end();
}
$: collection && refresh();
@ -189,7 +200,8 @@
<div class="formrow one">
<label class="field">
<span class="label">Query or id</span>
<input type="text"
<input
type="text"
class="code"
placeholder={defaults.query}
autocomplete="off"
@ -230,7 +242,8 @@
<label class="field">
<span class="label">Skip</span>
<input type="number"
<input
type="number"
min="0"
bind:value={form.skip}
use:input
@ -241,7 +254,8 @@
<label class="field">
<span class="label">Limit</span>
<input type="number"
<input
type="number"
min="0"
bind:value={form.limit}
use:input
@ -326,7 +340,10 @@
<div>
<label class="field inline">
<select bind:value={collection.viewKey}>
{#each Object.entries(viewsForCollection) as [ key, view ]}
{#each Object.entries(viewsForCollection) as [
key,
view,
]}
<option value={key}>{view.name}</option>
{/each}
</select>
@ -334,19 +351,49 @@
<Icon name="cog" />
</button>
</label>
<button class="button danger" on:click={removeActive} disabled={!activePath?.length} title="Drop selected item">
<button
class="button danger"
on:click={removeActive}
disabled={!activePath?.length}
title="Drop selected item"
>
<Icon name="-" />
</button>
<button class="button" on:click={first} disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results || (activePage === 0)} title="First page">
<button
class="button"
on:click={first}
disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results || (activePage === 0)}
title="First page"
>
<Icon name="chevs-l" />
</button>
<button class="button" on:click={prev} disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results || (activePage === 0)} title="Previous {submittedForm.limit} items">
<button
class="button"
on:click={prev}
disabled={!submittedForm.limit || (submittedForm.skip <= 0) || !result?.results || (activePage === 0)}
title="Previous {submittedForm.limit} items"
>
<Icon name="chev-l" />
</button>
<button class="button" on:click={next} disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results || !lastPage || (activePage >= lastPage)} title="Next {submittedForm.limit} items">
<button
class="button"
on:click={next}
disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results || !lastPage || (activePage >= lastPage)}
title="Next {submittedForm.limit} items"
>
<Icon name="chev-r" />
</button>
<button class="button" on:click={last} disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results || !lastPage || (activePage >= lastPage)} title="Last page">
<button
class="button"
on:click={last}
disabled={!submittedForm.limit || ((result?.results?.length || 0) < submittedForm.limit) || !result?.results || !lastPage || (activePage >= lastPage)}
title="Last page"
>
<Icon name="chevs-r" />
</button>
</div>
@ -355,11 +402,24 @@
</div>
{#if objectViewerData}
<ObjectViewer bind:data={objectViewerData} saveable on:save={saveDocument} bind:successMessage={objectViewerSuccessMessage} />
<ObjectViewer
bind:data={objectViewerData}
saveable
on:save={saveDocument}
bind:successMessage={objectViewerSuccessMessage}
/>
{/if}
<datalist id="limits">
{#each [ 1, 5, 10, 25, 50, 100, 200 ] as value}
{#each [
1,
5,
10,
25,
50,
100,
200,
] as value}
<option {value} />
{/each}
</datalist>

View File

@ -18,14 +18,14 @@
export let tab = 'find';
const tabs = {
'stats': { icon: 'chart', title: 'Stats', component: Stats },
'find': { icon: 'db', title: 'Find', component: Find },
'insert': { icon: '+', title: 'Insert', component: Insert },
'update': { icon: 'edit', title: 'Update', component: Update },
'remove': { icon: 'trash', title: 'Remove', component: Remove },
'indexes': { icon: 'list', title: 'Indexes', component: Indexes },
'aggregate': { icon: 're', title: 'Aggregate', component: Aggregate },
'shell': { icon: 'shell', title: 'Shell', component: Shell },
stats: { icon: 'chart', title: 'Stats', component: Stats },
find: { icon: 'db', title: 'Find', component: Find },
insert: { icon: '+', title: 'Insert', component: Insert },
update: { icon: 'edit', title: 'Update', component: Update },
remove: { icon: 'trash', title: 'Remove', component: Remove },
indexes: { icon: 'list', title: 'Indexes', component: Indexes },
aggregate: { icon: 're', title: 'Aggregate', component: Aggregate },
shell: { icon: 'shell', title: 'Shell', component: Shell },
};
for (const key of Object.keys(tabs)) {

View File

@ -73,9 +73,11 @@
<button class="button" on:click={refresh}>
<Icon name="reload" spin={busy} /> Reload
</button>
<button class="button" on:click={createIndex}>
<Icon name="+" /> Create index…
</button>
<button class="button danger" on:click={dropIndex} disabled={!_indexes.length || !activePath[0]}>
<Icon name="x" /> Drop selected
</button>

View File

@ -4,11 +4,11 @@
import Icon from '$components/icon.svelte';
import ObjectEditor from '$components/editors/objecteditor.svelte';
import ObjectViewer from '$components/objectviewer.svelte';
import { randomString } from '$lib/math';
import { inputTypes } from '$lib/mongo';
import views from '$lib/stores/views';
import { capitalise, convertLooseJson, jsonLooseParse } from '$lib/strings';
import { InsertItems } from '$wails/go/app/App';
import { randomString } from '$lib/math.js';
import { inputTypes } from '$lib/mongo/index.js';
import views from '$lib/stores/views.js';
import { capitalise, convertLooseJson, jsonLooseParse } from '$lib/strings.js';
import { InsertItems } from '$wails/go/app/App.js';
import { EJSON } from 'bson';
import { createEventDispatcher, onMount } from 'svelte';
import Form from './components/form.svelte';

View File

@ -1,8 +1,8 @@
<script>
import Icon from '$components/icon.svelte';
import ObjectEditor from '$components/editors/objecteditor.svelte';
import { convertLooseJson } from '$lib/strings';
import { RemoveItems } from '$wails/go/app/App';
import { convertLooseJson } from '$lib/strings.js';
import { RemoveItems } from '$wails/go/app/App.js';
import { onMount } from 'svelte';
export let collection;

View File

@ -1,10 +1,10 @@
<script>
import Icon from '$components/icon.svelte';
import input from '$lib/actions/input';
import { atomicUpdateOperators } from '$lib/mongo';
import { deepClone } from '$lib/objects';
import { convertLooseJson, jsonLooseParse } from '$lib/strings';
import { UpdateItems } from '$wails/go/app/App';
import input from '$lib/actions/input.js';
import { atomicUpdateOperators } from '$lib/mongo/index.js';
import { deepClone } from '$lib/objects.js';
import { convertLooseJson, jsonLooseParse } from '$lib/strings.js';
import { UpdateItems } from '$wails/go/app/App.js';
export let collection = {};
@ -27,7 +27,8 @@
});
// function buildCode(form) {
// let operation = '{ ' + form.parameters.filter(p => p.type).map(p => `${p.type}: ${p.value || '{}'}`).join(', ') + ' }';
// let operation = '{ ' + form.parameters.filter(p => p.type).map(p =>
// `${p.type}: ${p.value || '{}'}`).join(', ') + ' }';
// if (operation === '{ }') {
// operation = '{}';
// }
@ -38,7 +39,8 @@
// form.many && (options += 'multi: true');
// (form.upsert || form.many) && (options += ' }');
// const code = `db.${collection.key}.update(${form.query || '{}'}, ${operation}${options});`;
// const code = `db.${collection.key}.update(${form.query || '{}'},
// ${operation}${options});`;
// return code;
// }
@ -48,7 +50,13 @@
f.parameters = f.parameters.map(param => {
return { ...param, value: convertLooseJson(param.value) };
});
updatedCount = await UpdateItems(collection.hostKey, collection.dbKey, collection.key, JSON.stringify(f));
updatedCount = await UpdateItems(
collection.hostKey,
collection.dbKey,
collection.key,
JSON.stringify(f)
);
}
function removeParam(index) {
@ -114,7 +122,12 @@
<label class="field">
<span class="label">Filter</span>
<input type="text" class="code" bind:value={form.query} use:input={{ type: 'json', autofocus: true }} placeholder={'{}'} />
<input
type="text"
class="code"
bind:value={form.query}
use:input={{ type: 'json', autofocus: true }}
placeholder={'{}'} />
</label>
<fieldset class="parameters">
@ -132,7 +145,13 @@
</optgroup>
{/each}
</select>
<input type="text" class="code" bind:value={param.value} placeholder={'{}'} use:input={{ type: 'json' }} />
<input
type="text"
class="code"
bind:value={param.value}
placeholder={'{}'}
use:input={{ type: 'json' }}
/>
</label>
<button class="button" disabled={form.parameters.length >= allOperators.length} on:click={() => addParameter()} type="button">

View File

@ -2,10 +2,9 @@
import DirectoryChooser from '$components/editors/directorychooser.svelte';
import Grid from '$components/grid/grid.svelte';
import Modal from '$components/modal.svelte';
import { startProgress } from '$lib/progress';
import hostTree from '$lib/stores/hosttree';
import applicationSettings from '$lib/stores/settings';
import { OpenConnection, OpenDatabase } from '$wails/go/app/App';
import hostTree from '$lib/stores/hosttree.js';
import applicationSettings from '$lib/stores/settings.js';
import { OpenConnection, OpenDatabase } from '$wails/go/app/App.js';
import { createEventDispatcher } from 'svelte';
export let info = {};
@ -23,7 +22,6 @@
info.collKeys = [];
if (hostKey) {
const progress = startProgress(`Opening connection to host "${hostKey}"`);
const databases = await OpenConnection(hostKey);
if (databases && !$hostTree[hostKey]) {
@ -32,8 +30,6 @@
$hostTree[hostKey].databases[dbKey] = $hostTree[hostKey].databases[dbKey] || { collections: {} };
});
}
progress.end();
}
}
@ -42,14 +38,11 @@
info.dbKey = dbKey;
if (dbKey) {
const progress = startProgress(`Opening database "${dbKey}"`);
const collections = await OpenDatabase(info.hostKey, dbKey);
for (const collKey of collections?.sort() || []) {
$hostTree[info.hostKey].databases[dbKey].collections[collKey] = {};
}
progress.end();
}
}

View File

@ -1,7 +1,7 @@
<script>
import BlankState from '$components/blankstate.svelte';
import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime';
import { EventsOn } from '$wails/runtime/runtime.js';
import Shell from '../shell.svelte';
import Stats from './stats.svelte';
@ -11,8 +11,8 @@
export let tab = 'stats';
const tabs = {
'stats': { icon: 'chart', title: 'Database stats', component: Stats },
'shell': { icon: 'shell', title: 'Shell', component: Shell },
stats: { icon: 'chart', title: 'Database stats', component: Stats },
shell: { icon: 'shell', title: 'Shell', component: Shell },
};
for (const key of Object.keys(tabs)) {

View File

@ -1,8 +1,8 @@
<script>
import Modal from '$components/modal.svelte';
import input from '$lib/actions/input';
import hostTree from '$lib/stores/hosttree';
import { AddHost, UpdateHost } from '$wails/go/app/App';
import input from '$lib/actions/input.js';
import hostTree from '$lib/stores/hosttree.js';
import { AddHost, UpdateHost } from '$wails/go/app/App.js';
import { createEventDispatcher, onMount } from 'svelte';
export let hostKey = '';
@ -54,7 +54,13 @@
<label class="field">
<span class="label">Connection string</span>
<input type="text" placeholder="mongodb://..." bind:value={form.uri} spellcheck="false" use:input />
<input
type="text"
placeholder="mongodb://..."
bind:value={form.uri}
spellcheck="false"
use:input
/>
</label>
</form>

View File

@ -1,7 +1,7 @@
<script>
import BlankState from '$components/blankstate.svelte';
import TabBar from '$components/tabbar.svelte';
import { EventsOn } from '$wails/runtime/runtime';
import { EventsOn } from '$wails/runtime/runtime.js';
import Logs from './logs.svelte';
import Shell from '../shell.svelte';
@ -12,10 +12,10 @@
export let tab = 'status';
const tabs = {
'status': { icon: 'chart', title: 'Host status', component: Status },
'shell': { icon: 'shell', title: 'Shell', component: Shell },
'logs': { icon: 'doc', title: 'Logs', component: Logs },
'systemInfo': { icon: 'server', title: 'System info', component: SystemInfo },
status: { icon: 'chart', title: 'Host status', component: Status },
shell: { icon: 'shell', title: 'Shell', component: Shell },
logs: { icon: 'doc', title: 'Logs', component: Logs },
systemInfo: { icon: 'server', title: 'System info', component: SystemInfo },
};
for (const key of Object.keys(tabs)) {

View File

@ -2,9 +2,9 @@
import Grid from '$components/grid/grid.svelte';
import Icon from '$components/icon.svelte';
import ObjectViewer from '$components/objectviewer.svelte';
import input from '$lib/actions/input';
import { logComponents, logLevels } from '$lib/mongo';
import { BrowserOpenURL } from '$wails/runtime/runtime';
import input from '$lib/actions/input.js';
import { logComponents, logLevels } from '$lib/mongo/index.js';
import { BrowserOpenURL } from '$wails/runtime/runtime.js';
import { onDestroy } from 'svelte';
export let host;
@ -82,7 +82,13 @@
<div class="formrow">
<label class="field">
<span class="label">Auto reload (seconds)</span>
<input type="number" class="autoreloadinput" bind:value={autoReloadInterval} list="autoreloadintervals" use:input />
<input
type="number"
class="autoreloadinput"
bind:value={autoReloadInterval}
list="autoreloadintervals"
use:input
/>
</label>
<label class="field">

View File

@ -1,26 +1,33 @@
<script>
import Grid from '$components/grid/grid.svelte';
import hostTree from '$lib/stores/hosttree';
import hostTree from '$lib/stores/hosttree.js';
export let path = [];
</script>
<Grid
striped={false}
columns={[ { key: 'name' }, { key: 'count', right: true } ]}
columns={[
{ key: 'name' },
{ key: 'count', right: true },
]}
items={Object.values($hostTree || {}).map(host => {
return {
id: host.key,
name: host.name,
loading: host.loading,
icon: 'server',
children: Object.values(host.databases || {})
.sort((a, b) => a.key.localeCompare(b))
.map(database => {
return {
id: database.key,
name: database.key,
icon: 'db',
loading: database.loading,
count: Object.keys(database.collections || {}).length || '',
icon: 'db',
children: Object.values(database.collections)
.sort((a, b) => a.key.localeCompare(b))
.map(collection => {
@ -42,6 +49,7 @@
],
};
}) || [],
menu: [
{ label: 'Dump database (BSON via mongodump)…', fn: database.dump },
{ label: 'Drop database…', fn: database.drop },
@ -51,6 +59,7 @@
],
};
}),
menu: [
{ label: 'New database…', fn: host.newDatabase },
{ separator: true },

View File

@ -1,8 +1,8 @@
<script>
import Icon from '$components/icon.svelte';
import hostTree from '$lib/stores/hosttree';
import sharedState from '$lib/stores/sharedstate';
import { EventsOn } from '$wails/runtime/runtime';
import hostTree from '$lib/stores/hosttree.js';
import sharedState from '$lib/stores/sharedstate.js';
import { EventsOn } from '$wails/runtime/runtime.js';
import CollectionView from './collection/index.svelte';
import DatabaseView from './database/index.svelte';
import HostView from './host/index.svelte';

View File

@ -2,9 +2,9 @@
import BlankState from '$components/blankstate.svelte';
import CodeEditor from '$components/editors/codeeditor.svelte';
import Icon from '$components/icon.svelte';
import environment from '$lib/stores/environment';
import { OpenShellScript, SaveShellScript } from '$wails/go/app/App';
import { BrowserOpenURL } from '$wails/runtime/runtime';
import environment from '$lib/stores/environment.js';
import { OpenShellScript, SaveShellScript, SaveShellOuput } from '$wails/go/app/App.js';
import { BrowserOpenURL } from '$wails/runtime/runtime.js';
import { javascript } from '@codemirror/lang-javascript';
import { onDestroy, onMount } from 'svelte';
@ -24,7 +24,7 @@
let editor;
async function runScript() {
if (!$environment.hasMongoDump) {
if (!$environment.hasMongoShell) {
return;
}
@ -73,6 +73,10 @@
);
}
async function saveOutput() {
await SaveShellOuput(result.output + '\n' + result.stderr);
}
async function copyErrorDescription() {
await navigator.clipboard.writeText(result.errorDescription);
copySucceeded = true;
@ -155,6 +159,10 @@
</button>
</div>
<button class="button secondary" disabled={!result.output} on:click={saveOutput}>
<Icon name="upload" /> Save output as…
</button>
<button class="button viewtoggle" title="Toggle horizontal/vertical view" on:click={toggleView}>
<Icon name="columns" rotation={horizontal ? 90 : 0} />
</button>

View File

@ -1,50 +0,0 @@
#app-loading {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
}
/* Source of the following CSS: https://loading.io/css/ (modified) */
#app-loading .ring {
display: inline-block;
position: relative;
width: 136px;
height: 136px;
margin: auto;
}
#app-loading .ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 120px;
height: 120px;
margin: 8px;
border: 8px solid;
border-radius: 50%;
animation: loading-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #f1dac8 transparent transparent transparent;
}
#app-loading .ring div:nth-child(1) {
animation-delay: -0.45s;
}
#app-loading .ring div:nth-child(2) {
animation-delay: -0.3s;
}
#app-loading .ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes loading-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -1,6 +1,9 @@
:root {
--darwin-titlebar-height: 36px;
--radius: 4px;
--titlebar-height: 36px;
--primary: #00008b;
--selection: rgba(0, 62, 205, 0.3);
}
html,
@ -14,8 +17,8 @@ body {
-webkit-user-select: none;
user-select: none;
cursor: default;
font-size: 13px;
line-height: 13px;
font-size: 15px;
line-height: 17px;
background-color: rgba(255, 255, 255, 0.45);
}
@ -42,7 +45,7 @@ p strong {
}
a {
color: rgb(0, 0, 204);
color: #0000cc;
text-decoration: underline;
text-underline-offset: 2px;
text-decoration-thickness: 1px;
@ -66,8 +69,8 @@ select:disabled {
}
.button {
background-color: #00008b;
border: 1px solid #00008b;
background-color: var(--primary);
border: 1px solid var(--primary);
padding: 0.5rem;
border-radius: var(--radius);
color: #fff;
@ -142,7 +145,7 @@ select:disabled {
.field > textarea,
.field > select {
flex: 1;
padding: 0 0.5rem;
padding: 0.5rem;
border: 1px solid #ccc;
background-color: #fff;
appearance: none;
@ -151,8 +154,8 @@ select:disabled {
.field > textarea:focus,
.field > select:focus {
outline: none;
border-color: #00008b;
box-shadow: 0 0 0 3px rgba(0, 0, 139, 0.2);
border-color: var(--primary);
box-shadow: 0 0 0 1px var(--primary);
}
.field > input.invalid,
.field > textarea.invalid,
@ -215,3 +218,8 @@ code,
.flash-green {
animation: 1s ease-out 0s 1 flashGreen;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@ -9,10 +9,10 @@ export default defineConfig({
plugins: [ svelte() ],
resolve: {
alias: {
'$components': currentDir + '/src/components',
'$organisms': currentDir + '/src/organisms',
'$wails': currentDir + '/wailsjs',
'$lib': currentDir + '/src/lib',
$components: currentDir + '/src/components',
$organisms: currentDir + '/src/organisms',
$wails: currentDir + '/wailsjs',
$lib: currentDir + '/src/lib',
},
},
});

9
frontend/wailsjs/go/app/App.d.ts generated vendored
View File

@ -1,7 +1,6 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {app} from '../models';
import {map[string]app} from '../models';
import {menu} from '../models';
import {context} from '../models';
import {ui} from '../models';
@ -12,6 +11,8 @@ export function Aggregate(arg1:string,arg2:string,arg3:string,arg4:string,arg5:s
export function AskConfirmation(arg1:string):Promise<boolean>;
export function ChooseDirectory(arg1:string):Promise<string>;
export function CountItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise<app.CountItemsResult>;
export function CreateIndex(arg1:string,arg2:string,arg3:string,arg4:string):Promise<string>;
@ -34,7 +35,7 @@ export function GetIndexes(arg1:string,arg2:string,arg3:string):Promise<app.GetI
export function HostLogs(arg1:string,arg2:string):Promise<app.HostLogsResult>;
export function Hosts():Promise<map[string]app.Host>;
export function Hosts():Promise<{[key: string]: app.Host}>;
export function InsertItems(arg1:string,arg2:string,arg3:string,arg4:string):Promise<any>;
@ -70,9 +71,11 @@ export function ReportSharedStateVariable(arg1:string,arg2:string):Promise<void>
export function SaveQuery(arg1:string):Promise<string>;
export function SaveShellOuput(arg1:string):Promise<void>;
export function SaveShellScript(arg1:string,arg2:string,arg3:string,arg4:string,arg5:boolean):Promise<app.SaveShellScriptResult>;
export function SavedQueries():Promise<map[string]app.SavedQuery>;
export function SavedQueries():Promise<{[key: string]: app.SavedQuery}>;
export function Settings():Promise<app.Settings>;

View File

@ -14,6 +14,10 @@ export function AskConfirmation(arg1) {
return window['go']['app']['App']['AskConfirmation'](arg1);
}
export function ChooseDirectory(arg1) {
return window['go']['app']['App']['ChooseDirectory'](arg1);
}
export function CountItems(arg1, arg2, arg3, arg4) {
return window['go']['app']['App']['CountItems'](arg1, arg2, arg3, arg4);
}
@ -130,6 +134,10 @@ export function SaveQuery(arg1) {
return window['go']['app']['App']['SaveQuery'](arg1);
}
export function SaveShellOuput(arg1) {
return window['go']['app']['App']['SaveShellOuput'](arg1);
}
export function SaveShellScript(arg1, arg2, arg3, arg4, arg5) {
return window['go']['app']['App']['SaveShellScript'](arg1, arg2, arg3, arg4, arg5);
}

6
frontend/wailsjs/go/ui/UI.d.ts generated vendored
View File

@ -4,12 +4,6 @@ import {context} from '../models';
export function Beep():Promise<void>;
export function OpenDirectory(arg1:string):Promise<string>;
export function Reveal(arg1:string):Promise<void>;
export function StartProgressBar(arg1:number,arg2:string):Promise<void>;
export function Startup(arg1:context.Context):Promise<void>;
export function StopProgressBar(arg1:number):Promise<void>;

View File

@ -6,22 +6,10 @@ export function Beep() {
return window['go']['ui']['UI']['Beep']();
}
export function OpenDirectory(arg1) {
return window['go']['ui']['UI']['OpenDirectory'](arg1);
}
export function Reveal(arg1) {
return window['go']['ui']['UI']['Reveal'](arg1);
}
export function StartProgressBar(arg1, arg2) {
return window['go']['ui']['UI']['StartProgressBar'](arg1, arg2);
}
export function Startup(arg1) {
return window['go']['ui']['UI']['Startup'](arg1);
}
export function StopProgressBar(arg1) {
return window['go']['ui']['UI']['StopProgressBar'](arg1);
}

View File

@ -225,3 +225,11 @@ export function Hide(): void;
// [Show](https://wails.io/docs/reference/runtime/intro#show)
// Shows the application.
export function Show(): void;
// [ClipboardGetText](https://wails.io/docs/reference/runtime/clipboard#clipboardgettext)
// Returns the current text stored on clipboard
export function ClipboardGetText(): Promise<string>;
// [ClipboardSetText](https://wails.io/docs/reference/runtime/clipboard#clipboardsettext)
// Sets a text on the clipboard
export function ClipboardSetText(text: string): Promise<boolean>;

View File

@ -37,11 +37,11 @@ export function LogFatal(message) {
}
export function EventsOnMultiple(eventName, callback, maxCallbacks) {
window.runtime.EventsOnMultiple(eventName, callback, maxCallbacks);
return window.runtime.EventsOnMultiple(eventName, callback, maxCallbacks);
}
export function EventsOn(eventName, callback) {
EventsOnMultiple(eventName, callback, -1);
return EventsOnMultiple(eventName, callback, -1);
}
export function EventsOff(eventName, ...additionalEventNames) {
@ -49,7 +49,7 @@ export function EventsOff(eventName, ...additionalEventNames) {
}
export function EventsOnce(eventName, callback) {
EventsOnMultiple(eventName, callback, 1);
return EventsOnMultiple(eventName, callback, 1);
}
export function EventsEmit(eventName) {
@ -192,3 +192,11 @@ export function Hide() {
export function Show() {
window.runtime.Show();
}
export function ClipboardGetText() {
return window.runtime.ClipboardGetText();
}
export function ClipboardSetText(text) {
return window.runtime.ClipboardSetText(text);
}

48
go.mod
View File

@ -1,8 +1,10 @@
module github.com/garraflavatra/rolens
go 1.18
go 1.21
require github.com/wailsapp/wails/v2 v2.3.1
toolchain go1.21.5
require github.com/wailsapp/wails/v2 v2.7.1
require (
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6
@ -11,12 +13,9 @@ require (
)
require (
github.com/akavel/rsrc v0.10.2 // indirect
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/josephspurrier/goversioninfo v1.4.0 // indirect
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 // indirect
golang.org/x/image v0.7.0 // indirect
github.com/leaanthony/u v1.1.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/wailsapp/go-webview2 v1.0.10 // indirect
)
require (
@ -27,35 +26,32 @@ require (
github.com/golang/snappy v0.0.1 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/labstack/echo/v4 v4.9.0 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/leaanthony/go-ansi-parser v1.0.1 // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
github.com/leaanthony/gosod v1.0.3 // indirect
github.com/leaanthony/slicer v1.5.0 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/leaanthony/slicer v1.6.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/ncruces/zenity v0.10.9
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/samber/lo v1.27.1 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/tkrajina/go-reflector v0.5.5 // indirect
github.com/tkrajina/go-reflector v0.5.6 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.3.0
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
// replace github.com/wailsapp/wails/v2 v2.3.1 => /Users/romeinvanburen/go/pkg/mod

126
go.sum
View File

@ -1,12 +1,8 @@
github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f h1:OGqDDftRTwrvUoL6pOG7rYTmWsTCvyEWFsMjg+HcOaA=
github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f/go.mod h1:Dv9D0NUlAsaQcGQZa5kc5mqR9ua72SmA8VXi4cd+cBw=
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6 h1:jFEK/SA/7E8lg9T33+y8D4Z0I782+bbiEjmyyklRzRQ=
github.com/gen2brain/beeep v0.0.0-20220909211152-5a9ec94374f6/go.mod h1:/WeFVhhxMOGypVKS0w8DUJxUBbHypnWkUVnW7p5c9Pw=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
@ -17,78 +13,85 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/josephspurrier/goversioninfo v1.4.0 h1:Puhl12NSHUSALHSuzYwPYQkqa2E1+7SrtAPJorKK0C8=
github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4=
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg=
github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI=
github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/ncruces/zenity v0.10.9 h1:TYdNwEj9HiDDcpdsIUecBMsQw7L80Aiu/IJMM0Tao1E=
github.com/ncruces/zenity v0.10.9/go.mod h1:FzjqP1loicusCFJTdIt5Oqbmoj2zySHpM0RsgJeeCbk=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 h1:GranzK4hv1/pqTIhMTXt2X8MmMOuH3hMeUR0o9SP5yc=
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844/go.mod h1:T1TLSfyWVBRXVGzWd0o9BI4kfoO9InEgfQe4NV3mLz8=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg=
github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk=
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o=
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8=
github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ=
github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE=
github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/wailsapp/go-webview2 v1.0.10 h1:PP5Hug6pnQEAhfRzLCoOh2jJaPdrqeRgJKZhyYyDV/w=
github.com/wailsapp/go-webview2 v1.0.10/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.3.1 h1:ZJz+pyIBKyASkgO8JO31NuHO1gTTHmvwiHYHwei1CqM=
github.com/wailsapp/wails/v2 v2.3.1/go.mod h1:zlNLI0E2c2qA6miiuAHtp0Bac8FaGH0tlhA19OssR/8=
github.com/wailsapp/wails/v2 v2.7.1 h1:HAzp2c5ODOzsLC6ZMDVtNOB72ozM7/SJecJPB2Ur+UU=
github.com/wailsapp/wails/v2 v2.7.1/go.mod h1:oIJVwwso5fdOgprBYWXBBqtx6PaSvxg8/KTQHNGkadc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
@ -97,36 +100,20 @@ github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCO
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -137,32 +124,19 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -75,8 +75,8 @@ func NewApp(version string) *App {
panic(errors.New("unsupported platform"))
}
os.MkdirAll(a.Env.DataDirectory, os.ModePerm)
os.MkdirAll(a.Env.LogDirectory, os.ModePerm)
os.MkdirAll(a.Env.DataDirectory, 0755)
os.MkdirAll(a.Env.LogDirectory, 0755)
return a
}
@ -166,3 +166,25 @@ func (a *App) AskConfirmation(message string) bool {
return false
}
}
func (a *App) ChooseDirectory(title string) string {
if title == "" {
title = "Choose a directory"
}
dir, err := wailsRuntime.OpenDirectoryDialog(a.ctx, wailsRuntime.OpenDialogOptions{
Title: title,
DefaultDirectory: a.Env.DownloadDirectory,
CanCreateDirectories: true,
})
if err != nil {
wailsRuntime.MessageDialog(a.ctx, wailsRuntime.MessageDialogOptions{
Title: "Error while opening directory",
Message: err.Error(),
Type: wailsRuntime.ErrorDialog,
})
}
return dir
}

View File

@ -24,12 +24,12 @@ func (a *App) Menu() *menu.Menu {
appMenu := menu.NewMenu()
aboutMenu := appMenu.AddSubmenu("Rolens")
aboutMenu.AddText("About Rolens", nil, menuCallbackEmit(a, "OpenAboutModal"))
aboutMenu.AddText("About Rolens", nil, menuCallbackEmit(a, "global.about"))
aboutMenu.AddSeparator()
aboutMenu.AddText("Preferences…", keys.CmdOrCtrl(","), menuCallbackEmit(a, "OpenPreferences"))
aboutMenu.AddText("Preferences…", keys.CmdOrCtrl(","), menuCallbackEmit(a, "global.settings"))
aboutMenu.AddSeparator()
aboutMenu.AddText("Open data directory", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.DataDirectory) })
aboutMenu.AddText("Open log directory", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.LogDirectory) })
aboutMenu.AddText("Open data directory", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.DataDirectory) })
aboutMenu.AddText("Open log directory", nil, func(cd *menu.CallbackData) { a.ui.Reveal(a.Env.LogDirectory) })
aboutMenu.AddText("Purge logs…", nil, func(cd *menu.CallbackData) { a.PurgeLogDirectory() })
aboutMenu.AddSeparator()
@ -47,9 +47,10 @@ func (a *App) Menu() *menu.Menu {
hostMenu.AddText("New…", keys.OptionOrAlt("C"), menuCallbackEmit(a, "ui.host.new"))
hostMenu.AddText("Edit host…", keys.OptionOrAlt("H"), menuCallbackEmit(a, "ui.host.edit"))
hostMenu.AddSeparator()
hostMenu.AddText("Server status", nil, menuCallbackEmit(a, "ui.host.tab", "status"))
hostMenu.AddText("System info", nil, menuCallbackEmit(a, "ui.host.tab", "systemInfo"))
hostMenu.AddText("Host status", nil, menuCallbackEmit(a, "ui.host.tab", "status"))
hostMenu.AddText("Shell", nil, menuCallbackEmit(a, "ui.host.tab", "shell"))
hostMenu.AddText("Logs", nil, menuCallbackEmit(a, "ui.host.tab", "logs"))
hostMenu.AddText("System info", nil, menuCallbackEmit(a, "ui.host.tab", "systemInfo"))
hostMenu.AddSeparator()
hostMenu.AddText("Remove host…", nil, menuCallbackEmit(a, "ui.host.remove"))

View File

@ -3,7 +3,6 @@ package app
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"github.com/wailsapp/wails/v2/pkg/runtime"
@ -77,7 +76,7 @@ func (a *App) UpdateSettings(jsonData string) Settings {
}
filePath := path.Join(a.Env.DataDirectory, "settings.json")
err = ioutil.WriteFile(filePath, newJson, os.ModePerm)
err = ioutil.WriteFile(filePath, newJson, 0644)
if err != nil {
runtime.LogErrorf(a.ctx, "Could not update host list: %s", err.Error())
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{

View File

@ -3,7 +3,6 @@ package app
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"github.com/wailsapp/wails/v2/pkg/runtime"
@ -25,7 +24,7 @@ func updateQueryFile(a *App, newData map[string]SavedQuery) error {
return err
}
err = ioutil.WriteFile(filePath, jsonData, os.ModePerm)
err = ioutil.WriteFile(filePath, jsonData, 0644)
return err
}

View File

@ -142,7 +142,7 @@ func (a *App) SaveShellScript(hostKey, dbKey, collKey, script string, temp bool)
scriptHeader = scriptHeader + "\n"
script = scriptHeader + strings.TrimLeft(strings.TrimRight(script, " \t\n"), "\n")
if err := os.WriteFile(result.Fname, []byte(script), os.ModePerm); err != nil {
if err := os.WriteFile(result.Fname, []byte(script), 0755); err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to write script to %s: %s", result.Fname, err.Error())
result.ErrorTitle = "Could not create temporary script file"
result.ErrorDescription = err.Error()
@ -154,7 +154,7 @@ func (a *App) SaveShellScript(hostKey, dbKey, collKey, script string, temp bool)
func (a *App) OpenShellScript() string {
dir := path.Join(a.Env.DataDirectory, "Shell Scripts")
os.MkdirAll(dir, os.ModePerm)
os.MkdirAll(dir, 0755)
fname, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
DefaultDirectory: path.Join(a.Env.DataDirectory, "Shell Scripts"),
@ -182,3 +182,30 @@ func (a *App) OpenShellScript() string {
return string(script)
}
func (a *App) SaveShellOuput(output string) {
fname, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
DefaultFilename: "mongosh-output.txt",
DefaultDirectory: a.Env.DownloadDirectory,
Title: "Save mongosh output",
CanCreateDirectories: true,
})
if err != nil {
runtime.LogWarningf(a.ctx, "Shell: error exporting output to %s: %s", fname, err.Error())
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
Title: "Error exporting output",
Message: err.Error(),
Type: runtime.ErrorDialog,
})
}
if err := os.WriteFile(fname, []byte(output), 0755); err != nil {
runtime.LogWarningf(a.ctx, "Shell: error writing shell output to %s: %s", fname, err.Error())
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
Title: "Error writing shell output",
Message: err.Error(),
Type: runtime.ErrorDialog,
})
}
}

View File

@ -4,7 +4,6 @@ import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"path"
"github.com/google/uuid"
@ -23,7 +22,7 @@ func updateHostsFile(a *App, newData map[string]Host) error {
return err
}
err = ioutil.WriteFile(filePath, jsonData, os.ModePerm)
err = ioutil.WriteFile(filePath, jsonData, 0644)
return err
}

View File

@ -4,7 +4,6 @@ import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"path"
"github.com/wailsapp/wails/v2/pkg/runtime"
@ -63,7 +62,7 @@ func updateViewStore(a *App, newData ViewStore) error {
return err
}
err = ioutil.WriteFile(filePath, jsonData, os.ModePerm)
err = ioutil.WriteFile(filePath, jsonData, 0644)
return err
}

View File

@ -4,12 +4,8 @@ import (
"os"
"path"
"strings"
"github.com/ncruces/zenity"
)
var showError = true
type AppLogger struct {
directory string
filename string
@ -25,25 +21,9 @@ func NewAppLogger(directory, filename string) *AppLogger {
}
func (l *AppLogger) Print(message string) {
os.MkdirAll(l.directory, os.ModePerm)
f, err := os.OpenFile(l.filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil && showError {
zenity.Error(err.Error(), zenity.Title("Could not open logfile!"), zenity.ErrorIcon)
showError = false
}
if _, err = f.WriteString(message); err != nil {
if showError {
zenity.Error(err.Error(), zenity.Title("Could not write to logfile!"), zenity.ErrorIcon)
showError = false
} else {
showError = true
}
} else {
showError = true
}
os.MkdirAll(l.directory, 0755)
f, _ := os.OpenFile(l.filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
f.WriteString(message)
f.Close()
}

View File

@ -1,17 +0,0 @@
package ui
import "github.com/ncruces/zenity"
func (u *UI) OpenDirectory(title string) string {
if title == "" {
title = "Choose a directory"
}
dir, err := zenity.SelectFile(zenity.Title(title), zenity.Directory(), zenity.Modal())
if err != nil && err != zenity.ErrCanceled {
zenity.Error("Error while opening directory", zenity.ErrorIcon)
}
return dir
}

View File

@ -1,34 +0,0 @@
package ui
import (
"time"
"github.com/ncruces/zenity"
)
// @todo: this takes ~0.5 seconds. Improve?
func (u *UI) StartProgressBar(id uint, title string) {
if title == "" {
// default title
title = "Loading…"
}
p, err := zenity.Progress(zenity.Title(title), zenity.Pulsate(), zenity.Modal())
if err != nil {
return
}
u.progressBars[id] = p
}
func (u *UI) StopProgressBar(id uint) {
for try := 0; try < 10; try++ {
if p := u.progressBars[id]; p != nil {
p.Complete()
p.Close()
p = nil
return
}
println("Progress dialog not found:", id, try)
time.Sleep(100 * time.Millisecond)
}
}

View File

@ -5,18 +5,14 @@ import (
"runtime"
"github.com/gen2brain/beeep"
"github.com/ncruces/zenity"
)
type UI struct {
ctx context.Context
progressBars map[uint]zenity.ProgressDialog
}
func New() *UI {
return &UI{
progressBars: make(map[uint]zenity.ProgressDialog),
}
return &UI{}
}
func (u *UI) Startup(ctx context.Context) {

View File

@ -70,7 +70,7 @@ func main() {
WindowIsTranslucent: true,
About: &mac.AboutInfo{
Title: "Rolens - Multiplatform MongoDB client",
Message: "© 2023 Romein van Buren",
Message: "© 2022-2024 Romein van Buren",
Icon: appIcon,
},
},

View File

@ -13,9 +13,9 @@
"info": {
"productName": "Rolens",
"companyName": "Romein van Buren",
"productVersion": "0.2.2",
"productVersion": "0.3.0",
"comments": "The intuitive MongoDB administration tool",
"copyright": "© Romein van Buren 2023 (GNU GPL 3.0)."
"copyright": "© Romein van Buren 2022-2024 (GNU GPL 3.0)."
},
"preBuildHooks": {
"*/*": "node ../version_to_file.js"

View File

@ -60,7 +60,7 @@ function copyStatic() {
fs.readdirSync(__dirname+'/static').forEach(function(fname) {
fs.copyFileSync(__dirname+'/static/'+fname, outdir+'/'+fname);
});
globSync(indir+'/**/*.{png,jpg,jpeg}').forEach(function(fname) {
globSync(indir+'/**/*.{png,jpg,jpeg,webp}').forEach(function(fname) {
const dest = outdir+'/'+fname.slice(indir.length + 1);
fs.mkdirSync(path.dirname(dest), { recursive: true });
fs.copyFileSync(fname, dest);
@ -119,6 +119,5 @@ module.exports = function (eleventyConfig) {
templateFormats: ['html', 'liquid', 'md', '11ty.js'],
markdownTemplateEngine: 'liquid',
htmlTemplateEngine: 'liquid',
pathPrefix: '/rolens/',
};
};

View File

@ -8,9 +8,17 @@
<title>{% if title %}{{ title }} — {% endif %}Rolens</title>
<meta name="author" content="Romein van Buren" />
<link rel="stylesheet" href="/styles.css">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
{{ content }}
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "55488ce2587f482eac31bc460f5b067b"}'></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More