Skip to content

Commit 5bb9bf7

Browse files
committed
feat: show container size
1 parent 8b59022 commit 5bb9bf7

File tree

9 files changed

+106
-9
lines changed

9 files changed

+106
-9
lines changed

src/ReactUnipika/ReactUnipika.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface ReactUnipikaProps {
2222
toolbarStickyTop?: number;
2323
renderToolbar?: (props: ToolbarProps) => React.ReactNode;
2424
collapseIconType?: CollapseIconType;
25+
showContainerSize?: boolean;
2526
}
2627

2728
const defaultUnipikaSettings = {
@@ -45,6 +46,7 @@ export function ReactUnipika({
4546
toolbarStickyTop = 0,
4647
renderToolbar,
4748
collapseIconType,
49+
showContainerSize,
4850
}: ReactUnipikaProps) {
4951
const convertedValue = React.useMemo(() => {
5052
// TODO: fix me later
@@ -98,6 +100,7 @@ export function ReactUnipika({
98100
toolbarStickyTop={toolbarStickyTop}
99101
renderToolbar={renderToolbar}
100102
collapseIconType={collapseIconType}
103+
showContainerSize={showContainerSize}
101104
/>
102105
) : (
103106
<pre

src/ReactUnipika/__stories__/ReactUnipika.stories.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,18 @@ export const WithContentAbove: StoryObj<ReactUnipikaProps> = {
3737
);
3838
},
3939
};
40+
41+
export const WithContainerSize: StoryObj<ReactUnipikaProps> = {
42+
args: {
43+
value: data,
44+
showContainerSize: true,
45+
},
46+
};
47+
48+
export const WithContainerSizeYson: StoryObj<ReactUnipikaProps> = {
49+
args: {
50+
value: data,
51+
settings: {format: 'yson'},
52+
showContainerSize: true,
53+
},
54+
};

src/StructuredYson/Cell.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {ClickableText} from '../ClickableText/ClickableText';
1414

1515
import {cn} from '../utils/classname';
1616

17+
import i18n from './i18n';
18+
1719
import './Cell.scss';
1820

1921
const block = cn('g-ru-cell');
@@ -29,6 +31,7 @@ export interface CellProps {
2931
index: number;
3032
showFullText: (index: number) => void;
3133
collapseIconType?: CollapseIconType;
34+
showContainerSize?: boolean;
3235
}
3336

3437
export const JSON_VALUE_KEY = {
@@ -62,7 +65,18 @@ function getLevelOffsetSpaces(level: number) {
6265

6366
export function Cell(props: CellProps) {
6467
const {
65-
row: {level, open, close, key, value, hasDelimiter, path, collapsed, isAfterAttributes},
68+
row: {
69+
level,
70+
open,
71+
close,
72+
key,
73+
value,
74+
hasDelimiter,
75+
path,
76+
collapsed,
77+
isAfterAttributes,
78+
depth,
79+
},
6680
settings,
6781
yson,
6882
onToggleCollapse,
@@ -104,6 +118,9 @@ export function Cell(props: CellProps) {
104118
isAfterAttributes={isAfterAttributes}
105119
/>
106120
{open && <OpenClose type={open} yson={yson} settings={settings} />}
121+
{props.showContainerSize && depth !== undefined && (
122+
<span className={'unipika'}>{i18n('context_items-count', {count: depth})}</span>
123+
)}
107124
{value !== undefined && (
108125
<Value
109126
text={value}
@@ -114,7 +131,7 @@ export function Cell(props: CellProps) {
114131
showFullText={handleShowFullText}
115132
/>
116133
)}
117-
{collapsed && <span className={'unipika'}>...</span>}
134+
{collapsed && depth === undefined && <span className={'unipika'}>...</span>}
118135
{close && <OpenClose type={close} yson={yson} settings={settings} close />}
119136
{hasDelimiter && <SlaveText text={yson ? ';' : ','} />}
120137
</div>

src/StructuredYson/StructuredYson.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ interface Props {
3939
toolbarStickyTop?: number;
4040
renderToolbar?: (props: ToolbarProps) => React.ReactNode;
4141
collapseIconType?: CollapseIconType;
42+
showContainerSize?: boolean;
4243
}
4344

4445
interface State {
@@ -155,7 +156,7 @@ export class StructuredYson extends React.PureComponent<Props, State> {
155156
settings,
156157
filter,
157158
} = this.state;
158-
const {collapseIconType} = this.props;
159+
const {collapseIconType, showContainerSize} = this.props;
159160

160161
return (
161162
<Table
@@ -168,6 +169,7 @@ export class StructuredYson extends React.PureComponent<Props, State> {
168169
onShowFullText={this.onShowFullText}
169170
scrollToRef={this.tableRef}
170171
collapseIconType={collapseIconType}
172+
showContainerSize={showContainerSize}
171173
/>
172174
);
173175
}

src/StructuredYson/Table.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface TableProps {
2020
onShowFullText: (index: number) => void;
2121
scrollToRef: React.RefObject<null | {scrollToIndex(index: number): void}>;
2222
collapseIconType?: CollapseIconType;
23+
showContainerSize?: boolean;
2324
}
2425

2526
export const Table: React.FC<TableProps> = ({
@@ -32,6 +33,7 @@ export const Table: React.FC<TableProps> = ({
3233
onShowFullText,
3334
scrollToRef,
3435
collapseIconType,
36+
showContainerSize,
3537
}) => {
3638
const renderCell: ColumnDef<UnipikaFlattenTreeItem>['cell'] = ({row}) => {
3739
const {original, index} = row;
@@ -46,6 +48,7 @@ export const Table: React.FC<TableProps> = ({
4648
showFullText={onShowFullText}
4749
index={index}
4850
collapseIconType={collapseIconType}
51+
showContainerSize={showContainerSize}
4952
/>
5053
);
5154
};

src/StructuredYson/i18n/en.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"action_collapse-all": "Collapse all",
3+
"action_expand-all": "Expand all",
4+
"action_next": "Next",
5+
"action_back": "Back",
6+
"description_search": "Search...",
7+
"description_matched-rows": "Matched rows",
8+
"context_items-count": [
9+
" {{count}} item ",
10+
" {{count}} items ",
11+
" {{count}} items ",
12+
" {{count}} items "
13+
]
14+
}

src/StructuredYson/i18n/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {makeKeyset} from '../../i18n';
2+
3+
import en from './en.json';
4+
import ru from './ru.json';
5+
6+
const COMPONENT = 'structured-yson';
7+
8+
export default makeKeyset(COMPONENT, {ru, en});

src/StructuredYson/i18n/ru.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"action_collapse-all": "Свернуть все",
3+
"action_expand-all": "Развернуть все",
4+
"action_next": "Далее",
5+
"action_back": "Назад",
6+
"description_search": "Поиск...",
7+
"description_matched-rows": "Совпадающие строки",
8+
"context_items-count": [
9+
" {{count}} элемент ",
10+
" {{count}} элемента ",
11+
" {{count}} элементов ",
12+
" {{count}} элементов "
13+
]
14+
}

src/utils/flattenUnipika.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface UnipikaFlattenTreeItem {
1717
level: number;
1818
open?: BlockType;
1919
close?: BlockType;
20+
depth?: number;
2021

2122
path?: string; // if present the block is collapsible/expandable
2223

@@ -123,6 +124,10 @@ function flattenUnipikaJsonImpl(value: UnipikaValue, level = 0, ctx: FlatContext
123124

124125
if (isCollapsed) {
125126
handleCollapsedValue(value, level, ctx);
127+
// Get container size even for collapsed items
128+
if (isContainerType) {
129+
containerSize = value.$value.length;
130+
}
126131
} else {
127132
let jsonOpenLevel = NaN;
128133
let valueLevel = level;
@@ -155,6 +160,9 @@ function flattenUnipikaJsonImpl(value: UnipikaValue, level = 0, ctx: FlatContext
155160
}
156161

157162
if (isContainerType) {
163+
if (containerSize) {
164+
ctx.dst[itemPathIndex].depth = containerSize;
165+
}
158166
if (hasAttributes || containerSize) {
159167
handlePath(ctx, itemPathIndex); // handle 'array item'/'object field' path
160168
}
@@ -170,7 +178,7 @@ function handleJsonAttributes(
170178

171179
const isCollapsed = isPathCollapsed(ctx);
172180
if (isCollapsed) {
173-
handleCollapsedBlock('attributes', valueLevel, ctx);
181+
handleCollapsedBlock('attributes', valueLevel, ctx, $attributes.length);
174182
} else {
175183
const attrsLevelInfo = openBlock('attributes', valueLevel, ctx, $attributes.length);
176184
handlePath(ctx, ctx.dst.length - 1);
@@ -198,6 +206,8 @@ function handleValueBlock(
198206
const isValueCollapsed = isContainerType && isPathCollapsed(ctx);
199207
if (isValueCollapsed) {
200208
handleCollapsedValue(value, valueLevel, ctx);
209+
// Get container size even for collapsed $value
210+
containerSize = value.$type === 'map' || value.$type === 'list' ? value.$value.length : 0;
201211
} else {
202212
switch (value.$type) {
203213
case 'map':
@@ -263,6 +273,10 @@ function flattenUnipikaYsonImpl(value: UnipikaValue, level = 0, ctx: FlatContext
263273
}
264274
}
265275

276+
if (isContainerType && containerSize) {
277+
ctx.dst[itemPathIndex].depth = containerSize;
278+
}
279+
266280
if (
267281
(containerSize && !hasAttributes) ||
268282
(hasAttributes && (parentType === 'object' || parentType === 'attributes'))
@@ -274,11 +288,11 @@ function flattenUnipikaYsonImpl(value: UnipikaValue, level = 0, ctx: FlatContext
274288
function handleCollapsedValue(value: UnipikaValue, level: number, ctx: FlatContext) {
275289
switch (value.$type) {
276290
case 'map': {
277-
handleCollapsedBlock('object', level, ctx);
291+
handleCollapsedBlock('object', level, ctx, value.$value.length);
278292
break;
279293
}
280294
case 'list': {
281-
handleCollapsedBlock('array', level, ctx);
295+
handleCollapsedBlock('array', level, ctx, value.$value.length);
282296
break;
283297
}
284298
default: {
@@ -287,8 +301,8 @@ function handleCollapsedValue(value: UnipikaValue, level: number, ctx: FlatConte
287301
}
288302
}
289303

290-
function handleCollapsedBlock(type: BlockType, level: number, ctx: FlatContext) {
291-
openBlock(type, level, ctx, 0);
304+
function handleCollapsedBlock(type: BlockType, level: number, ctx: FlatContext, depth?: number) {
305+
openBlock(type, level, ctx, depth || 0);
292306
const item = ctx.dst[ctx.dst.length - 1];
293307
item.collapsed = true;
294308
handlePath(ctx, ctx.dst.length - 1);
@@ -326,8 +340,15 @@ function openBlock(type: BlockType, level: number, ctx: FlatContext, length: num
326340
// for attributes level should be upper than level of key or parent array
327341
if (last?.key && last.level === level) {
328342
last.open = type;
343+
if (length > 0) {
344+
last.depth = length;
345+
}
329346
} else {
330-
dst.push({level, open: type});
347+
const item: UnipikaFlattenTreeItem = {level, open: type};
348+
if (length > 0) {
349+
item.depth = length;
350+
}
351+
dst.push(item);
331352
}
332353
const levelInfo = {type, length, currentIndex: 0};
333354
ctx.levels.push(levelInfo);

0 commit comments

Comments
 (0)