[attribute-behavior] Add alphabetical and rev-alphabetical sorting (#10546)
* Add alphabetical and rev-alphabetical sorting This is just an initial convenient way to jump to the top or bottom of the list. Next we will add a sorting which groups rows together if their behavior pattern is the same. * Add sorting to group the rows by behavior pattern **what is the change?:** Another sorting option - if the content of a row is the same, it takes those rows and groups them together. **why make this change?:** This will help us find groups of attributes that behave similarly. **test plan:** manual testing * rename variable to be more clear
Flarnie Marchan committed
Aug 25, 2017 at 18:03 UTC
c0a41196e68dea0128c887bef8f125925d4777d2
1 file changed
+128
-49
fixtures/attribute-behavior/src/App.js
+128
-49
@@ -2376,6 +2376,19 @@ const attributes = [
2376
{name: 'zoomAndPan', read: getSVGAttribute('zoomAndPan'), tagName: 'svg'},
2377
];
2378
2379
+const ALPHABETICAL = 'alphabetical';
2380
+const REV_ALPHABETICAL = 'reverse_alphabetical';
2381
+const GROUPED_BY_ROW_PATTERN = 'grouped_by_row_pattern';
2382
+
2383
+const attributesSorted = {
2384
+ [ALPHABETICAL]: attributes
2385
+ .slice(0)
2386
+ .sort((attr1, attr2) => (attr1.name < attr2.name ? -1 : 1)),
2387
+ [REV_ALPHABETICAL]: attributes
2388
+ .slice(0)
2389
+ .sort((attr1, attr2) => (attr1.name < attr2.name ? 1 : -1)),
2390
+};
2391
+
2392
let _didWarn = false;
2393
function warn(str) {
2394
_didWarn = true;
@@ -2473,45 +2486,42 @@ function getRenderedAttributeValues(attribute, type) {
2486
}
2487
2488
const table = new Map();
2489
+const groupByRowPattern = new Map();
2490
2491
// Disable error overlay while test each attribute
2492
uninjectErrorOverlay();
2493
for (let attribute of attributes) {
2494
const row = new Map();
2495
+ let rowHash = '';
2496
for (let type of types) {
2497
const result = getRenderedAttributeValues(attribute, type);
2498
row.set(type.name, result);
2499
+ rowHash +=
2500
+ getResultDisplayString(result.react15.result) +
2501
+ getResultDisplayString(result.react16.result);
2502
}
2503
table.set(attribute, row);
2504
+ if (!groupByRowPattern.get(rowHash)) {
2505
+ groupByRowPattern.set(rowHash, []);
2506
+ }
2507
+ const updatedAttributesArray = groupByRowPattern.get(rowHash);
2508
+ updatedAttributesArray.push(attribute);
2509
+ groupByRowPattern.set(rowHash, updatedAttributesArray);
2510
}
2487
-// Renable error overlay
2488
-injectErrorOverlay();
2511
2490
-const successColor = 'white';
2491
-const warnColor = 'yellow';
2492
-const errorColor = 'red';
2512
+let attributesSortedByRowPattern = [];
2513
+groupByRowPattern.forEach(arrayOfAttributes => {
2514
+ attributesSortedByRowPattern = attributesSortedByRowPattern.concat(
2515
+ arrayOfAttributes
2516
+ );
2517
+});
2518
2494
-function RendererResult({version, result, defaultValue, didWarn, didError}) {
2495
- let backgroundColor;
2496
- if (didError) {
2497
- backgroundColor = errorColor;
2498
- } else if (didWarn) {
2499
- backgroundColor = warnColor;
2500
- } else if (result !== defaultValue) {
2501
- backgroundColor = 'cyan';
2502
- } else {
2503
- backgroundColor = successColor;
2504
- }
2519
+attributesSorted[GROUPED_BY_ROW_PATTERN] = attributesSortedByRowPattern;
2520
2506
- let style = {
2507
- display: 'flex',
2508
- alignItems: 'center',
2509
- position: 'absolute',
2510
- height: '100%',
2511
- width: '100%',
2512
- backgroundColor,
2513
- };
2521
+// Renable error overlay
2522
+injectErrorOverlay();
2523
2524
+function getResultDisplayString(result) {
2525
let displayResult;
2526
switch (typeof result) {
2527
case 'undefined':
@@ -2546,8 +2556,35 @@ function RendererResult({version, result, defaultValue, didWarn, didError}) {
2556
default:
2557
throw new Error('Switch statement should be exhaustive.');
2558
}
2559
+ return displayResult;
2560
+}
2561
2550
- return <div css={style}>{displayResult}</div>;
2562
+const successColor = 'white';
2563
+const warnColor = 'yellow';
2564
+const errorColor = 'red';
2565
+
2566
+function RendererResult({version, result, defaultValue, didWarn, didError}) {
2567
+ let backgroundColor;
2568
+ if (didError) {
2569
+ backgroundColor = errorColor;
2570
+ } else if (didWarn) {
2571
+ backgroundColor = warnColor;
2572
+ } else if (result !== defaultValue) {
2573
+ backgroundColor = 'cyan';
2574
+ } else {
2575
+ backgroundColor = successColor;
2576
+ }
2577
+
2578
+ let style = {
2579
+ display: 'flex',
2580
+ alignItems: 'center',
2581
+ position: 'absolute',
2582
+ height: '100%',
2583
+ width: '100%',
2584
+ backgroundColor,
2585
+ };
2586
+
2587
+ return <div css={style}>{getResultDisplayString(result)}</div>;
2588
}
2589
2590
function ResultPopover(props) {
@@ -2687,9 +2724,8 @@ function RowHeader({children}) {
2724
}
2725
2726
function CellContent(props) {
2690
- const {columnIndex, rowIndex} = props;
2691
-
2692
- const attribute = attributes[rowIndex - 1];
2727
+ const {columnIndex, rowIndex, attributesInSortedOrder} = props;
2728
+ const attribute = attributesInSortedOrder[rowIndex - 1];
2729
const type = types[columnIndex - 1];
2730
2731
if (columnIndex === 0) {
@@ -2709,30 +2745,73 @@ function CellContent(props) {
2745
return <Result {...result} />;
2746
}
2747
2712
-function cellRenderer(props) {
2713
- return <div style={props.style}><CellContent {...props} /></div>;
2714
-}
2715
-
2748
class App extends Component {
2749
+ constructor() {
2750
+ super();
2751
+ this.state = {sortOrder: REV_ALPHABETICAL};
2752
+ this._renderCell = this.renderCell.bind(this);
2753
+ this._onUpdateSort = this.onUpdateSort.bind(this);
2754
+ }
2755
+
2756
+ renderCell(props) {
2757
+ return (
2758
+ <div style={props.style}>
2759
+ <CellContent
2760
+ attributesInSortedOrder={attributesSorted[this.state.sortOrder]}
2761
+ {...props}
2762
+ />
2763
+ </div>
2764
+ );
2765
+ }
2766
+
2767
+ onUpdateSort(e) {
2768
+ this.setState({sortOrder: e.target.value});
2769
+ this.grid.forceUpdateGrids();
2770
+ }
2771
+
2772
render() {
2773
return (
2719
- <AutoSizer disableHeight={true}>
2720
- {({width}) => (
2721
- <MultiGrid
2722
- cellRenderer={cellRenderer}
2723
- columnWidth={200}
2724
- columnCount={1 + types.length}
2725
- fixedColumnCount={1}
2726
- enableFixedColumnScroll={true}
2727
- enableFixedRowScroll={true}
2728
- height={1200}
2729
- rowHeight={40}
2730
- rowCount={attributes.length + 1}
2731
- fixedRowCount={1}
2732
- width={width}
2733
- />
2734
- )}
2735
- </AutoSizer>
2774
+ <div>
2775
+ <div>
2776
+ <select onChange={this._onUpdateSort}>
2777
+ <option
2778
+ selected={this.state.sortOrder === ALPHABETICAL}
2779
+ value={ALPHABETICAL}>
2780
+ alphabetical
2781
+ </option>
2782
+ <option
2783
+ selected={this.state.sortOrder === REV_ALPHABETICAL}
2784
+ value={REV_ALPHABETICAL}>
2785
+ reverse alphabetical
2786
+ </option>
2787
+ <option
2788
+ selected={this.state.sortOrder === GROUPED_BY_ROW_PATTERN}
2789
+ value={GROUPED_BY_ROW_PATTERN}>
2790
+ grouped by row pattern :)
2791
+ </option>
2792
+ </select>
2793
+ </div>
2794
+ <AutoSizer disableHeight={true}>
2795
+ {({width}) => (
2796
+ <MultiGrid
2797
+ ref={input => {
2798
+ this.grid = input;
2799
+ }}
2800
+ cellRenderer={this._renderCell}
2801
+ columnWidth={200}
2802
+ columnCount={1 + types.length}
2803
+ fixedColumnCount={1}
2804
+ enableFixedColumnScroll={true}
2805
+ enableFixedRowScroll={true}
2806
+ height={1200}
2807
+ rowHeight={40}
2808
+ rowCount={attributes.length + 1}
2809
+ fixedRowCount={1}
2810
+ width={width}
2811
+ />
2812
+ )}
2813
+ </AutoSizer>
2814
+ </div>
2815
);
2816
}
2817
}