This repository has been archived by the owner on Nov 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
Adding a guide that is run the first time a user enters catwalk. #142
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
b68c0fe
Adding the guide steps implementation
c269dde
Merge branch 'master' into tutorial
0e4f999
Merge branch 'master' into tutorial
f661c7e
Updating baseline img for grid e2e
2df0f86
Fixing review comments
fc431de
Review comments, language wise
e76ff52
step content update
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
import React from 'react'; | ||
|
||
const steps = [ | ||
{ | ||
content: ( | ||
<div> | ||
<h2>Welcome to catwalk!</h2> | ||
<p> | ||
catwalk lets you explore your data model to gain | ||
insights about fields, associations and how interactions | ||
with the data impacts the model. | ||
</p> | ||
<p> | ||
Follow the guide to discover the power of catwalk. | ||
</p> | ||
</div> | ||
), | ||
placement: 'center', | ||
target: 'body', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
<h2>Welcome to catwalk!</h2> | ||
<p>The URL to catwalk is</p> | ||
<span className="breakword"> | ||
{window.location.href} | ||
</span> | ||
<p> | ||
where | ||
{' '} | ||
<code>engine_url</code> | ||
{' '} | ||
points to the app containing the data model. Change this to explore another data model. | ||
</p> | ||
</div> | ||
), | ||
placement: 'center', | ||
target: 'body', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
<p> | ||
The highlighted area represents a table in the data model. | ||
</p> | ||
<p>On the top we can see the table name, together with the number of rows in the table.</p> | ||
</div> | ||
), | ||
placement: 'right-start', | ||
target: '.column', | ||
title: 'Table', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
<p> | ||
Fields, the data-carrying entities in the data model, are represented with a box like this. | ||
</p> | ||
<p> | ||
The field name and the number of field values are visible. | ||
</p> | ||
<p> | ||
The number of field values are presented in the form of 6 of 6(5) | ||
which means that 5 out of 6 values are present in this table. If for example three field values are | ||
selected, the numbers would change to 3 of 6(5). | ||
</p> | ||
</div> | ||
), | ||
placement: 'right', | ||
target: '.vertcell.keycell', | ||
title: 'Field', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
A field can have different border colors where the color represents different type of keys. | ||
<div className="guide-step"> | ||
<div className="perfect" /> | ||
<p>Perfect key.</p> | ||
<p> | ||
Indicates that every row contains a key value, and that all of these key values are unique. | ||
The field's subset ratio is 100 percent. | ||
</p> | ||
</div> | ||
<div className="guide-step"> | ||
<div className="primary" /> | ||
<p>Primary key</p> | ||
<br /> | ||
<p> | ||
Indicates that all key values are unique, but not every row contains a key value or | ||
the field's subset ratio is less than 100 percent. | ||
</p> | ||
</div> | ||
<div className="guide-step"> | ||
<div className="default" /> | ||
<p>Key</p> | ||
<br /> | ||
<p> | ||
Indicates that the key is not unique. Usually seen in fact tables, where the same dimension | ||
value may be associated with many different facts. | ||
</p> | ||
</div> | ||
</div> | ||
), | ||
target: '.table-field', | ||
title: 'Field', | ||
placement: 'right', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
<p> | ||
The fields are clickable. When clicking on a field, it unfolds and displays the field values with the possibility to make | ||
selections. Selections can be helpful when trying to figure out the data model, and to find errors in the data model. | ||
</p> | ||
<p> | ||
Go ahead, click the field and make a selection! | ||
</p> | ||
</div> | ||
), | ||
spotlightClicks: true, | ||
placement: 'right', | ||
target: '.vertcell.keycell', | ||
title: 'Field', | ||
}, | ||
{ | ||
step: 'selections', | ||
content: ( | ||
<div> | ||
<p> | ||
The selections made can be seen in the top bar. | ||
</p> | ||
<p> | ||
Selections in any single field can be removed, or all selections in the app can be removed by clicking the X to the left. | ||
</p> | ||
</div> | ||
), | ||
spotlightClicks: true, | ||
placement: 'bottom', | ||
target: '.selection-field', | ||
title: 'Selections', | ||
}, | ||
{ | ||
content: 'This shows the association between two fields, with basic frequency information on each end of the association line (*, 1 or 0/1).', | ||
target: '.association-to-right-b', | ||
title: 'Associations', | ||
}, | ||
{ | ||
step: 'openHypercubeBuilder', | ||
content: ( | ||
<div> | ||
<p> | ||
Here you can build your own hypercube with the fields, dimensions and | ||
measure in the app. This could be handy when you want to see how the information | ||
in the datamodel is connected. | ||
</p> | ||
<p> | ||
Click the button to open the hypercube builder. | ||
</p> | ||
</div> | ||
), | ||
spotlightClicks: true, | ||
disableOverlayClose: true, | ||
hideFooter: true, | ||
target: '.add-button', | ||
title: 'Hypercube builder', | ||
}, | ||
{ | ||
step: 'selectEntity', | ||
content: ( | ||
<div> | ||
<p>Here you can see a list of all the fields, dimensions and measures defined in the app. The input field on top will filter the list.</p> | ||
<p>Click on an entity to select it.</p> | ||
</div> | ||
), | ||
disableOverlayClose: true, | ||
hideFooter: true, | ||
spotlightClicks: true, | ||
target: '.cube-column-chooser', | ||
title: 'Hypercube builder', | ||
}, | ||
{ | ||
step: 'addAnotherColumn', | ||
content: ( | ||
<div> | ||
<p> | ||
A cube is created with the selected entity as the first column. All the entity values are shown | ||
and it is possible to spot any errande values. If selections are applied, only the selected values | ||
are displayed. | ||
</p> | ||
<p>Add another column by clicking the plus button.</p> | ||
</div> | ||
), | ||
disableOverlayClose: true, | ||
hideFooter: true, | ||
spotlightClicks: true, | ||
target: '.card', | ||
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, | ||
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', | ||
title: 'Hypercube builder', | ||
}, | ||
{ | ||
content: ( | ||
<div> | ||
<p> | ||
Now you can continue to explore your data model with catwalk on your own! | ||
</p> | ||
<p> | ||
To restart the guide, right click and select | ||
{' '} | ||
<code>Start Guide</code> | ||
. | ||
</p> | ||
</div> | ||
), | ||
placement: 'bottom', | ||
target: '.topbarLogo', | ||
title: 'Guide completed!', | ||
}, | ||
]; | ||
|
||
export default steps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import React, | ||
{ | ||
useState, | ||
useCallback, | ||
forwardRef, | ||
useImperativeHandle, | ||
} from 'react'; | ||
import Joyride, { ACTIONS, EVENTS, STATUS } from 'react-joyride'; | ||
import steps from './guide-steps'; | ||
|
||
import './guide.pcss'; | ||
|
||
// The component needs to be wrapped in `forwardRef` to give access to the | ||
// ref object assigned using the `ref` prop. | ||
const Guide = forwardRef((props, ref) => { | ||
const [runGuide, setRunGuide] = useState(!localStorage.getItem('catwalkGuide')); | ||
const [stepIndex, setStepIndex] = useState(0); | ||
|
||
// Any instance of the component is extended with what is returned from the | ||
// callback passed as the second argument. | ||
useImperativeHandle(ref, () => ({ | ||
startGuideFunc() { | ||
if (!runGuide) { | ||
setRunGuide(true); | ||
} | ||
}, | ||
})); | ||
|
||
const setStep = (stepName) => { | ||
setRunGuide(false); | ||
setStepIndex(steps.findIndex(s => s.step === stepName)); | ||
setTimeout(() => setRunGuide(true), 300); | ||
}; | ||
|
||
const onClick = useCallback((evt) => { | ||
let parentElemName = evt.target.parentElement.className; | ||
if (parentElemName) { | ||
parentElemName = parentElemName.trim(); | ||
} | ||
|
||
if (parentElemName === 'field') { | ||
// a click in the field (to open the filterbox). | ||
// stop and start the guide in order to highlight the opened filterbox. | ||
setRunGuide(false); | ||
setRunGuide(true); | ||
} | ||
if (parentElemName === 'add-button') { | ||
// a click on the big hypercube builder button. | ||
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'); | ||
} | ||
} | ||
if (nbrOfColumns > 0) { | ||
setStep('cubeFinished'); | ||
} else { | ||
setStep('addAnotherColumn'); | ||
} | ||
} else if (parentElemName === 'column-add-button') { | ||
// a click on the little add button in the hypercube builder. | ||
setStep('selectAnotherEntity'); | ||
} | ||
}, []); | ||
|
||
const handleJoyrideCallback = (data) => { | ||
const { | ||
action, index, type, status, | ||
} = data; | ||
|
||
if ([EVENTS.TOUR_START].includes(type)) { | ||
document.addEventListener('mouseup', onClick); | ||
} else if ([STATUS.FINISHED, STATUS.SKIPPED].includes(status)) { | ||
setRunGuide(false); | ||
setStepIndex(0); | ||
localStorage.setItem('catwalkGuide', 'catwalk'); | ||
document.removeEventListener('mouseup', onClick); | ||
} else if ([EVENTS.STEP_AFTER, EVENTS.TARGET_NOT_FOUND].includes(type)) { | ||
const newStepIndex = index + (action === ACTIONS.PREV ? -1 : 1); | ||
// Update state to advance the guide | ||
setStepIndex(newStepIndex); | ||
} | ||
}; | ||
|
||
return ( | ||
<Joyride | ||
continuous | ||
stepIndex={stepIndex} | ||
showProgress | ||
showSkipButton | ||
disableBeacon | ||
run={runGuide} | ||
callback={handleJoyrideCallback} | ||
styles={{ | ||
options: { | ||
primaryColor: '#398ab5', | ||
}, | ||
}} | ||
steps={steps} | ||
/> | ||
); | ||
}); | ||
|
||
export default Guide; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section reads a bit weird for me, shouldn't the full form be presented first before talking about parts of it? I.e. explain
6(5)
before explaining6
. I also got a bit confused when the numbers weren't related to my app/the focused field :)