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

Creating and editing note experience should be the same #310

Merged
merged 4 commits into from Dec 19, 2018

Conversation

galileo
Copy link
Contributor

@galileo galileo commented Dec 18, 2018

Release Type: Non-Breaking Feature

Fixes https://x-team-internal.atlassian.net/browse/XP-2518

Description

We decided to follow recently with the path where we will align Notes experience which will only show us the plain textarea editor.

Checklist

Before submitting a pull request, please make sure the following is done:

  • set yourself as an assignee
  • set appropriate labels for a PR (In Review or In Progress depending on its status)
  • move respective JIRA issue to the IN REVIEW column
  • make sure your code lints (npm run lint)
  • Flow typechecks passed (npm run flow)
  • Snapshots tests passed (npm run jest)
  • check cleanup tasks (https://github.com/x-team/auto/labels/cleanup) and take a suitable small one (if exists) in a related area of the current changes
  • component's documentation (.stories.js file) is changed or added accordingly to reflect any new or updated use cases or variants usage.
  • if you've fixed a bug or added code that should be tested, add unit tests
  • if any snapshots have been changed, verify that component still works and looks as expected and update the changed snapshot
  • manually tested the component by running it in the browser and checked nothing is broken and operates as expected!

Steps to Test or Reproduce

  1. Go into applicant
  2. Add a new note (you can use markdown syntax)
  3. Edit recent note, you should see only the plain textarea, when you select a word you should not see any context menu from Medium
  4. Save

Impacted Areas in Application

Notes Inline editing, NotesFeed

Screenshots

zrzut ekranu z 2018-12-18 12-23-30

@galileo galileo self-assigned this Dec 18, 2018
@@ -187,22 +190,32 @@ class Note extends PureComponent<Props, State> {
}

handleEditorValueChange = (onValueChange: Function) => (value: any) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that given how we changed the component, the value argument should be renamed to event and set its type to SyntheticEvent<HTMLTextAreaElement>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct that the way which I followed on auto PR. Thanks 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@reyronald I applied changes but. After I added this Event definition for this method I ended up with multiple errors so I was forced to use in the event type definition
(value: any) to resolve them. I there is a possibility to solve this easily please let me know how to deal with that.

I guess the value can be anything right now from SyntheticEvent to any other object. You can try for example with mixed and it will crush for several places. I would really appreciate your help. Cheers

Copy link
Contributor

Choose a reason for hiding this comment

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

That's because in the body of that function you are using .target instead of .currentTarget which is a common mistake, it's described in the Flow documentation here: https://flow.org/en/docs/react/events/

Note: To get the element instance, like HTMLButtonElement in the example above, it is a common mistake to use event.target instead of event.currentTarget. The reason why you want to use event.currentTarget` is that event.target may be the wrong element due to event propagation.

If you go directly to the Flow definition of SyntheticEvent in react-dom and check the target property, you'll even find more context:

https://github.com/facebook/flow/blob/2d9ade7e8bb97bbde458c69086c3460c3bcd04d9/lib/react-dom.js#L130-L132

declare class SyntheticEvent<+T: EventTarget = EventTarget, +E: Event = Event> {
  bubbles: boolean;
  cancelable: boolean;
  +currentTarget: T;
  defaultPrevented: boolean;
  eventPhase: number;
  isDefaultPrevented(): boolean;
  isPropagationStopped(): boolean;
  isTrusted: boolean;
  nativeEvent: E;
  preventDefault(): void;
  stopPropagation(): void;
  // This should not be `T`. Use `currentTarget` instead. See:
  // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11508#issuecomment-256045682
  +target: EventTarget;
  timeStamp: number;
  type: string;
  persist(): void;
}

A more thorough explanation of why we should use currentTarget instead is explained in that link: DefinitelyTyped/DefinitelyTyped#11508 (comment)

So, Flow's libdefs were designed to prevent this common mistake :). That's why it's always helpful to annotate things properly because then the tool will prevent us from doing unintended things.

With that fix it'll clear the errors you were getting related to that. After, you'll have to update the type of the onChange prop over at InputField too, but if you do it properly you'll get errors from other places of the app that are doing the same mistake, so I would suggest just using any there:

  onChange?: (value: any) => void,

It was untyped anyway before so you wouldn't be doing any more harm!

Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't tested it with those changes, but if applying them break the functionality you were aiming for just roll them back and disregard the suggestion, not worth it to spend more time debugging it just to fix that tiny thing 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks a lot for the detailed answer I really appreciate it! I think I had the same thoughts while I was adding those changes. So the question is?
I added the definition for the onChange function like this:

 onChange?: (value: any) => mixed,

And you introduce the void return (actually is this the specification of return type for functions?)

 onChange?: (value: any) => void,

Should I change it to void? It was previously declared as mixed. WDYT? @reyronald

Copy link
Collaborator

@nicksp nicksp Dec 19, 2018

Choose a reason for hiding this comment

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

According to official docs, () => mixed should be used for types that accept arbitrary functions. For our case when we have a defined function signature and it doesn't return anything, use of void should be fine. That's how I understand it though 😄

So, for this specific case, I'd suggest changing to void as it's more explicit type signature cc @galileo

Copy link
Contributor

Choose a reason for hiding this comment

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

Just like Nick said, I guess () => mixed was chosen here so that it would accept arbitrary functions.

But in this case, event listeners are not really arbitrary functions, they all have the same base shape where they accept an Event as an argument and return nothing, so that's why in my snippet I changed it to onChange?: (value: any) => void. You can see how it's defined here:

https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent (check "Return value")

And also the official specs (a little bit harder to interpret but you'll notice it doesn't return anything there either):

https://dom.spec.whatwg.org/#callbackdef-eventlistener

@galileo @nicksp

src/components/ui/Note.js Outdated Show resolved Hide resolved
@galileo galileo force-pushed the XP-2518-unify-editors-for-create-and-edit branch from 25c1196 to 097e828 Compare December 18, 2018 21:29
@galileo galileo force-pushed the XP-2518-unify-editors-for-create-and-edit branch from a3d517c to 80a9a8e Compare December 18, 2018 21:36
@nicksp nicksp force-pushed the XP-2518-unify-editors-for-create-and-edit branch from 80a9a8e to cad4b42 Compare December 19, 2018 15:42
Copy link
Collaborator

@nicksp nicksp left a comment

Choose a reason for hiding this comment

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

Hey @galileo This looks very good now. I tested this in a browser locally and can confirm it behaves consistently, we no longer show a medium-formatting toolbar when selecting anything, we still preserve line breaks and highlight links. Good work!

Please just check several things related to the code. And check my input in this thread: #310 (comment)

@@ -186,23 +190,35 @@ class Note extends PureComponent<Props, State> {
return TextWrapper({}, <Text content={content} isPureContent />)
}

handleEditorValueChange = (onValueChange: Function) => (value: any) => {
this.setState({ newValueIsValid: !!value.trim() })
handleEditorValueChange = (onValueChange: Function) => (event: SyntheticEvent<HTMLTextAreaElement>) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since Function is unsafe and should be avoided(link), I'd use exactly () => mixed type for the onValueChange callback. Would like to see what you guys think.
cc @galileo @reyronald

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But this is our general approach or from now because we are using a lot of Function definition, you can check in this file. For me it is misleading for this project if I can not base my assumption on the current project state 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not everything we have in a project is correct apparently and we should fix it whenever possible. Once we're on this use case, let' fix it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for answering. Just to confirm. We, want to support for now both notations in the code?

/>
)
}

handleCancel = () => {
const { text = '' } = this.props

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not a change request, just some thoughts on code structure. For short methods that are 3-4 lines long, it's fine to have no empty lines. It's just when the method body is longer it's good to group logical blocks of code and separate them with empty lines.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Over time we should eliminate all the use cases of unsafe types like Function, any, and Object. Since we can't do that at once, we're better focusing on fixing things in the area that we touch :)

Copy link
Contributor

@reyronald reyronald left a comment

Choose a reason for hiding this comment

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

LGTM the way it is now @galileo, thanks for applying the changes!

@galileo galileo force-pushed the XP-2518-unify-editors-for-create-and-edit branch from cad4b42 to ca1f3bc Compare December 19, 2018 17:35
@galileo
Copy link
Contributor Author

galileo commented Dec 19, 2018

Changes applied

Copy link
Collaborator

@nicksp nicksp left a comment

Choose a reason for hiding this comment

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

Latest changes look great to me :) Thanks Kamil! Happy to merge that now.

@nicksp nicksp merged commit 5d112ab into develop Dec 19, 2018
@nicksp nicksp deleted the XP-2518-unify-editors-for-create-and-edit branch December 19, 2018 17:46
@nicksp nicksp added Done and removed In Review labels Dec 19, 2018
nicksp pushed a commit that referenced this pull request Jan 2, 2019
* Change inline editor for notes

* Add review requested changes

* Change types defintions

* Add build

# Conflicts:
#	lib/auto-ui.js
#	lib/auto-ui.js.map
@nicksp nicksp mentioned this pull request Jan 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants