Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move redux and focusSpan up from VirtualizedTraceView #517

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

aocenas
Copy link

@aocenas aocenas commented Feb 6, 2020

Signed-off-by: Andrej Ocenas [email protected]

Which problem is this PR solving?

Short description of the changes

  • Pushing redux and url creation (focusSpan) dependencies up from VirtualizedTraceView and TraceTimelineViewer to TracePage so it will be easier to move them to separate package.

@aocenas aocenas changed the title Move redux up from VirtualizedTraceView Move redux and focusSpan up from VirtualizedTraceView Feb 6, 2020
});

describe('mapDispatchToProps()', () => {
it('creates the actions correctly', () => {
expect(mapDispatchToProps(() => {})).toEqual({
expect(mapDispatchToProps(() => {})).toMatchObject({
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are few more functions because of the usage of:

...((bindActionCreators(timelineActions, dispatch) as unknown) as TDispatchPropsTimelineViewer),

In the map dispatch see a comment there.

acknowledgeArchive,
archiveTrace,
fetchTrace,
...((bindActionCreators(timelineActions, dispatch) as unknown) as TDispatchPropsTimelineViewer),
Copy link
Author

@aocenas aocenas Feb 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if the preferred way to do this. Seen it at few places and is definitely shorter than destructuring all the functions and then assign them again, but there is more stuff passed to the component than necessary needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admittedly have a bias towards verbosity, but I find it clearer and preferable to destructure everything that is necessary and pass it along, rather than (bindActionCreators(actions, dispatch) as unknown) as TType.

It's a little more verbose in this case, but I'd still prefer it over the cast.

@aocenas
Copy link
Author

aocenas commented Feb 6, 2020

Moving the redux up and passing an all the handlers makes for a pretty big props list but also I realised that all of the redux actions are simple UI toggles like expanding span. I wonder if this is so that navigating to search and back to the same trace will preserve the UI state or if that is just unneeded side-effect. Because I think lots of those could be hidden in a local component state making the props list shorter and probably making the components a bit easier to use if do not need to preserve the UI state on navigation.

Another question is whether to keep the /TraceTimelineViewer/duck.tsx where it is. I think if we keep the redux state it makes sense to still have it split like this ie having TracePage/traceTimelineViewer.duck.tsx and TracePage/archiveNotifier.duck.tsx as separate files but can also be moved and merged into TracePage/duck.tsx later on.

@aocenas aocenas requested review from everett980 and tiffon February 6, 2020 14:05
@codecov
Copy link

codecov bot commented Feb 6, 2020

Codecov Report

Attention: 13 lines in your changes are missing coverage. Please review.

Comparison is base (8cb13c4) 92.92% compared to head (3539f92) 96.57%.
Report is 751 commits behind head on main.

❗ Current head 3539f92 differs from pull request most recent head e884e7c. Consider uploading reports for the commit e884e7c to get more accurate results

Files Patch % Lines
.../jaeger-ui/src/components/QualityMetrics/index.tsx 93.87% 3 Missing ⚠️
...r-ui/src/components/Monitor/ServicesView/index.tsx 98.37% 2 Missing ⚠️
...components/SearchTracePage/SearchResults/index.tsx 90.00% 2 Missing ⚠️
...aeger-ui/src/actions/path-agnostic-decorations.tsx 97.91% 1 Missing ⚠️
packages/jaeger-ui/src/components/App/TopNav.tsx 94.44% 1 Missing ⚠️
...rc/components/DeepDependencies/SidePanel/index.tsx 96.77% 1 Missing ⚠️
...jaeger-ui/src/components/DependencyGraph/index.jsx 95.83% 1 Missing ⚠️
...ger-ui/src/components/Monitor/EmptyState/index.tsx 92.85% 1 Missing ⚠️
...c/components/Monitor/ServicesView/serviceGraph.tsx 98.18% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #517      +/-   ##
==========================================
+ Coverage   92.92%   96.57%   +3.64%     
==========================================
  Files         197      254      +57     
  Lines        4808     7620    +2812     
  Branches     1160     1986     +826     
==========================================
+ Hits         4468     7359    +2891     
+ Misses        299      261      -38     
+ Partials       41        0      -41     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Collaborator

@everett980 everett980 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aocenas, thanks again for your patience with this, sorry it took so long to circle back to.

Big picture this looks good, I left some feedback to clean it up a bit and make it a bit DRYer. I don't believe it will take long to address my feedback, but of course let me know if you have any questions or disagree.

@@ -80,13 +80,14 @@ describe('makeShortcutCallbacks()', () => {
});

describe('<TracePage>', () => {
TraceTimelineViewer.prototype.shouldComponentUpdate.mockReturnValue(false);
TraceTimelineViewer.mockReturnValue('');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do? I've never mocked the return value of a React component before.

describe('focusSpan', () => {
it('calls updateUiFind and focusUiFindMatches', () => {
const spanName = 'span1';
wrapper.instance().focusSpan(spanName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe to follow the pattern (generally) present in the code base, this should be: wrapper.find(TraceTimelineView).prop('focusSpan')(spanName);

reason being: testing wrapper.instance().fnName(arg) can lean towards testing implementation, while testing someChildComponent.prop('fnName')(arg) tests functionality (in this case child component is able to set and focus uiFind)

import { TraceArchive } from '../../types/archive';
import { EmbeddedState } from '../../types/embedded';
import filterSpans from '../../utils/filter-spans';
import updateUiFind from '../../utils/update-ui-find';

import './index.css';
import TTraceTimeline from '../../types/TTraceTimeline';

type TDispatchPropsTimelineViewer = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this type should exist somewhere that VirtualizedTraceView can import it, to be DRYer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps TTraceTimelineDispatchFns in ../../types/TTraceTimeline


type TDispatchProps = {
// was from redux
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than commenting this, a type should be imported and TVirtualizedTraceViewOwnProps can be called TProps (no separation of own vs dispatch props) which would look like:

TProps = {
  currentViewRangeTime: [number, number];
  findMatchesIDs: Set<string> | TNil;
  focusSpan: (uiFind: string) => void;
  scrollToFirstVisibleSpan: () => void;
  registerAccessors: (accesors: Accessors) => void;
  trace: Trace;
} & TImportedType;

@@ -332,6 +310,7 @@ export class VirtualizedTraceViewImpl extends React.Component<VirtualizedTraceVi
findMatchesIDs,
spanNameColumnWidth,
trace,
focusSpan,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

admittedly nit, but please destructure and pass focusSpan in alphabetical order.

@@ -71,17 +90,17 @@ type TOwnProps = {
match: Match<{ id: string }>;
};

type TReduxProps = {
type TReduxProps = TExtractUiFindFromStateReturn & {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

acknowledgeArchive,
archiveTrace,
fetchTrace,
...((bindActionCreators(timelineActions, dispatch) as unknown) as TDispatchPropsTimelineViewer),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admittedly have a bias towards verbosity, but I find it clearer and preferable to destructure everything that is necessary and pass it along, rather than (bindActionCreators(actions, dispatch) as unknown) as TType.

It's a little more verbose in this case, but I'd still prefer it over the cast.

@everett980
Copy link
Collaborator

I wonder if this is so that navigating to search and back to the same trace will preserve the UI state or if that is just unneeded side-effect.

While the case of going from a trace back to search back to that trace in a single session is probably pretty rare, I believe this implementation also ensures that going from the Trace Gantt Chart to the Trace Graph and back to the Gantt Chart preserves the visible spans / span details / KV tables within span details. For this reason I believe it visibility state should not be lost on unmount.

However, if we wanted to simplify the props list and keep this functionality, TraceTimelineViewer could tuck its visibility state away into session storage on componentWillUnmount then restored in the constructor (not, not componentWillMount as its deprecated).

Using session storage instead of a highly verbose props list is actually probably the best approach as it will lessen the burden to embed this component.

@everett980
Copy link
Collaborator

I think if we keep the redux state it makes sense to still have it split like this ie having TracePage/traceTimelineViewer.duck.tsx and TracePage/archiveNotifier.duck.tsx as separate files but can also be moved and merged into TracePage/duck.tsx later on.

Using session storage makes this a moot point, but in case a similar pattern comes up later:
I also like having the divide between these two ducks. I think the best approach would be to have a TracePage/duck.tsx file that simply imports the two ducks and exports the full redux functionality for TracePage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants