-
Notifications
You must be signed in to change notification settings - Fork 7
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
Column linking table refactor + component test #230
Column linking table refactor + component test #230
Conversation
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.
Hey @jarmoza, thanks a lot for the PR 🎉 . Again, really good size of change, very nice to review!
I can confirm that the changes run and pass locally (I guess we already know this now that the CI is working). I do have three main comments (details in inline replies):
- I think there is logic in the component that could be refactored into a state getter. For example, you're assuming that a number of store.state variables exist, access them directly, and then pick the data you need from across them. That's a lot of work, I think a getter could do the heavy lifting here (e.g. get you the columns, and a second to get you the descriptions). We have other components who need similar things, and so we can start reusing getters.
- In some places the data flow isn't completely clear to me. There are actions called in response to click-events, but the component figures out what action to call given the current store state (I think that'd be better handled by the store itself), and then a second emit is done directly to the parent. Maybe that'd be something we can briefly chat about in case I don't get it.
- Like in Refactor of category-select-table component #229, I think we should really have less information about specifics in the store / store data in the tests. So ideally we could just hard-code the data that the getters are supposed to provide to the component during testing, and then not have to model the entire store state that is currently mostly used to fill the getters.
components/column-linking-table.vue
Outdated
applyCategory(p_row, p_index, p_event) { | ||
|
||
// Tell the parent page that a column has been linked with a category | ||
this.$emit("column-name-selected", { column: p_row.column }); | ||
const dataForStore = { column: p_row.column }; |
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.
If I understand correctly here: when I click on a column, this applyCategory
gets called. And it then tells the store: "hey, someone clicked on this column while this category was active - can you go figure this out?". So I think we can leave it up to the store to figure out whether the meaning of this click is going to be a "unlink" or a "link" action. That is, I think here we should just call the store mutation/action
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.
applyCategory
now calls the action (to be implemented in store refactor) alterColumnCategoryRelation
. This will take a payload of the column and category and determine whether the column should be linked with this category (if it has no category, or a different category associated with it) or if it should be unlinked (the input category is the same as the one it is currently associated with).
}, | ||
|
||
methods: { | ||
|
||
...mapActions([ |
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.
any reason these need to be actions instead of mutations? are you planning on using actions for any multi-mutation event? Or do you expect there to be some asynchronous logic to happen here?
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.
These will become mutations in the next store refactor, and I will be creating a new, general store refactor issue to list these changes as these come in.
A new action has been added (alterColumnCategoryRelation
) in 01377f2
The idea here is that this action will contain the logic that decides whether one of the two methods should be called given the input (column/category) and the state of the columnTocCategoryMap
in the store.
components/column-linking-table.vue
Outdated
} | ||
|
||
// 2. Tell the categorization page a column has been clicked | ||
this.$emit("column-name-clicked", dataForStore); |
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.
Why do we need this emit here? At this point I have already told the store about the column click. Could whoever is listening to this emit not receive that information from the store directly?
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.
As discussed in our huddle, the current function of this emit is to let the parent page know to check if the next page (annotation page) is ready to be accessed given the state of the store.
I am leaving in the emit
for now as I would like to handle the general move of next page access to the layout/store in a separate PR.
components/column-linking-table.vue
Outdated
this.$emit("column-name-clicked", dataForStore); | ||
}, | ||
|
||
setupColumnToCategoryTable() { |
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.
I get what this method does. But given how many assumptions we're making here about how the store will be organized, I think it might be cleaner to just ask the store to provide the data elements we want here directly - like we're doing in other components. E.g. one getter to get the column names of the data table, and a second getter to get the description for each column if there is one.
Then we don't have to do so much work in the component and also have an easier time if we decide to change the specifics in the store.
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.
As per our discussion of refactoring/writing tests toward an ideal store, this function is removed. Its logic will be split apart/reworked and added to the store. (This work will be added as a subtask of the new store refactor issue I will be creating.)
Instead, now the table rows are computed property that returns an array of objects with keys for column name, column description, and category. The first two pull from a to-be-implemented columns
store getter that returns an array of objects containing a column name and description per array entry.
The unused column of category
has also been added to the table (and is now utilized) as another visual indicator of the link between column and category. See data().uiText.tableFields
.
|
||
actions: { | ||
|
||
dispatch: (p_actionName, p_payload) => { } |
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.
I really like this. I haven't added the actions to my tests but I think it helps to document them explicitly. One thing though: shouldn't there be two actions here, linkColumnWithCategory
and unlinkColumnFromCategory
?
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.
linkColumnWithCategory
and unlinkColumnFromCategory
will be converted to mutations and a new action alterColumnCategoryRelation
has been added that will call (in future store refactor) either depending on the given action input and state of the store field columnToCategoryMap
.
getters: {} | ||
}; | ||
|
||
store.getters = { |
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.
why are the getters from above overwritten here?
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.
The mock store and getters have been completely reworked as per our discussion in Slack huddle.
See 01377f2
$store: store.actions | ||
}, | ||
|
||
computed: store.getters, |
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.
I don't think the getters are used by the component at all. Is this an oversight here?
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.
The mock store and getters have been completely reworked as per our discussion in Slack huddle.
See 01377f2
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.
Thanks @jarmoza, I think this looks great. One question: did you mean to keep the emit
in there? I may have misunderstood but I thought the record of the categorization action would be recorded in the store because of the dispatched action. Could you take a look if you still need that emit
(and the test for it)?
Otherwise, good to go.
components/column-linking-table.vue
Outdated
this.alterColumnCategoryRelation(payload); | ||
|
||
// 2. Tell the categorization page a column has been clicked | ||
this.$emit("column-name-clicked", payload); |
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.
Did you still want to remove this emit here, now that the action will handle things?
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.
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.
Ah OK, I see the point. My view was that we should refactor these components without worrying a lot about what other app parts still depend on this. So if you remove the emit
now, the the categorization page will be broken. But we have to refactor the categorization page anyway and I think having a clean component to do this against might be easier than having to remember that this emit
should be removed. But your call. Maybe a NOTE
is enough.
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.
I was torn over it, and see the logic of both sides. Let's break things. I'll at least leave a NOTE
in its place with a final commit and then merge.
Refactor changes
mapState
insteaduiText
objectsetupColumnToCategoryTable
- which has been moved from the categorization page)Component tests
Tests two scenarios to make sure the correct data is being emitted by click on the table rows:
Closes #205