1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-01-18 13:07:58 +00:00

Use Webdesq objecttree instead highlight.js

This commit is contained in:
Romein van Buren 2023-01-19 08:57:25 +01:00
parent 44d4fb843d
commit a4698eee43
Signed by: romein
GPG Key ID: 0EFF8478ADDF6C49
9 changed files with 270 additions and 112 deletions

View File

@ -7,9 +7,6 @@
"": {
"name": "frontend",
"version": "0.0.0",
"dependencies": {
"highlight.js": "^11.7.0"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"eslint": "^8.31.0",
@ -1891,14 +1888,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/highlight.js": {
"version": "11.7.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -4534,11 +4523,6 @@
"has-symbols": "^1.0.2"
}
},
"highlight.js": {
"version": "11.7.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ=="
},
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",

View File

@ -21,8 +21,5 @@
"nodejs",
"svelte3"
]
},
"dependencies": {
"highlight.js": "^11.7.0"
}
}

View File

@ -1 +1 @@
d445254075c563425c5b0fd21e804d4a
e25516ba8abdacf5ab40609a5d48f542

View File

@ -1,18 +1,12 @@
<script>
import CodeViewer from './codeviewer.svelte';
export let code = '';
let modalCode = '';
</script>
<div class="examplecode" on:pointerdown={() => modalCode = code}>
<div class="examplecode">
<strong>CLI command</strong>
<code>{code}</code>
</div>
<CodeViewer bind:code={modalCode} language="js" />
<style>
.examplecode {
border: 1px solid #ccc;

View File

@ -1,74 +0,0 @@
<script>
import hljs from 'highlight.js/lib/core';
import hljsJSON from 'highlight.js/lib/languages/json';
import hljsJavaScript from 'highlight.js/lib/languages/javascript';
import Icon from './icon.svelte';
import Modal from './modal.svelte';
import 'highlight.js/styles/atom-one-dark.css';
import { onDestroy } from 'svelte';
export let code = '';
export let language = 'json';
const languageNames = {
json: 'JSON',
js: 'JavaScript',
};
hljs.registerLanguage('json', hljsJSON);
hljs.registerLanguage('js', hljsJavaScript);
let copySucceeded = false;
let timeout;
$: highlighted = code ? hljs.highlight(code, { language }).value : '';
async function copy() {
await navigator.clipboard.writeText(code);
copySucceeded = true;
timeout = setTimeout(() => copySucceeded = false, 1500);
}
onDestroy(() => clearTimeout(timeout));
</script>
{#if code}
<Modal bind:show={code} title="{languageNames[language]} viewer" contentPadding={false}>
<div class="codeblock">
<div class="buttons">
<button class="btn" on:click={copy}>
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
</button>
</div>
<pre><code class="hljs">{@html highlighted}</code></pre>
</div>
</Modal>
{/if}
<style>
.codeblock {
position: relative;
}
.buttons {
position: absolute;
top: 0;
right: 0;
margin: 1rem;
}
.buttons button {
margin-left: 1rem;
background: none;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.buttons button:hover {
background-color: rgba(0, 0, 0, 0.3);
}
.hljs {
user-select: text;
line-height: 1.2;
}
pre :global(::selection) {
background: rgba(5, 5, 5, 0.8);
}
</style>

View File

@ -0,0 +1,208 @@
<script>
export let data;
export let depth = 0;
export let readonly = false;
export let level = 0;
export let last = true;
export let draggable = false;
export let kp = '';
const collapsedSymbol = '...';
const getType = i => {
if (i === null) {
return 'null';
}
return typeof i;
};
let displayOnly = true;
let items;
let isArray;
let openBracket;
let closeBracket;
$: {
items = getType(data) === 'object' ? Object.keys(data) : [];
isArray = Array.isArray(data);
openBracket = isArray ? '[' : '{';
closeBracket = isArray ? ']' : '}';
}
let collapsed;
$: collapsed = depth < level;
const format = i => {
switch (getType(i)) {
case 'string':
return `${i}`;
case 'function':
return 'f () {...}';
case 'symbol':
return i.toString();
default:
return i;
}
};
const clicked = e => {
if (e.shiftKey) {
if (depth == 0) {
depth = 999;
}
else {
depth = 0;
}
}
collapsed = !collapsed;
};
let invalid = false;
let dbg;
function json2data() {
try {
data = JSON.parse(dbg.value);
invalid = false;
}
catch {
invalid = true;
if (dbg.value.trim == '') {
data = {};
}
}
}
function dragstart(e, keypath, value) {
console.log('kp:', keypath);
const item = {};
item[keypath] = value;
e.dataTransfer.setData('text/plain', JSON.stringify(item));
}
function onKeydown(event) {
const save = (event.key === 's') && (event.metaKey || event.ctrlKey);
if (!save) {
event.stopPropagation();
}
}
</script>
{#if displayOnly}
{#if items.length}
<span class:root={level == 0} class:hidden={collapsed}>
{#if draggable && isArray}
<span on:dragstart={e => dragstart(e, kp, data)} draggable="true" class="bracket" on:click={clicked} tabindex="0">{openBracket}</span>
{:else}
<span class="bracket" on:click={clicked} tabindex="0">{openBracket}</span>
{/if}
<ul on:dblclick={() => (readonly ? displayOnly = true : displayOnly = false)} >
{#each items as i, idx}
<li>
{#if !isArray}
{#if draggable}
<span on:dragstart={e => dragstart(e, kp ? kp + '.' + i : i, data[i])} draggable="true" class="key">{i}:</span>
{:else}
<span class="key">{i}:</span>
{/if}
{/if}
{#if getType(data[i]) === 'object'}
<svelte:self {readonly} {draggable} kp={kp ? kp + '.' + i : i} data={data[i]} {depth} level={level + 1} last={idx === items.length - 1} />
{:else}
{#if draggable}
<span on:dragstart={e => dragstart(e, kp ? kp + '.' + i : i, data[i])} draggable="true" class="val {getType(data[i])}">{format(data[i])}</span>{#if idx < items.length - 1}<span draggable class="comma">,</span>{/if}
{:else}
<span class="val {getType(data[i])}">{format(data[i])}</span>{#if idx < items.length - 1}<span class="comma">,</span>{/if}
{/if}
{/if}
</li>
{/each}
</ul>
<span class="bracket" on:click={clicked} tabindex="0">{closeBracket}</span>{#if !last}<span
class="comma">,</span>
{/if}
</span>
<span style="padding: {level == 0 ? 10 : 0}px;" class="bracket" class:hidden={!collapsed} on:click={clicked} tabindex="0">{openBracket}{collapsedSymbol}{closeBracket}</span>{#if !last && collapsed}<span class="comma">,</span>{/if}
{:else}
{@html isArray ? '[]' : '{}'}
{/if}
{:else}
<textarea on:keydown="{onKeydown}" class="debug" spellcheck="false" bind:this={dbg} class:invalid on:input={json2data}>{JSON.stringify(data, null, 2)}</textarea>
{/if}
<style>
ul {
list-style: none;
margin: 0;
padding: 0;
font-family: inherit;
font-size: inherit;
padding-left: var(--nodePaddingLeft, 1rem);
border-left: var(--nodeBorderLeft, 1px dashed #d0d0f0);
color: var(--nodeColor, #666);
}
li {
white-space: nowrap;
}
.root {
font-family: menlo, monospace;
font-size: 90%;
overflow: auto;
}
.hidden {
display: none;
}
.bracket {
cursor: pointer;
}
.bracket:hover {
background: var(--bracketHoverBackground, #d1d5db);
}
.comma {
color: var(--nodeColor, #374151);
opacity: 0.5;
}
.val {
color: var(--leafDefaultColor, #9ca3af);
white-space: nowrap;
}
.val[draggable] {
cursor: move;
}
.val.string {
color: var(--leafStringColor, #000);
}
.val.string:before {
content: "'";
opacity: 0.4;
}
.val.string:after {
content: "'";
opacity: 0.4;
}
.val.number {
color: var(--leafNumberColor, #d97706);
}
.val.boolean {
color: var(--leafBooleanColor, #3994dd);
}
.key.draggable {
cursor: move;
}
textarea.debug {
font-family: menlo, monospace;
padding: 10px;
flex: 1 0;
white-space: pre;
font-size: 90%;
border: none;
margin: 0;
height: 100%;
outline: none;
line-height: 1.5;
resize: none;
}
textarea.invalid {
background: #ffe3e3;
color: #b30202 !important;
}
</style>

View File

@ -0,0 +1,52 @@
<script>
import Icon from './icon.svelte';
import Modal from './modal.svelte';
import ObjectTree from './objecttree.svelte';
import { onDestroy } from 'svelte';
export let data;
let copySucceeded = false;
let timeout;
async function copy() {
await navigator.clipboard.writeText(JSON.stringify(data));
copySucceeded = true;
timeout = setTimeout(() => copySucceeded = false, 1500);
}
onDestroy(() => clearTimeout(timeout));
</script>
{#if data}
<Modal bind:show={data} title="Object viewer" contentPadding={false}>
<div class="objectviewer">
<div class="buttons">
<button class="btn" on:click={copy}>
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
</button>
</div>
<div class="code">
<ObjectTree {data} />
</div>
</div>
</Modal>
{/if}
<style>
.objectviewer {
position: relative;
}
.code {
padding: 1rem;
}
.buttons {
position: absolute;
top: 0;
right: 0;
margin: 1rem;
}
.buttons button {
margin-left: 1rem;
}
</style>

View File

@ -4,7 +4,7 @@
import { input } from '../../../actions';
import ObjectGrid from '../../../components/objectgrid.svelte';
import Icon from '../../../components/icon.svelte';
import CodeViewer from '../../../components/codeviewer.svelte';
import ObjectViewer from '../../../components/objectviewer.svelte';
export let collection;
@ -21,7 +21,7 @@
let submittedForm = {};
let queryField;
let activePath = '';
let json = '';
let objectViewerData;
$: 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})` : ''};`;
async function submitQuery() {
@ -57,10 +57,7 @@
function openJson(itemId) {
const item = result?.results?.find(i => i._id == itemId);
if (!item) {
return;
}
json = JSON.stringify(item, undefined, 2);
objectViewerData = item;
}
export function performQuery(q) {
@ -133,7 +130,7 @@
</div>
</div>
<CodeViewer bind:code={json} language="json" />
<ObjectViewer bind:data={objectViewerData} />
<style>
.find {

View File

@ -1,5 +1,5 @@
<script>
import CodeViewer from '../../../components/codeviewer.svelte';
import ObjectViewer from '../../../components/objectviewer.svelte';
import ObjectGrid from '../../../components/objectgrid.svelte';
import { DropIndex, GetIndexes } from '../../../../wailsjs/go/app/App';
@ -7,7 +7,7 @@
let indexes = [];
let activeKey = '';
let json = '';
let objectViewerData = '';
async function getIndexes() {
const result = await GetIndexes(collection.hostKey, collection.dbKey, collection.key);
@ -29,7 +29,7 @@
function openJson(indexId) {
const item = indexes?.filter(i => i.name == indexId);
json = JSON.stringify(item, undefined, 2);
objectViewerData = item;
}
</script>
@ -50,7 +50,7 @@
</div>
</div>
<CodeViewer bind:code={json} language="json" />
<ObjectViewer bind:data={objectViewerData} />
<style>
.indexes {