proje-react-panel 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/components/list/CellField.test.d.ts +1 -0
- package/dist/decorators/list/Cell.d.ts +9 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/package.json +1 -1
- package/src/__tests__/components/list/CellField.test.tsx +67 -0
- package/src/components/list/CellField.tsx +24 -0
- package/src/components/list/Datagrid.tsx +11 -2
- package/src/components/list/cells/ImageCell.tsx +4 -1
- package/src/decorators/list/Cell.ts +9 -0
- package/src/styles/list.scss +19 -1
package/package.json
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import { TextDecoder, TextEncoder } from 'util';
|
|
5
|
+
// react-router reads TextEncoder at import time and jsdom has none — set it up before the
|
|
6
|
+
// imports below pull the router in.
|
|
7
|
+
Object.assign(globalThis, { TextEncoder, TextDecoder });
|
|
8
|
+
|
|
9
|
+
import 'reflect-metadata';
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { describe, expect, it } from '@jest/globals';
|
|
12
|
+
import { render } from '@testing-library/react';
|
|
13
|
+
import { MemoryRouter } from 'react-router';
|
|
14
|
+
import { CellField } from '../../../components/list/CellField';
|
|
15
|
+
import { CellConfiguration } from '../../../decorators/list/Cell';
|
|
16
|
+
|
|
17
|
+
// Tablo `table-layout: fixed` kullaniyor: kolon genisligi sabit ve tasan metin
|
|
18
|
+
// ellipsis'e dusuyor. Kesilen degeri okumanin tek yolu hucrenin tooltip'i.
|
|
19
|
+
const cell = (over: Partial<CellConfiguration> = {}): CellConfiguration => ({
|
|
20
|
+
name: 'description',
|
|
21
|
+
type: 'string',
|
|
22
|
+
...over,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const titleOf = (configuration: CellConfiguration, item: Record<string, unknown>) =>
|
|
26
|
+
render(
|
|
27
|
+
// Link hucresi react-router'in <Link>'ini basiyor, o da router context'i istiyor.
|
|
28
|
+
<MemoryRouter>
|
|
29
|
+
<table>
|
|
30
|
+
<tbody>
|
|
31
|
+
<tr>
|
|
32
|
+
<CellField configuration={configuration} item={item} />
|
|
33
|
+
</tr>
|
|
34
|
+
</tbody>
|
|
35
|
+
</table>
|
|
36
|
+
</MemoryRouter>
|
|
37
|
+
)
|
|
38
|
+
.container.querySelector('td')
|
|
39
|
+
?.getAttribute('title');
|
|
40
|
+
|
|
41
|
+
describe("CellField — hucre tooltip'u", () => {
|
|
42
|
+
it('metin hucresinde tam degeri title olarak verir', () => {
|
|
43
|
+
const uzun = 'a'.repeat(400);
|
|
44
|
+
|
|
45
|
+
expect(titleOf(cell(), { description: uzun })).toBe(uzun);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('metin olmayan degerleri yaziya cevirir', () => {
|
|
49
|
+
expect(titleOf(cell({ type: 'number' }), { description: 42 })).toBe('42');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Bu hucreler metin degil element basiyor; ham url'i tooltip yapmak
|
|
53
|
+
// kullaniciya bir sey anlatmiyor, yalnizca gurultu olurdu.
|
|
54
|
+
it.each(['image', 'download', 'link'] as const)('%s hucresinde title vermez', type => {
|
|
55
|
+
expect(titleOf(cell({ type, name: 'thumbnailUrl' }), { thumbnailUrl: '/uploads/x.png' })).toBe(
|
|
56
|
+
null
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it.each([
|
|
61
|
+
['null', null],
|
|
62
|
+
['undefined', undefined],
|
|
63
|
+
['nesne', { a: 1 }],
|
|
64
|
+
])('%s degerde title vermez', (_ad, value) => {
|
|
65
|
+
expect(titleOf(cell(), { description: value })).toBe(null);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -48,6 +48,7 @@ export function CellField<T extends AnyClass>({
|
|
|
48
48
|
return (
|
|
49
49
|
<td
|
|
50
50
|
key={configuration.name}
|
|
51
|
+
title={cellTitle(configuration, item)}
|
|
51
52
|
style={{
|
|
52
53
|
minWidth,
|
|
53
54
|
width,
|
|
@@ -57,3 +58,26 @@ export function CellField<T extends AnyClass>({
|
|
|
57
58
|
</td>
|
|
58
59
|
);
|
|
59
60
|
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sabit kolon genisliginde uzun metin ellipsis'e dusuyor ve tam degeri okumanin
|
|
64
|
+
* tek yolu hover kaliyor. Gorsel/indirme/link hucrelerinde metin degil element
|
|
65
|
+
* basildigi icin ham degeri tooltip yapmak yalnizca gurultu olurdu.
|
|
66
|
+
*/
|
|
67
|
+
function cellTitle<T extends AnyClass>(
|
|
68
|
+
configuration: CellConfiguration,
|
|
69
|
+
item: T
|
|
70
|
+
): string | undefined {
|
|
71
|
+
if (
|
|
72
|
+
configuration.type === 'image' ||
|
|
73
|
+
configuration.type === 'download' ||
|
|
74
|
+
configuration.type === 'link'
|
|
75
|
+
) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const value = item[configuration.name];
|
|
79
|
+
if (value === null || value === undefined || typeof value === 'object') {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
return String(value);
|
|
83
|
+
}
|
|
@@ -11,6 +11,13 @@ import { CellField } from './CellField';
|
|
|
11
11
|
import { CellConfiguration } from '../../decorators/list/Cell';
|
|
12
12
|
import { useAppStore } from '../../store/store';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Otomatik duzende bu deger yalnizca bir ipucuydu; tarayici "Actions" etiketi
|
|
16
|
+
* sigsin diye kolonu kendisi buyutuyordu. `table-layout: fixed` ile genislik
|
|
17
|
+
* birebir uygulaniyor, dolayisiyla eski 30px etiketi kirpiyor.
|
|
18
|
+
*/
|
|
19
|
+
const ACTIONS_COLUMN_WIDTH = '120px';
|
|
20
|
+
|
|
14
21
|
interface DatagridProps<T extends AnyClass> {
|
|
15
22
|
data: T[];
|
|
16
23
|
listPageMeta: ListPageMeta<T>;
|
|
@@ -49,7 +56,9 @@ export function Datagrid<T extends AnyClass>({
|
|
|
49
56
|
{(listActions?.details ||
|
|
50
57
|
listActions?.edit ||
|
|
51
58
|
listActions?.delete ||
|
|
52
|
-
listActions?.customActions?.length) &&
|
|
59
|
+
listActions?.customActions?.length) && (
|
|
60
|
+
<th style={{ width: ACTIONS_COLUMN_WIDTH }}>Actions</th>
|
|
61
|
+
)}
|
|
53
62
|
</tr>
|
|
54
63
|
</thead>
|
|
55
64
|
<tbody>
|
|
@@ -80,7 +89,7 @@ export function Datagrid<T extends AnyClass>({
|
|
|
80
89
|
);
|
|
81
90
|
})}
|
|
82
91
|
{(listCells?.details || listCells?.edit || listCells?.delete) && (
|
|
83
|
-
<td style={{ width:
|
|
92
|
+
<td className="util-cell-actions-cell" style={{ width: ACTIONS_COLUMN_WIDTH }}>
|
|
84
93
|
<div className="util-cell-actions">
|
|
85
94
|
<p className="util-cell-actions-label">
|
|
86
95
|
Actions <DownArrowIcon className="icon icon-down" />
|
|
@@ -14,11 +14,14 @@ export function ImageCell({ item, configuration }: ImageCellProps) {
|
|
|
14
14
|
if (!value) return <>-</>;
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
+
// maxWidth sart: sabit tablo duzeninde kolon 100px'ten dar kalabiliyor ve
|
|
18
|
+
// hucre tasmayi kirptigi icin gorsel sessizce yarim gorunurdu. Kucultmek
|
|
19
|
+
// kirpmaktan iyi; objectFit: contain oranı koruyor.
|
|
17
20
|
<img
|
|
18
21
|
width={100}
|
|
19
22
|
height={100}
|
|
20
23
|
src={imageConfiguration.baseUrl + value}
|
|
21
|
-
style={{ objectFit: 'contain' }}
|
|
24
|
+
style={{ objectFit: 'contain', maxWidth: '100%' }}
|
|
22
25
|
alt=""
|
|
23
26
|
/>
|
|
24
27
|
);
|
|
@@ -23,7 +23,16 @@ export interface CellOptions {
|
|
|
23
23
|
placeHolder?: string;
|
|
24
24
|
filter?: Filter | StaticSelectFilter;
|
|
25
25
|
style?: {
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated Tablo `table-layout: fixed` kullaniyor; sabit duzende hucre
|
|
28
|
+
* `min-width`'i kolon genisligini etkilemiyor (CSS 2.1 17.5.2.1). Bunun
|
|
29
|
+
* yerine `width` verin.
|
|
30
|
+
*/
|
|
26
31
|
minWidth?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Kolon genisligi. Sabit duzende birebir uygulanir; yuzde vermek tabloyu
|
|
34
|
+
* konteynere sigdirir, px vermek toplam konteyneri asarsa yatay scroll acar.
|
|
35
|
+
*/
|
|
27
36
|
width?: string;
|
|
28
37
|
};
|
|
29
38
|
}
|
package/src/styles/list.scss
CHANGED
|
@@ -86,8 +86,17 @@ $datagrid-height: calc(100vh - #{$header-height} - #{$footer-height});
|
|
|
86
86
|
@include custom-scrollbar;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// `width` sart: `table-layout: fixed`, genislik `auto` kaldigi surece devreye
|
|
90
|
+
// girmiyor (CSS 2.1 17.5.2.1) ve tarayici otomatik duzene doner. Burada eskiden
|
|
91
|
+
// sadece `min-width: 100%` vardi, yani sabit duzen hic calismiyordu: nowrap
|
|
92
|
+
// hucreler kolonu icerik kadar sisiriyor, tablo konteyneri asiyor ve uzun
|
|
93
|
+
// metin tasiyan her liste yatay scroll aciyordu.
|
|
94
|
+
//
|
|
95
|
+
// Kolonlarina px genislik veren tuketiciler genis tabloyu kaybetmiyor: sabit
|
|
96
|
+
// duzende kullanilan tablo genisligi, belirtilen kolon genisliklerinin toplami
|
|
97
|
+
// ile bu %100 degerinin buyugudur.
|
|
89
98
|
.datagrid-table {
|
|
90
|
-
|
|
99
|
+
width: 100%;
|
|
91
100
|
table-layout: fixed;
|
|
92
101
|
border-collapse: collapse;
|
|
93
102
|
position: relative;
|
|
@@ -97,10 +106,19 @@ $datagrid-height: calc(100vh - #{$header-height} - #{$footer-height});
|
|
|
97
106
|
padding: 12px 16px;
|
|
98
107
|
text-align: left;
|
|
99
108
|
border-bottom: 1px solid var(--prp-border-primary);
|
|
109
|
+
// `text-overflow` yalnizca tasma kirpildiginda is goruyor; `overflow`
|
|
110
|
+
// olmadan ellipsis hicbir zaman cizilmiyordu.
|
|
111
|
+
overflow: hidden;
|
|
100
112
|
text-overflow: ellipsis;
|
|
101
113
|
white-space: nowrap;
|
|
102
114
|
}
|
|
103
115
|
|
|
116
|
+
// Actions hucresindeki acilir liste `position: absolute`; kirpilirsa menu
|
|
117
|
+
// gorunmez oluyor. Kirpma sadece metin kolonlari icin gerekli.
|
|
118
|
+
.util-cell-actions-cell {
|
|
119
|
+
overflow: visible;
|
|
120
|
+
}
|
|
121
|
+
|
|
104
122
|
th {
|
|
105
123
|
color: var(--prp-text-primary);
|
|
106
124
|
background-color: var(--prp-bg-tertiary);
|