Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Add possibility to remove a column in the hybercube builder (#261)
Browse files Browse the repository at this point in the history
* adding possibility to remove hypercube column

* closing cube if empty

* Adding red color when hovering over trash bin

* fix lint errors
  • Loading branch information
Helene Rignér committed May 16, 2019
1 parent 123d13b commit 8a4f3c1
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 15 deletions.
21 changes: 17 additions & 4 deletions src/components/cube.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import './cube.pcss';
// The component needs to be wrapped in `forwardRef` to give access to the
// ref object assigned using the `ref` prop.
const Cube = forwardRef(({
app, tableData: { initialColumns }, closeOnClickOutside, id, isLocalStorage,
app, tableData: { initialColumns }, closeOnClickOutside, id, isLocalStorage, closeCube,
}, ref) => {
const selectableColumns = useColumnOptions(app);
const [columns, setColumns] = useState(initialColumns);
Expand Down Expand Up @@ -106,8 +106,14 @@ const Cube = forwardRef(({
}

function onHeaderClick({ columnData, event }) {
columnToReplace.current = columnData;
toggleAdd(event);
if (event.target && (event.target.tagName === 'path' || event.target.tagName === 'svg')) {
// remove column
setColumns(columns.filter(c => c !== columnData));
} else {
// add column
columnToReplace.current = columnData;
toggleAdd(event);
}
}

function createProperties(dimensions, measures) {
Expand Down Expand Up @@ -150,14 +156,19 @@ const Cube = forwardRef(({
if (isEmpty && addOpen.current) {
return popup;
}

if (isEmpty && closeCube) {
closeCube(id);
}

return (
<div className={`cube ${isEmpty ? 'empty' : ''}`}>
{popup}
<div className="table-wrapper">
<div role="button" title="Add another column" tabIndex="-1" className={`column-add-button ${isEmpty ? 'empty' : ''}`} onClick={e => toggleAdd(e)}>
<span className="text">+</span>
</div>
{!isEmpty ? <HypercubeTable model={model} onHeaderClick={data => onHeaderClick(data)} dimensions={dimensions} measures={measures} height={28 * 8} maxWidth={100 * 8} /> : null}
{!isEmpty ? <HypercubeTable model={model} onHeaderClick={data => onHeaderClick(data)} dimensions={dimensions} measures={measures} height={28 * 8} /> : null}
</div>
</div>
);
Expand All @@ -167,6 +178,7 @@ export default Cube;
Cube.defaultProps = {
closeOnClickOutside: () => true,
isLocalStorage: false,
closeCube: undefined,
};

Cube.propTypes = {
Expand All @@ -175,4 +187,5 @@ Cube.propTypes = {
closeOnClickOutside: PropTypes.func,
id: PropTypes.number.isRequired,
isLocalStorage: PropTypes.bool,
closeCube: PropTypes.func,
};
4 changes: 0 additions & 4 deletions src/components/cube.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,5 @@
.hypercube-table {
flex: 1 1 auto;
}

.column-add-button.empty {
border-right: 1px solid #d9d9d9;
}
}
}
2 changes: 1 addition & 1 deletion src/components/cubes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function Cubes({ app, closeOnClickOutside, isLocalStorage }) {
<SVGInline className="copy" svg={copy} onClick={() => copyToClipboard(cube.id)} title="Copy hypercube def to clipboard" />
<SVGInline {...closeButton} onClick={() => removeCube(cube.id)} title="Close cube" />
</div>
<Cube ref={refs.current[cube.id]} app={app} tableData={cube} closeOnClickOutside={closeOnClickOutside} id={cube.id} isLocalStorage={isLocalStorage} />
<Cube ref={refs.current[cube.id]} app={app} tableData={cube} closeOnClickOutside={closeOnClickOutside} id={cube.id} isLocalStorage={isLocalStorage} closeCube={removeCube} />
</div>
));
return (
Expand Down
36 changes: 30 additions & 6 deletions src/components/hypercube-table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,34 @@ headerRowRenderer.propTypes = {
style: PropTypes.object.isRequired,
};

function columnHeaderRenderer({ label }) {
return (
<div className="column-header">
<span className="ReactVirtualized__Table__headerTruncatedText" key="label">
{label}
</span>
<span>
<svg title="remove column" width={16} height={16} viewBox="0 0 24 24">
<path d="M21 6h-5V4.33A2.42 2.42 0 0 0 13.5 2h-3A2.42 2.42 0 0 0 8 4.33V6H3a1 1 0 0 0 0 2h1v11a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8h1a1 1 0 0 0 0-2zM10 4.33c0-.16.21-.33.5-.33h3c.29 0 .5.17.5.33V6h-4zM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8h12z" />
<path d="M9 17a1 1 0 0 0 1-1v-4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1z" />
<path d="M15 17a1 1 0 0 0 1-1v-4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1z" />
</svg>
</span>
</div>
);
}

columnHeaderRenderer.propTypes = {
label: PropTypes.any.isRequired,
};

function noRowsRenderer() {
return <div className="no-values">No values</div>;
}

const GLYPH_SIZE = 8; // Aproximate max width in pixels of a glyph
const MAX_ROW_GLYTH_LENGTH = 40; // If the column is more than 40 glyphs wide then limit it
const PADDING = 8; // The total padding added around table cells
const PADDING = 20; // The total padding added around table cells
const BORDER = 1; // The size added by the border between cells
const SCROLLBAR_PADDING = 17; // React-virtualized adds and subtracts this value to accomodate for the space stolen by the scroll bar

Expand Down Expand Up @@ -149,35 +170,37 @@ export default function HypercubeTable({
headerRowRenderer={headerRowRenderer}
onHeaderClick={data => onHeaderClick(data)}
headerRowHeight={24}
width={calculatedWidth < maxWidth ? calculatedWidth : maxWidth}
width={(calculatedWidth < maxWidth || maxWidth === 0) ? calculatedWidth : maxWidth}
height={height}
defPath="/qHyperCubeDef"
>
{dimensions.map((dim, dimensionIndex) => (
<Column
minWidth={80}
label={dim.title}
dataKey={dim.title}
columnData={dim}
key={dim.title}
width={getDimensionWidth(layout, dimensionIndex, dim.title)}
flexGrow={1}
flexShrink={1}
cellDataGetter={cellGetterForIndex(dimensionIndex)}
cellRenderer={cellRendererForIndex(dimensionIndex)}
headerRenderer={columnHeaderRenderer}
/>
))
}
{measures.map((measure, measureIndex) => (
<Column
width={getMeasureWidth(layout, measureIndex, measure.title)}
minWidth={80}
label={measure.title}
dataKey={measure.title}
columnData={measure}
key="measure"
key={measure.title}
flexGrow={1}
flexShrink={1}
cellDataGetter={cellGetterForIndex(dimensions.length + measureIndex)}
cellRenderer={cellRendererForIndex(dimensions.length + measureIndex)}
headerRenderer={columnHeaderRenderer}
/>
))
}
Expand All @@ -193,12 +216,13 @@ HypercubeTable.propTypes = {
measures: PropTypes.arrayOf(PropTypes.object),
dimensions: PropTypes.arrayOf(PropTypes.object),
model: PropTypes.object,
maxWidth: PropTypes.number.isRequired,
maxWidth: PropTypes.number,
height: PropTypes.number.isRequired,
};
HypercubeTable.defaultProps = {
onHeaderClick: () => {},
measures: [],
dimensions: [],
model: null,
maxWidth: 0,
};
20 changes: 20 additions & 0 deletions src/components/hypercube-table.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@
outline: none;
}

svg {
cursor: pointer;
display: none;
fill: #4d4d4d;
float: right;

&:hover {
fill: #ff3232;
}
}

.column-header {
&:hover {
svg {
animation: fade 0.4s ease-in;
display: block;
}
}
}

.ReactVirtualized__Table__rowColumn {
background-color: white;
border-bottom: 1px solid #d9d9d9;
Expand Down

0 comments on commit 8a4f3c1

Please sign in to comment.