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

Commit

Permalink
Fixing various problems with the hypercube builder guide steps
Browse files Browse the repository at this point in the history
  • Loading branch information
Helene Rigner committed Jan 24, 2019
1 parent 7c212d8 commit 044e3f3
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function App() {
<Guide ref={guideRef} />
<TopBar app={app} appLayout={appLayout} startGuide={() => guideRef.current.startGuideFunc()} />
<Model app={app} appLayout={appLayout} />
<Cubes app={app} />
<Cubes app={app} closeOnClickOutside={() => !guideRef.current.isGuideRunning()} />
</div>
{reloadSplasher}
</AppContext.Provider>
Expand Down
11 changes: 7 additions & 4 deletions src/components/cube-column-chooser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ function findAttribute(event, attrName) {
}

export default function CubeColumnChooser({
alignTo, arrowStyle, chooseColumn, selectableColumns,
alignTo, arrowStyle, chooseColumn, selectableColumns, closeOnClickOutside,
}) {
const [filter, setFilter] = useState('');
const inputRef = useRef(null);
const selfRef = useRef(null);

useClickOutside(selfRef, true, () => {
chooseColumn(null);
useClickOutside(selfRef, closeOnClickOutside(), () => {
if (closeOnClickOutside()) {
chooseColumn(null);
}
});

const filteredColumnsOptions = selectableColumns.filter(item => item.title.toLowerCase().indexOf(filter) >= 0);
Expand Down Expand Up @@ -75,8 +76,10 @@ CubeColumnChooser.propTypes = {
arrowStyle: PropTypes.string,
chooseColumn: PropTypes.func.isRequired,
selectableColumns: PropTypes.arrayOf(PropTypes.object).isRequired,
closeOnClickOutside: PropTypes.func,
};

CubeColumnChooser.defaultProps = {
arrowStyle: '',
closeOnClickOutside: () => true,
};
10 changes: 7 additions & 3 deletions src/components/cube.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import HypercubeTable from './hypercube-table';

import './cube.pcss';

export default function Cube({ app, tableData: { initialColumns } }) {
export default function Cube({ app, tableData: { initialColumns }, closeOnClickOutside }) {
const selectableColumns = useColumnOptions(app);
const [columns, setColumns] = useState(initialColumns);
const currentHeader = useRef(null);
Expand Down Expand Up @@ -55,8 +55,7 @@ export default function Cube({ app, tableData: { initialColumns } }) {
toggleAdd(event);
}

const popup = addOpen.current ? <CubeColumnChooser alignTo={currentHeader.current} selectableColumns={selectableColumns} chooseColumn={addColumn} /> : null;

const popup = addOpen.current ? <CubeColumnChooser alignTo={currentHeader.current} selectableColumns={selectableColumns} chooseColumn={addColumn} closeOnClickOutside={closeOnClickOutside} /> : null;

const measures = columns.filter(column => column.type === 'measure');
const dimensions = columns.filter(column => column.type === 'dimension' || column.type === 'field');
Expand All @@ -78,7 +77,12 @@ export default function Cube({ app, tableData: { initialColumns } }) {
);
}

Cube.defaultProps = {
closeOnClickOutside: () => true,
};

Cube.propTypes = {
app: PropTypes.object.isRequired,
tableData: PropTypes.object.isRequired,
closeOnClickOutside: PropTypes.func,
};
7 changes: 4 additions & 3 deletions src/components/cubes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import CubeColumnChooser from './cube-column-chooser';

import './cubes.pcss';

export function Cubes({ app }) {
export function Cubes({ app, closeOnClickOutside }) {
const [count, setCount] = useState(1);
const [cubeList, setCubeList] = useState([]);
const [, forceUpdate] = useState(null);
Expand Down Expand Up @@ -42,14 +42,14 @@ export function Cubes({ app }) {
forceUpdate();
}

const popup = addOpen.current ? <CubeColumnChooser arrowStyle="arrowRight" alignTo={addButtonRef.current} selectableColumns={selectableColumns} chooseColumn={column => addCube(column)} /> : null;
const popup = addOpen.current ? <CubeColumnChooser arrowStyle="arrowRight" alignTo={addButtonRef.current} selectableColumns={selectableColumns} chooseColumn={column => addCube(column)} closeOnClickOutside={closeOnClickOutside} /> : null;
const cubeDivs = cubeList.map(cube => (
<div key={cube.id} className="card">
<div className="top-bar">
<div className="title">HYPERCUBE</div>
<SVGInline {...closeButton} onClick={() => removeCube(cube.id)} />
</div>
<Cube app={app} tableData={cube} />
<Cube app={app} tableData={cube} closeOnClickOutside={closeOnClickOutside} />
</div>
));
return (
Expand All @@ -67,6 +67,7 @@ export function Cubes({ app }) {

Cubes.propTypes = {
app: PropTypes.object.isRequired,
closeOnClickOutside: PropTypes.func.isRequired,
};

export default Cubes;
16 changes: 6 additions & 10 deletions src/components/guide-steps.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ const steps = [
</div>
),
spotlightClicks: true,
disableOverlayClose: true,
hideFooter: true,
placement: 'left-end',
target: '.add-button',
title: 'Hypercube builder',
},
Expand All @@ -195,8 +194,6 @@ const steps = [
<p>Click on an entity to select it.</p>
</div>
),
disableOverlayClose: true,
hideFooter: true,
spotlightClicks: true,
target: '.cube-column-chooser',
title: 'Hypercube builder',
Expand All @@ -213,26 +210,25 @@ const steps = [
<p>Add another column by clicking the plus button.</p>
</div>
),
disableOverlayClose: true,
hideFooter: true,
spotlightClicks: true,
target: '.card',
hideBackButton: true,
target: '.card:last-child',
title: 'Hypercube builder',
},
{
step: 'selectAnotherEntity',
content: 'Click an entity to add it as a column in the cube.',
placement: 'left',
disableOverlayClose: true,
hideFooter: true,
spotlightClicks: true,
hideBackButton: true,
target: '.cube-column-chooser',
title: 'Hypercube builder',
},
{
step: 'cubeFinished',
content: 'More columns can be added to the cube. To close the cube, just click the button in the upper corner.',
target: '.card',
hideBackButton: true,
target: '.card:last-child',
title: 'Hypercube builder',
},
{
Expand Down
70 changes: 60 additions & 10 deletions src/components/guide.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,23 @@ const Guide = forwardRef((props, ref) => {
setRunGuide(true);
}
},
isGuideRunning() {
return runGuide;
},
}));

const getNbrOfColumnsInCube = () => {
let nbrOfColumns = 0;
const table = document.getElementsByClassName('hypercube-table');
if (table.length > 0) {
const virtTable = table[table.length - 1].getElementsByClassName('ReactVirtualized__Table');
if (virtTable.length > 0) {
nbrOfColumns = virtTable[0].getAttribute('aria-colcount');
}
}
return nbrOfColumns;
};

const setStep = (stepName) => {
setRunGuide(false);
setStepIndex(steps.findIndex(s => s.step === stepName));
Expand All @@ -49,14 +64,7 @@ const Guide = forwardRef((props, ref) => {
setStep('selectEntity');
} else if (parentElemName === 'expression' || parentElemName === 'expression-list') {
// a click on an expression in the hypercube builder.
let nbrOfColumns = 0;
const table = document.getElementsByClassName('hypercube-table');
if (table.length > 0) {
const virtTable = table[0].getElementsByClassName('ReactVirtualized__Table');
if (virtTable.length > 0) {
nbrOfColumns = virtTable[0].getAttribute('aria-colcount');
}
}
const nbrOfColumns = getNbrOfColumnsInCube();
if (nbrOfColumns > 0) {
setStep('cubeFinished');
} else {
Expand All @@ -75,19 +83,61 @@ const Guide = forwardRef((props, ref) => {
document.removeEventListener('mouseup', onClick);
};

const readyToProceed = (newStepIndex) => {
if (newStepIndex < steps.length) {
const stepName = steps[newStepIndex].step;
if (stepName === 'addAnotherColumn') {
// we need to have a hypercube with a column in order for the step to be valid.
const nbrOfColumns = getNbrOfColumnsInCube();
if (nbrOfColumns <= 0) {
return false;
}
} else if (stepName === 'selectAnotherEntity') {
const overlay = document.getElementsByClassName('cube-column-chooser');
if (!overlay.length > 0) {
return false;
}
} else if (stepName === 'cubeFinished') {
const nbrOfColumns = getNbrOfColumnsInCube();
if (nbrOfColumns > 0) {
return false;
}
}
}
// we are ready to proceed with this step.
return true;
};

const handleJoyrideCallback = (data) => {
const {
action, index, type, status,
} = data;
if ([EVENTS.TOUR_START].includes(type)) {
document.addEventListener('mouseup', onClick);
} else if ([ACTIONS.START].includes(action) && index === 0) {
// if the guide is restarted there will be no EVENTS.TOUR_START, the EventListener must
// be added on ACTION.START and step 0.
document.addEventListener('mouseup', onClick);
} else if ([ACTIONS.CLOSE].includes(action) || [STATUS.FINISHED, STATUS.SKIPPED].includes(status)) {
if (runGuide) {
endGuide();
}
} else if ([EVENTS.STEP_AFTER, EVENTS.TARGET_NOT_FOUND].includes(type)) {
} else if ([EVENTS.STEP_AFTER].includes(type)) {
const newStepIndex = index + (action === ACTIONS.PREV ? -1 : 1);
// Update state to advance the guide
if (action !== ACTIONS.PREV && !readyToProceed(newStepIndex)) {
// we are not ready to proceed to the next step. Reset the current step.
// The stop/start of the guide is needed to reset the Joyride events, or it will
// be somewhere in between steps, statewise.
setRunGuide(false);
setStepIndex(index);
setTimeout(() => setRunGuide(true), 100);
} else {
// Update state to advance the guide
setStepIndex(newStepIndex);
}
} else if ([EVENTS.TARGET_NOT_FOUND].includes(type)) {
// The target could not be found. Go to previous step.
const newStepIndex = index - 1;
setStepIndex(newStepIndex);
}
};
Expand Down

0 comments on commit 044e3f3

Please sign in to comment.