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

Contributions page creation #480

Merged

Conversation

sandrina-p
Copy link
Contributor

@sandrina-p sandrina-p commented Sep 3, 2018

Desktop

image

Tablet

image

Add / edit contribution flow

sep-05-2018 22-23-32

What's done:

  • Hardcoded data with 3 giving contributions for testing purposes
  • UI Logic to add/edit contributions with hardcoded submit for testing purposes.

Cool features

  • Add / Delete contributions by using cursor or pressing Enter
  • Cancel from adding/editing contribution by clicking "Cancel" or pressing Esc
  • The placeholder to add a new contribution is a random value from 5 predefined placeholders 🎲
  • All the actions can be achieved by just using screen readers with meaning names (labels and errors).

Next step

Since this PR is already big I suggest to deal with Monetary contributions UI Logic in a separate branch/PR. That way this one is easier/faster to review/merge.

Girl scout Rule

Fix #481

@sandrina-p sandrina-p force-pushed the feat/contributions-page-creation branch from 6f587c2 to 70b5b6a Compare September 5, 2018 20:16
@sandrina-p sandrina-p force-pushed the feat/contributions-page-creation branch from 70b5b6a to 6486b42 Compare September 5, 2018 20:18
@sandrina-p sandrina-p changed the title WIP: Contributions page creation Contributions page creation Sep 5, 2018
},
methods: {
handleClick () {
if (this.$listeners.click) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: I don't like very much this condition, but it was the cleaner way I've found to conditionally trigger a different behaviour when the contribution is monetary.
Maybe a prop isMonetary is more intuitive...

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about this this.$listeners approach... it seems very confusing and arbitrary to me.

With this approach, there is no clear relationship between the parent component and this one. It's not clear semantically what it means for this.$listeners.click to exist, so I would not rely on it for semantic meaning as is being done here.

Instead, I would recommend using $emit to emit events that the parent component can listen for and act appropriately.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I'll use the $emit like I did with @new-value, actually it's way obvious.

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 nevertheless it's needed to confirm if the parent is listening to the $emit. When it's not, it should set this.isAdding to true (that shows the input)

@@ -12,7 +12,7 @@ export default {
default: 'span'
}
},
computed: {
methods: {
Copy link
Contributor Author

@sandrina-p sandrina-p Sep 5, 2018

Choose a reason for hiding this comment

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

(I've already wrote this, but the comment disappeared, so I'm writing it again, sorry if you get a double notification)

@taoeffect there was a weird bug on input save/delete buttons when using i18n.

sep-05-2018 21-20-43

Note how the delete button (red color) has the Save button text "save" and not "delete". The DOM/JS is correct: The delete button (red save), deletes the contribution and the save button (blue save), updates the text.

This was really tricky and I took a while to understand the problem was from i18n and not the component itself. Changing translatedText from computed to methods seemed to fix the issue and each button has the correct text, but honestly I can't explain exactly why that bug happened...

}
</style>
<script>
import { symbol } from './utils/currencies.js'
Copy link
Member

Choose a reason for hiding this comment

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

If you want to "boy/girl scout rule" this one, I just opened a minor issue: #481

You don't need to do it for this PR, only if you want. It would require doing some replacements in other files as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do it later :)

variant="editable"
@click="showGivingMincomeSettings"
>
<span class="has-text-weight-bold">{{currency}}{{giving.monetary}}</span> <i18n>to other's mincome</i18n>
Copy link
Member

Choose a reason for hiding this comment

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

Some languages may reverse the order of the information... so it might be better to place the span inside the i18n...

>
<strong v-if="isMonetary(contribution.type)">{{textGivingMonetary(index)}}</strong>
<strong v-else>{{contribution.what}}</strong>
<i18n>from</i18n>
Copy link
Member

Choose a reason for hiding this comment

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

Similar to the comment below, the problem with chopping up strings like this (outside of <i18n> tags), is that some languages may reverse the order of words.

In other words, here we have a sentence that looks like this:

Cooking from Lilia Bouvet

But another language might write that like so:

Bouvet Lilia Cooking from

Or something else entirely crazy.

This is why you need to go through the entire PR and look at all areas like this, and ensure that all sentences are enclosed entirely within a single <i18n> tag, and use the :args= binding to pass in variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It makes sense, I'll look into that later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we're dealing with text within html tags and part of it has a button that is a tooltip... Kinda tricky. @taoeffect how do you suggest to implement the translation here?

return this.placeholders[Math.floor(Math.random() * this.placeholders.length)]
},
iconClass () {
return this.$listeners.click ? 'fa-ellipsis-v' : 'fa-edit'
Copy link
Member

Choose a reason for hiding this comment

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

(Read this comment after the one below about this.$listeners)

Similarly, here I would rely on some internal this.state variable that has a value of possible enums (defined as constants at the top of this file, perhaps)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

possible enums? like what? check what I've done to see if it's ok...

@sandrina-p sandrina-p force-pushed the feat/contributions-page-creation branch from 5f95937 to bac8a22 Compare September 6, 2018 06:54
<contribution
v-for="contribution, index in receiving"
:variant="isMonetary(contribution.type) ? 'editable' : undefined"
v-on="isMonetary(contribution.type) ? { 'control-click': showReceivingSettings } : {}"
Copy link
Member

Choose a reason for hiding this comment

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

We need to avoid the use of 'control-click' for a couple reasons: (1) it can be confusing for some users, especially Mac users, who are not used to control-clicking things, and (2) it doesn't exist on mobile

Copy link
Contributor Author

Choose a reason for hiding this comment

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

control-click doesn't have nothing to do with ctrl key... it means the dev controls the click on the contribution and doesn't trigger the input, yah... horrible name. I'll find a better name and let you know about it

>{currency}{amount} for mincome</i18n>
<strong v-else>{{contribution.what}}</strong>
<i18n>from</i18n>
{{getWho(contribution.who)}}
Copy link
Member

Choose a reason for hiding this comment

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

So is there a reason that lines 23, 24, and 25 can't be placed into the i18n tag on line 20? Remember that at least entire sentences must be translated as a whole, not as parts, as otherwise it might be impossible to translate the UI into some language

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe you didn't see my last comment yesterday asking for you advice on the implementation for this exact lines:

Here we're dealing with text within html tags and part of it has a button that is a tooltip... Kinda tricky. @taoeffect how do you suggest to implement the translation here?

So, instead of having Cooking from John we'll have <\strong>Cooking</strong> from John.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I've found a way using Vue native directive v-html Raw-HTML... but we still have the button/tooltip (and X others part) out of i18n... check the last commit and let me know your thoughts.

return this.placeholders[Math.floor(Math.random() * this.placeholders.length)]
},
iconClass () {
return this.hasControlClickListener ? 'fa-ellipsis-v' : 'fa-edit'
Copy link
Member

Choose a reason for hiding this comment

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

possible enums? like what? check what I've done to see if it's ok...

Yeah I'm saying that checking whether there is a click listener, ctrl-click listener, etc, is not semantically meaningful. In other words, it's not clear at all what that means, when what you're trying to say here is that "this contribution is of a certain type". That is not conveyed at all by assigned a control-click listener.

For example, the control-click listener needs to be removed anyway (see the comment above about that), but that shouldn't have any impact on what goes on here.

So what you want to do is pass in a param to the component that sets its type (or, if it's not about type, but about what state the contribution is in, then it would set the initial this.state variable to some value).

Then either the this.type or this.state would be checked here. And it needs to be semantically clear what you're checking, what it means in other words. Like well written English. this.hasControlClickListener tells me nothing about what is being checked here and why 'fa-ellipsis-v' is returned in one case, and 'fa-edit' is returned in another. The code should read like a book and tell me that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I completely agree with you and that was the comment I had before, with a TODO about my struggle to find the right name to reflect the context correctly.

So... let me put it into words and maybe find a good name for it. The component <contribution>'s state can be "self-controllable" or not:

  • When it is, it shows the input to create/edit a contribution after the user interacts with it - the edit icon button or all the contribution (ex: Add non-monetary method)). This happens on non-monetary contributions.
  • When not, instead of showing the input, the parent is the one who decides what happens when the user interacts with it. In this case, to show (in a next PR) a Modal with Monerary methods. This happens on monetary contributions.

After this... maybe the best prop name is isMonetary and the best custom-event name is @interact.

In practice..
if isMonetary it has the icon 'fa-ellipsis-v', otherwise it has 'fa-edit'.
if isMonetary, on click it emits @interact, otherwise it shows the input to edit the contribution.

Does it makes more sense now?

methods: {
handleClick () {
if (this.hasControlClickListener) {
this.$emit('control-click')
Copy link
Member

@taoeffect taoeffect Sep 6, 2018

Choose a reason for hiding this comment

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

This needs to be a different event that's semantically meaningful. If after reading all my comments here it's still not clear what I mean by that, then let me know and we can do a video chat about it :)

:isMonetary="isMonetary(contribution.type)"
@interaction="showReceivingSettings"
>
<span v-html="textReceivingContribution(contribution, index)"></span>
Copy link
Member

Choose a reason for hiding this comment

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

This seems acceptable for now, and it seems like a flexible enough approach that we can modify it if necessary for the section containing the tooltip below. Nice job! 👍

@taoeffect taoeffect merged commit 2950dab into okTurtles:master Sep 7, 2018
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.

None yet

2 participants