cell data formatting in perspectives

This commit is contained in:
Jan Prochazka
2022-07-31 09:40:20 +02:00
parent 802f231e43
commit 37d5c6fbf9
5 changed files with 147 additions and 105 deletions

View File

@@ -0,0 +1,104 @@
<script context="module">
function makeBulletString(value) {
return _.pad('', value.length, '•');
}
function highlightSpecialCharacters(value) {
value = value.replace(/\n/g, '↲');
value = value.replace(/\r/g, '');
value = value.replace(/^(\s+)/, makeBulletString);
value = value.replace(/(\s+)$/, makeBulletString);
value = value.replace(/(\s\s+)/g, makeBulletString);
return value;
}
// const dateTimeRegex = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?Z?$/;
const dateTimeRegex =
/^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|()|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))$/;
function formatNumber(value) {
if (value >= 10000 || value <= -10000) {
if (getBoolSettingsValue('dataGrid.thousandsSeparator', false)) {
return value.toLocaleString();
} else {
return value.toString();
}
}
return value.toString();
}
function formatDateTime(testedString) {
const m = testedString.match(dateTimeRegex);
return `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}:${m[6]}`;
}
</script>
<script lang="ts">
import _, { isPlainObject, join } from 'lodash';
import ShowFormButton from '../formview/ShowFormButton.svelte';
import { getBoolSettingsValue } from '../settings/settingsTools';
import { arrayToHexString, isJsonLikeLongString, safeJsonParse } from 'dbgate-tools';
import { showModal } from '../modals/modalTools';
import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte';
import { openJsonDocument } from '../tabs/JsonTab.svelte';
import openNewTab from '../utility/openNewTab';
export let rowData;
export let value;
export let jsonParsedValue = undefined;
</script>
{#if rowData == null}
<span class="null">(No row)</span>
{:else if value === null}
<span class="null">(NULL)</span>
{:else if value === undefined}
<span class="null">(No field)</span>
{:else if _.isDate(value)}
{value.toString()}
{:else if value === true}
<span class="value">true</span>
{:else if value === false}
<span class="value">false</span>
{:else if _.isNumber(value)}
<span class="value">{formatNumber(value)}</span>
{:else if _.isString(value) && !jsonParsedValue}
{#if dateTimeRegex.test(value)}
<span class="value">
{formatDateTime(value)}
</span>
{:else}
{highlightSpecialCharacters(value)}
{/if}
{:else if value?.type == 'Buffer' && _.isArray(value.data)}
{#if value.data.length <= 16}
<span class="value">{'0x' + arrayToHexString(value.data)}</span>
{:else}
<span class="null">({value.data.length} bytes)</span>
{/if}
{:else if value.$oid}
<span class="value">ObjectId("{value.$oid}")</span>
{:else if _.isPlainObject(value)}
<span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span>
{:else if _.isArray(value)}
<span class="null" title={value.map(x => JSON.stringify(x)).join('\n')}>[{value.length} items]</span>
{:else if _.isPlainObject(jsonParsedValue)}
<span class="null" title={JSON.stringify(jsonParsedValue, undefined, 2)}>(JSON)</span>
{:else if _.isArray(jsonParsedValue)}
<span class="null" title={jsonParsedValue.map(x => JSON.stringify(x)).join('\n')}
>[{jsonParsedValue.length} items]</span
>
{:else}
{value.toString()}
{/if}
<style>
.null {
color: var(--theme-font-3);
font-style: italic;
}
.value {
color: var(--theme-icon-green);
}
</style>

View File

@@ -1,38 +1,3 @@
<script context="module">
function makeBulletString(value) {
return _.pad('', value.length, '•');
}
function highlightSpecialCharacters(value) {
value = value.replace(/\n/g, '↲');
value = value.replace(/\r/g, '');
value = value.replace(/^(\s+)/, makeBulletString);
value = value.replace(/(\s+)$/, makeBulletString);
value = value.replace(/(\s\s+)/g, makeBulletString);
return value;
}
// const dateTimeRegex = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?Z?$/;
const dateTimeRegex = /^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|()|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))$/;
function formatNumber(value) {
if (value >= 10000 || value <= -10000) {
if (getBoolSettingsValue('dataGrid.thousandsSeparator', false)) {
return value.toLocaleString();
} else {
return value.toString();
}
}
return value.toString();
}
function formatDateTime(testedString) {
const m = testedString.match(dateTimeRegex);
return `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}:${m[6]}`;
}
</script>
<script lang="ts">
import _, { isPlainObject, join } from 'lodash';
import ShowFormButton from '../formview/ShowFormButton.svelte';
@@ -42,6 +7,7 @@
import DictionaryLookupModal from '../modals/DictionaryLookupModal.svelte';
import { openJsonDocument } from '../tabs/JsonTab.svelte';
import openNewTab from '../utility/openNewTab';
import CellValue from './CellValue.svelte';
export let rowIndex;
export let col;
@@ -101,49 +67,7 @@
class:isFocusedColumn
{style}
>
{#if rowData == null}
<span class="null">(No row)</span>
{:else if value === null}
<span class="null">(NULL)</span>
{:else if value === undefined}
<span class="null">(No field)</span>
{:else if _.isDate(value)}
{value.toString()}
{:else if value === true}
<span class="value">true</span>
{:else if value === false}
<span class="value">false</span>
{:else if _.isNumber(value)}
<span class="value">{formatNumber(value)}</span>
{:else if _.isString(value) && !jsonParsedValue}
{#if dateTimeRegex.test(value)}
<span class="value">
{formatDateTime(value)}
</span>
{:else}
{highlightSpecialCharacters(value)}
{/if}
{:else if value?.type == 'Buffer' && _.isArray(value.data)}
{#if value.data.length <= 16}
<span class="value">{'0x' + arrayToHexString(value.data)}</span>
{:else}
<span class="null">({value.data.length} bytes)</span>
{/if}
{:else if value.$oid}
<span class="value">ObjectId("{value.$oid}")</span>
{:else if _.isPlainObject(value)}
<span class="null" title={JSON.stringify(value, undefined, 2)}>(JSON)</span>
{:else if _.isArray(value)}
<span class="null" title={value.map(x => JSON.stringify(x)).join('\n')}>[{value.length} items]</span>
{:else if _.isPlainObject(jsonParsedValue)}
<span class="null" title={JSON.stringify(jsonParsedValue, undefined, 2)}>(JSON)</span>
{:else if _.isArray(jsonParsedValue)}
<span class="null" title={jsonParsedValue.map(x => JSON.stringify(x)).join('\n')}
>[{jsonParsedValue.length} items]</span
>
{:else}
{value.toString()}
{/if}
<CellValue {rowData} {value} {jsonParsedValue} />
{#if allowHintField && rowData && _.some(col.hintColumnNames, hintColumnName => rowData[hintColumnName])}
<span class="hint"
@@ -256,13 +180,6 @@
color: var(--theme-font-3);
margin-left: 5px;
}
.null {
color: var(--theme-font-3);
font-style: italic;
}
.value {
color: var(--theme-icon-green);
}
.autoFillMarker {
width: 8px;

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import CellValue from '../datagrid/CellValue.svelte';
export let value;
export let rowSpan;
export let rowData;
</script>
<td rowspan={rowSpan}>
{#if value !== undefined}
<CellValue {rowData} {value} />
{/if}
</td>
<style>
td {
font-weight: normal;
/* border: 1px solid var(--theme-border); */
background-color: var(--theme-bg-0);
padding: 2px;
position: relative;
overflow: hidden;
vertical-align: top;
border-bottom: 1px solid var(--theme-border);
border-right: 1px solid var(--theme-border);
}
</style>

View File

@@ -13,7 +13,7 @@
<script lang="ts">
import { PerspectiveDisplay, PerspectiveTreeNode } from 'dbgate-datalib';
import _ from 'lodash';
import _, { values } from 'lodash';
import { onMount } from 'svelte';
import resizeObserver from '../utility/resizeObserver';
import PerspectiveIntersectionObserver from './PerspectiveIntersectionObserver.svelte';
@@ -25,6 +25,8 @@
import registerCommand from '../commands/registerCommand';
import createActivator, { getActiveComponent } from '../utility/createActivator';
import { openJsonDocument } from '../tabs/JsonTab.svelte';
import PerspectiveCell from './PerspectiveCell.svelte';
import DataGridCell from '../datagrid/DataGridCell.svelte';
const dbg = debug('dbgate:PerspectivaTable');
export const activator = createActivator('PerspectiveTable', true);
@@ -196,13 +198,12 @@
>
{:else}
{#each display.columns as column}
<!-- <td>{row.rowSpans[column.columnIndex]} {row.rowData[column.columnIndex]}</td> -->
{#if !row.rowCellSkips[column.columnIndex]}
{#if row.rowData[column.columnIndex] === undefined}
<td />
{:else}
<td rowspan={row.rowSpans[column.columnIndex]}>{row.rowData[column.columnIndex]}</td>
{/if}
<PerspectiveCell
value={row.rowData[column.columnIndex]}
rowSpan={row.rowSpans[column.columnIndex]}
rowData={row.rowData}
/>
{/if}
{/each}
{/if}
@@ -282,18 +283,6 @@
border-top: 1px solid var(--theme-border);
}
td {
font-weight: normal;
/* border: 1px solid var(--theme-border); */
background-color: var(--theme-bg-0);
padding: 2px;
position: relative;
overflow: hidden;
vertical-align: top;
border-bottom: 1px solid var(--theme-border);
border-right: 1px solid var(--theme-border);
}
/*
table {
border: 1px solid;