mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-07 14:57:12 -04:00
Merge 8545fc6fa5
into 63fbd3b45c
This commit is contained in:
commit
6759a97ec7
9 changed files with 321 additions and 7 deletions
9
components.d.ts
vendored
9
components.d.ts
vendored
|
@ -109,6 +109,7 @@ declare module '@vue/runtime-core' {
|
|||
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
|
||||
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
|
||||
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
|
||||
JsonSizeAnalyzer: typeof import('./src/tools/json-size-analyzer/json-size-analyzer.vue')['default']
|
||||
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
|
||||
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
|
||||
JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default']
|
||||
|
@ -138,11 +139,15 @@ declare module '@vue/runtime-core' {
|
|||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NInput: typeof import('naive-ui')['NInput']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
NLayout: typeof import('naive-ui')['NLayout']
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NTable: typeof import('naive-ui')['NTable']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTree: typeof import('naive-ui')['NTree']
|
||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
"iarna-toml-esm": "^3.0.5",
|
||||
"ibantools": "^4.3.3",
|
||||
"js-base64": "^3.7.6",
|
||||
"json-analyzer": "^1.2.2",
|
||||
"json5": "^2.2.3",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"libphonenumber-js": "^1.10.28",
|
||||
|
|
59
pnpm-lock.yaml
generated
59
pnpm-lock.yaml
generated
|
@ -107,6 +107,9 @@ dependencies:
|
|||
js-base64:
|
||||
specifier: ^3.7.6
|
||||
version: 3.7.7
|
||||
json-analyzer:
|
||||
specifier: ^1.2.2
|
||||
version: 1.2.2
|
||||
json5:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3
|
||||
|
@ -3412,7 +3415,7 @@ packages:
|
|||
dependencies:
|
||||
'@unhead/dom': 0.5.1
|
||||
'@unhead/schema': 0.5.1
|
||||
'@vueuse/shared': 11.0.3(vue@3.3.4)
|
||||
'@vueuse/shared': 11.1.0(vue@3.3.4)
|
||||
unhead: 0.5.1
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
|
@ -4054,8 +4057,8 @@ packages:
|
|||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@11.0.3(vue@3.3.4):
|
||||
resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==}
|
||||
/@vueuse/shared@11.1.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.10(vue@3.3.4)
|
||||
transitivePeerDependencies:
|
||||
|
@ -4581,6 +4584,11 @@ packages:
|
|||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||
dev: true
|
||||
|
||||
/colors@1.4.0:
|
||||
resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==}
|
||||
engines: {node: '>=0.1.90'}
|
||||
dev: false
|
||||
|
||||
/combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
@ -6636,6 +6644,21 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/json-analyzer@1.2.2:
|
||||
resolution: {integrity: sha512-3xWTxyIggxOYIPT9NkucQPxlOBPJY14/ifely3eCtifE5pAxJXl/jUmSDwq+fLVhHIIj9MIJ6Bv7u3ItChG8vQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
commander: 2.20.3
|
||||
lodash.flowright: 3.5.0
|
||||
lodash.get: 4.4.2
|
||||
lodash.isobject: 3.0.2
|
||||
pako: 1.0.11
|
||||
pretty-bytes: 5.6.0
|
||||
prettyjson: 1.2.5
|
||||
utf8-length: 0.0.1
|
||||
dev: false
|
||||
|
||||
/json-parse-even-better-errors@2.3.1:
|
||||
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
|
||||
dev: true
|
||||
|
@ -6775,6 +6798,18 @@ packages:
|
|||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
dev: true
|
||||
|
||||
/lodash.flowright@3.5.0:
|
||||
resolution: {integrity: sha512-YxTYuodkvyINbDInmFcGGvkQwoAuoGUYosqstRTr5eq63GQt7WQ2xFU0wG1UfdbKYPwevd3zWDd6ybEE2g6qvA==}
|
||||
dev: false
|
||||
|
||||
/lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
dev: false
|
||||
|
||||
/lodash.isobject@3.0.2:
|
||||
resolution: {integrity: sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==}
|
||||
dev: false
|
||||
|
||||
/lodash.merge@4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
dev: true
|
||||
|
@ -7022,7 +7057,6 @@ packages:
|
|||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: true
|
||||
|
||||
/mlly@1.4.0:
|
||||
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
|
||||
|
@ -7341,6 +7375,10 @@ packages:
|
|||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
/pako@1.0.11:
|
||||
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||
dev: false
|
||||
|
||||
/param-case@2.1.1:
|
||||
resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==}
|
||||
dependencies:
|
||||
|
@ -7573,7 +7611,6 @@ packages:
|
|||
/pretty-bytes@5.6.0:
|
||||
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/pretty-bytes@6.1.0:
|
||||
resolution: {integrity: sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==}
|
||||
|
@ -7589,6 +7626,14 @@ packages:
|
|||
react-is: 18.2.0
|
||||
dev: true
|
||||
|
||||
/prettyjson@1.2.5:
|
||||
resolution: {integrity: sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
colors: 1.4.0
|
||||
minimist: 1.2.8
|
||||
dev: false
|
||||
|
||||
/prosemirror-changeset@2.2.1:
|
||||
resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==}
|
||||
dependencies:
|
||||
|
@ -9048,6 +9093,10 @@ packages:
|
|||
requires-port: 1.0.0
|
||||
dev: true
|
||||
|
||||
/utf8-length@0.0.1:
|
||||
resolution: {integrity: sha512-j/XH2ftofBiobnyApxlN/J6j/ixwT89WEjDcjT66d2i0+GIn9RZfzt8lpEXXE4jUe4NsjBSUq70kS2euQ4nnMw==}
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: true
|
||||
|
|
|
@ -2,6 +2,7 @@ import { tool as base64FileConverter } from './base64-file-converter';
|
|||
import { tool as base64StringConverter } from './base64-string-converter';
|
||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||
import { tool as emailNormalizer } from './email-normalizer';
|
||||
import { tool as jsonSizeAnalyzer } from './json-size-analyzer';
|
||||
|
||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||
|
||||
|
@ -151,6 +152,7 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
crontabGenerator,
|
||||
jsonViewer,
|
||||
jsonMinify,
|
||||
jsonSizeAnalyzer,
|
||||
jsonToCsv,
|
||||
sqlPrettify,
|
||||
chmodCalculator,
|
||||
|
|
12
src/tools/json-size-analyzer/index.ts
Normal file
12
src/tools/json-size-analyzer/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { FileAnalytics } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Json Size Analyzer',
|
||||
path: '/json-size-analyzer',
|
||||
description: 'Measure JSON nodes relative weights',
|
||||
keywords: ['json', 'size', 'analyzer'],
|
||||
component: () => import('./json-size-analyzer.vue'),
|
||||
icon: FileAnalytics,
|
||||
createdAt: new Date('2024-07-14'),
|
||||
});
|
13
src/tools/json-size-analyzer/json-analyzer.d.ts
vendored
Normal file
13
src/tools/json-size-analyzer/json-analyzer.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
declare module 'json-analyzer' {
|
||||
export default function analyze({
|
||||
json,
|
||||
verbose,
|
||||
maxDepth,
|
||||
target,
|
||||
}: {
|
||||
json: any,
|
||||
verbose: boolean,
|
||||
maxDepth: number,
|
||||
target: string,
|
||||
});
|
||||
}
|
113
src/tools/json-size-analyzer/json-size-analyzer.service.test.ts
Normal file
113
src/tools/json-size-analyzer/json-size-analyzer.service.test.ts
Normal file
|
@ -0,0 +1,113 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { getJsonUsageTreeNodes } from './json-size-analyzer.service';
|
||||
|
||||
describe('json-size-analyzer', () => {
|
||||
describe('getJsonUsageTreeNodes', () => {
|
||||
it('return correct tree nodes structures', () => {
|
||||
expect(getJsonUsageTreeNodes([{ a: [1, 2, 3] }, { b: 'a' }])).to.deep.eq({
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [],
|
||||
key: '$.[0].a.[0]',
|
||||
label: '$.[0].a.[0]: 1 B(26 B gzip)',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.[0].a.[1]',
|
||||
label: '$.[0].a.[1]: 1 B(24 B gzip)',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.[0].a.[2]',
|
||||
label: '$.[0].a.[2]: 1 B(25 B gzip)',
|
||||
},
|
||||
],
|
||||
key: '$.[0].a',
|
||||
label: '$.[0].a: 7 B(35 B gzip) ; 28.000% of parent ; biggest child node: \'0\'',
|
||||
},
|
||||
],
|
||||
key: '$.[0]',
|
||||
label: '$.[0]: 13 B(43 B gzip) ; 52.000% of parent ; biggest child node: \'a\'',
|
||||
},
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [],
|
||||
key: '$.[1].b',
|
||||
label: '$.[1].b: 1 B(25 B gzip)',
|
||||
},
|
||||
],
|
||||
key: '$.[1]',
|
||||
label: '$.[1]: 9 B(34 B gzip) ; 36.000% of parent ; biggest child node: \'b\'',
|
||||
},
|
||||
],
|
||||
key: '$',
|
||||
label: '$: 25 B(61 B gzip) ; 100.00% of parent ; biggest child node: \'0\'',
|
||||
});
|
||||
expect(getJsonUsageTreeNodes({ a: { b: [1, 2, 3], c: 12 } })).to.deep.eq({
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.b.[0]',
|
||||
label: '$.a.b.[0]: 1 B(26 B gzip)',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.b.[1]',
|
||||
label: '$.a.b.[1]: 1 B(24 B gzip)',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.b.[2]',
|
||||
label: '$.a.b.[2]: 1 B(25 B gzip)',
|
||||
},
|
||||
],
|
||||
key: '$.a.b',
|
||||
label: '$.a.b: 7 B(35 B gzip) ; 26.923% of parent ; biggest child node: \'0\'',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.c',
|
||||
label: '$.a.c: 2 B(24 B gzip)',
|
||||
},
|
||||
],
|
||||
key: '$.a',
|
||||
label: '$.a: 20 B(50 B gzip) ; 76.923% of parent ; biggest child node: \'b\'',
|
||||
},
|
||||
],
|
||||
key: '$',
|
||||
label: '$: 26 B(63 B gzip) ; 100.00% of parent ; biggest child node: \'a\'',
|
||||
});
|
||||
expect(getJsonUsageTreeNodes({ a: { b: 'azerty', c: 'ueop' } })).to.deep.eq({
|
||||
children: [
|
||||
{
|
||||
children: [
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.b',
|
||||
label: '$.a.b: 6 B(30 B gzip)',
|
||||
},
|
||||
{
|
||||
children: [],
|
||||
key: '$.a.c',
|
||||
label: '$.a.c: 4 B(29 B gzip)',
|
||||
},
|
||||
],
|
||||
key: '$.a',
|
||||
label: '$.a: 25 B(51 B gzip) ; 80.645% of parent ; biggest child node: \'b\'',
|
||||
},
|
||||
],
|
||||
key: '$',
|
||||
label: '$: 31 B(61 B gzip) ; 100.00% of parent ; biggest child node: \'a\'',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
51
src/tools/json-size-analyzer/json-size-analyzer.service.ts
Normal file
51
src/tools/json-size-analyzer/json-size-analyzer.service.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import jsonAnalyzer from 'json-analyzer';
|
||||
|
||||
export interface Meta {
|
||||
__meta__: {
|
||||
size?: {
|
||||
value: number
|
||||
raw: string
|
||||
gzip: string
|
||||
}
|
||||
number_of_childs?: number
|
||||
parent_relative_percentage?: string
|
||||
biggest_node_child: string
|
||||
}
|
||||
}
|
||||
export type AnalysisNode = {
|
||||
[key: string]: object & Meta
|
||||
} & Meta;
|
||||
|
||||
export type TreeNode = {
|
||||
key: string
|
||||
label: string
|
||||
children: Array<TreeNode>
|
||||
} & Record<string, unknown>;
|
||||
|
||||
function getTreeNodes(obj: AnalysisNode, parentName: string): TreeNode {
|
||||
const childNodes = Object.entries(obj)
|
||||
.filter(([key, v]) => key !== '__meta__' && typeof v === 'object')
|
||||
.map(([k, v]) => ({
|
||||
key: (Number.isNaN(Number.parseInt(k, 10)) ? `.${k}` : `.[${k}]`),
|
||||
value: v as AnalysisNode,
|
||||
}));
|
||||
const biggest_child_node = obj.__meta__.biggest_node_child ? ` ; biggest child node: '${obj.__meta__.biggest_node_child}'` : '';
|
||||
const parent_relative_percentage = obj.__meta__.parent_relative_percentage ? ` ; ${obj.__meta__.parent_relative_percentage} of parent` : '';
|
||||
return {
|
||||
key: parentName,
|
||||
label: obj.__meta__
|
||||
? `${parentName}: ${obj.__meta__.size?.raw}(${obj.__meta__.size?.gzip} gzip)${parent_relative_percentage}${biggest_child_node}`
|
||||
: parentName,
|
||||
children: childNodes.map(childNode => getTreeNodes(childNode.value, parentName + childNode.key)),
|
||||
};
|
||||
}
|
||||
|
||||
export function getJsonUsageTreeNodes(jsonObj: any, maxDepth: number = 100, targetNode: string = ''): TreeNode {
|
||||
const analysis = jsonAnalyzer({
|
||||
json: jsonObj,
|
||||
verbose: true,
|
||||
maxDepth,
|
||||
target: targetNode,
|
||||
});
|
||||
return getTreeNodes(analysis, '$');
|
||||
}
|
68
src/tools/json-size-analyzer/json-size-analyzer.vue
Normal file
68
src/tools/json-size-analyzer/json-size-analyzer.vue
Normal file
|
@ -0,0 +1,68 @@
|
|||
<script setup lang="ts">
|
||||
import JSON5 from 'json5';
|
||||
import { getJsonUsageTreeNodes } from './json-size-analyzer.service';
|
||||
import { useValidation } from '@/composable/validation';
|
||||
|
||||
const json = ref('{"a": 1, "b": [1,2,3]}');
|
||||
const maxDepth = ref(100);
|
||||
const target = ref('');
|
||||
|
||||
const jsonSizes = computed(() => {
|
||||
const jsonObj = JSON5.parse(json.value);
|
||||
if (!jsonObj) {
|
||||
return null;
|
||||
}
|
||||
return [getJsonUsageTreeNodes(jsonObj, maxDepth.value - 1, target.value)];
|
||||
});
|
||||
const searchInAnalysis = ref('');
|
||||
|
||||
const jsonValidation = useValidation({
|
||||
source: json,
|
||||
rules: [
|
||||
{
|
||||
validator: (v) => {
|
||||
return JSON5.parse(v);
|
||||
},
|
||||
message: 'Provided JSON is not valid.',
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="max-width: 600px;">
|
||||
<c-card title="Input" mb-2>
|
||||
<c-input-text
|
||||
v-model:value="json"
|
||||
label="JSON"
|
||||
multiline
|
||||
placeholder="Put your JSON data here..."
|
||||
rows="5"
|
||||
:validation="jsonValidation"
|
||||
mb-2
|
||||
/>
|
||||
|
||||
<n-form-item label="Max Depth:" label-placement="left">
|
||||
<n-input-number v-model:value="maxDepth" :min="0" w-full />
|
||||
</n-form-item>
|
||||
|
||||
<c-input-text
|
||||
v-model:value="target"
|
||||
label="Target Node"
|
||||
placeholder="Where to start the analyze (ie, a[0].b.c)"
|
||||
mb-2
|
||||
/>
|
||||
</c-card>
|
||||
|
||||
<c-card v-if="jsonSizes" title="Analysis">
|
||||
<n-input v-model:value="searchInAnalysis" placeholder="Search in result" />
|
||||
<n-tree
|
||||
:show-irrelevant-nodes="false"
|
||||
:pattern="searchInAnalysis"
|
||||
:default-expand-all="true"
|
||||
:data="jsonSizes"
|
||||
block-line
|
||||
/>
|
||||
</c-card>
|
||||
</div>
|
||||
</template>
|
Loading…
Add table
Add a link
Reference in a new issue