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

New global store version + new dynamic styling for categorization page #66

Merged
merged 12 commits into from
Mar 18, 2022

Conversation

jarmoza
Copy link
Contributor

@jarmoza jarmoza commented Mar 4, 2022

As per #64, this PR contains the proposed, new version of the global store and new means of dynamic styling (via store data and class names only) for category linking on the categorization page.

Some detailed notes

  • The store has been flattened and any page specific data (mostly for nav and routing currently) are in store.pageData. It made sense to do this conversion in this PR because currently the majority of the store serves category-column linking and styling
  • Category-column linking and subsequent table painting no longer relies on examining the current colors of the element but rather uses class swapping to accomplish this while using a category-column map saved in the store as a ground truth. (formerly paintingData). This appears to be the best way to do this since b-table somewhat obscures access to the table rows and its dynamic class attribute for its rows (tbody-tr-class) is only computed on page load.
  • $refs was actually only used once by the categorization page itself (see styleTable, essentially a pass-through function). This is to ensure proper code encapsulation when the page changes state – e.g. the page knows its child component (the table) needs to be refreshed and directs it to do so. In this case, it's the filedata-table needing to repaint itself when the categorization page is navigated back to from another page
  • A previously unreported bug was fixed where one could "unclick" the current category in the coloring-listgroup and technically, rendering the current category transparent, and thus appearing as if painting the table was disabled. Now subsequent clicks on the already-selected category in the listgroup produces no visible change.

…data and class names only for category linking on categorization page
@jarmoza jarmoza requested a review from surchs March 4, 2022 22:44
Copy link
Contributor

@surchs surchs left a comment

Choose a reason for hiding this comment

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

Thanks @jarmoza for this large PR, this is a lot of work.

Having read over the code, I believe that we should make some changes that will allow us to handle this in a more compact form that is also more intuitive.

  1. Let's replace the coloring-listgroup component with a <b-table> component.
    We already know how to reactively style rows of a table and how to react to click-events there.
    This will make it easier for us to split the "category-to-column-mapping" side from the "updating-the-UI-components-reactively" side.
  2. And linked to 1.: let's use Vue for handling styling changes in response to changes of state and data, and let's avoid handling these things directly. We have discussed this before. We have adopted this framework to make things easier to understand, for us and future collaborators. But that means we also have to use the framework in the way it was intended/recommended, otherwise we don't get these benefits. From my review of the code, all instances where the DOM is currently directly access and edited can be handled more cleanly and compact via Vue.

To illustrate both points, I have coded up a small example here (its all in a single component though): https://codepen.io/surchs/pen/vYWqQKp?editors=1011

This uses @row-selected to handle both the category-selection and the category-to-column mapping. And it uses :tbody-tr-class to style the category-selection and category-to-column-mapper elements reactively.

I think we should adopt a similar structure for the corresponding components here. It would probably make sense for us to discuss this in person. Let me know what you think.

},

// Index of most recently clicked list group item
clickedIndex: 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the actual category names here. We should have access to them from the global store. We can still initialize as null. We can rename the variable to currentCategory or something descriptive like 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.

Sure, this small change is possible though currently moot since clickedIndex is only used as check to see if the same category is being clicked again. More on that in your next comment on null and currentCategory below.

@@ -55,23 +61,30 @@
// 1. Get the list group item element
Copy link
Contributor

Choose a reason for hiding this comment

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

This method handles both the styling (opacity) and the category selection. I think we should split the functionality to keep things clean.

So for example: -> clicking a row only updates currentCategory. If clickedCategory === currentCategory, then currentCategory = null, i.e. gets "unassigned". Otherwise currentCategory = clickedCategory.

Then we can have a separate method called stylingCategorySelector or something like that. This thing is responsible for redrawing the category-selector element whenever the currentCategory changes and to apply the appropriate styling. For example, the input to the category-selector element could be a computed property then.

I think both methods/computed properties should be pretty compact and straightforward.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is possible with the changeover to a b-table since usage of tbody-tr-class and @row-selected in conjunction is possible. The only stipulation here is that currentCategory should never be null. This is a UX consideration.

When a user is confronted with the categorization page, one category (the first, by default) should be selected as a visual prompt for the action of selecting categories from the listbox (or table).

On top of that, the state of not being able to paint doesn't currently make sense in our current design of the page.

Copy link
Contributor

Choose a reason for hiding this comment

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

The only stipulation here is that currentCategory should never be null

Now that I think about it, we currently treat null as an (empty) category. So there could be a use case for a no-current-category-selected state where currentCategory is null (e.g. you navigate back to categorization page to unassign a category but now first either need to select the current category to "unpaint" it or paint and "unpaint" with a different category). But I agree, that might make the interface less intuitve. Besides, we have other ways of quickly unassigning a category (e.g. in the annotation page).

let makingItemOpaque = ( this.defaultOpacity == currentOpacity ||
"" == currentOpacity );
let makingItemOpaque = ( this.opacities.default == currentOpacity ||
"" == currentOpacity );

// NOTE: Blank style string means it is unstyled.
// This occurs because Vue CSS is considered to be an external stylesheet
// If needs for more dynamic CSS styling arises, may need to re-address

// 3. Make all list group items transparent
let listGroup = document.getElementById(this.tag + "-listgroup");
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to go the DOM route here. We can use a b-table instead of the listgroup and apply our custom category CSS classes via :tbody-tr-class. This will also be a lot more compact.


// A. Set each row to either default or custom style, depending on the category column map
let rowKey = this.tableID + "__row_" + index.toString();
let row = document.getElementById(rowKey);
Copy link
Contributor

Choose a reason for hiding this comment

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

Here too I think we do not have to go the DOM route. :tbody-tr-class is a more concise way to apply classes to the rows (and I think we had that before, no?). We can set the selected-variant = "" to an empty string so we don't have to worry about the default selected styling.

methods: {
methods: {

styleTable() {
Copy link
Contributor

Choose a reason for hiding this comment

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

nice! I like this method!
But why isn't it used/called inside this component? Looks like this is being invoked only from the categorization page via reference. If this is supposed to restyle based on state changes, we can just pass the global state variables via props and use the :tbody-tr-class in a computed property that'll update automatically.

store/index.js Outdated

// Participants.tsv file data
// For format see 'convertTsvLinesToDict' in index.js
tsvDataOriginal: null,
Copy link
Contributor

Choose a reason for hiding this comment

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

how about rawDataTable

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 was thinking that these tsvData fields in the store should be grouped under one object. How about something like:

tsvData: {
    raw: null,
    annotated: []
}

And a similar object for the dataDictionary fields. I'll just mention this here instead of replying to each of your comments on the store names.

Copy link
Contributor

Choose a reason for hiding this comment

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

oh, yeah, I think that's a better way of handling this, agreed! In this case I would still drop the file extension from the variable name. Maybe dataTable and dataDictionary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just an addendum: How about dataTable.original instead of dataTable.raw? Raw data is not actually stored here as it's converted into the format (array of objects) asked for by b-table?

Copy link
Contributor

Choose a reason for hiding this comment

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

agreed, that's clearere!

store/index.js Outdated
// Stores table data in format ready for Bootstrap table
// This is an array of objects. See 'tableDataFromTsvAndOrJson' in
// categorization.vue for exact format
tsvDataTableFormatted: [],
Copy link
Contributor

Choose a reason for hiding this comment

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

how about annotatedDataTable

store/index.js Outdated

// Original data dictionary file data
// (formerly home.jsonFile)
dataDictionaryOriginal: null,
Copy link
Contributor

Choose a reason for hiding this comment

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

how about rawDataDictionary

store/index.js Outdated
dataDictionaryOriginal: null,

// User-amended data dictionary file data
dataDictionaryAmended: {},
Copy link
Contributor

Choose a reason for hiding this comment

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

how about annotatedDataDictionary

store/index.js Outdated
// Maps our categories in 'categoryList' to colors in 'toolColorPalette'
// (Final class names pending). This way colors can be swappable and
// rearrangeable for categories
categoryToColorMap: {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe we wanted to turn this into a computed property (via a hook on the upload page) and have an explicit mapping of category names to color names. This will allow us to access this more intuitively inside the app (e.g. by searching for the category name as the key rather than an index we have to get from some other place first.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So in other words, depending on the flavor of annotation the category to color mapping changes? I think we discussed this but was not considered for this PR. Since I also recall us discussing putting that on a page that will precede the upload page, I think we should make an issue for this feature. I've created one here: #67

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, makes sense to handle this in a separate PR. I mainly brought it up here because I find it more intuitive if categoryToColorMap has the actual category names (like categoryColumnMap does), i.e.:

categoryToColorMap: {
  "Age": "color1",
  "Sex": ...
}

I remember we discussed the computed property both in the context of future flexibility (for other categories), but also as a way to get the above explicit mapping without having to retype the category names a second time (and having to keep them in sync). I was more referring to the clarity aspect here. I'll add it to the issue.

@jarmoza
Copy link
Contributor Author

jarmoza commented Mar 10, 2022

@surchs While a b-table is possible for the categories list in coloring-listgroup, usage of tbody-tr-class is not for the table we are painting in filedata-table on the categorization page.

Though the reasoning for the use of class swapping via DOM selection instead of tbody-tr-class is mentioned in my PR comments, I had to go back and doublecheck why I did not use the @row-selected solution. Unfortunately, this does not work as @row-selected does not exhibit the desired behavior for "painting" the table with the selected category. Any second click on a row is considered a "deselection" of that row. And deselection of a row does not pass row data into the attached method to tbody-tr-class since the selected class is being removed. And since the second click on the row is assumed to be a deselection, it also "unpaints" the table row to the default background/foreground colors. Thus, if someone were to attempt to paint an already-painted row with another category, the action fails to produce the desired result of a color change.

When we use row-clicked in order to get the row data during each click on a row, tbody-tr-class no longer functions as a reactive attribute as we would wish. Thus it becomes necessary to identify the DOM element of the clicked row and swap its class.

See my codepen here, adapted from the one you posted here yesterday: https://codepen.io/jarmoza/pen/RwjXYrq

So either we can live with the solution of selecting the DOM element and swapping the class or find another workaround in Bootstrap-Vue.

I'll refrain from commenting further on your comments that address that tbody-tr-class solution until we discuss further.

@surchs
Copy link
Contributor

surchs commented Mar 10, 2022

For reference, we found that @row-clicked did not cause a reactive redraw by Vue because Vue doesn't seem to be aware of the dependency between the categoryToColumnMap and the table styling via the :tbody-tr-class binding. So although we change categoryToColumnMap in response to the @row-clicked event, this is not detected by Vue. One solution is to directly change the data being fed to <b-table> in response to @row-clicked - Vue does pay attention to that change, and then we can get reactive styling as intended. Example here: https://codepen.io/surchs/pen/rNYXRdO edit: see #66 (comment) below

The @row-selected event might make more sense regarding what we are doing here (selecting and deselecting things), but this event only passes on information about the clicked row when it changes from unselected->selected, not when it changes from selected->unselected. So although we would not use the Vue isSelected property to apply our styling (because we need more than the one style supported by Vue), we don't have a way to react to a user clicking on an (internally) unselected row and users have to double-click (to first internally re-select). We could hack around that by programmatically unselecting a row immediately after it was selected, but at this point we would have made things pretty obscure again and we wanted to avoid that with this PR.

So, short story: @row-clicked it is.

@jarmoza
Copy link
Contributor Author

jarmoza commented Mar 11, 2022

In addition, via this morning's update by @surchs. Though @row-clicked does not initiate an update to tbody-tr-class, updating an object that Vue is watching will initiate that update. With this in mind, updating a piece of data in the filedata-table component (that is also logically linked to category-column linking) should be a sufficient way to ensure the row values are updated (via the method assigned to tbody-tr-class). I will make sure to comment how/why this is working in the code.

@surchs
Copy link
Contributor

surchs commented Mar 11, 2022

we found that @row-clicked did not cause a reactive redraw by Vue because Vue doesn't seem to be aware of the dependency between the categoryToColumnMap and the table styling via the :tbody-tr-class binding. So although we change categoryToColumnMap in response to the @row-clicked event, this is not detected by Vue. One solution is to directly change the data being fed to <b-table> in response to @row-clicked - Vue does pay attention to that change, and then we can get reactive styling as intended. Example here: https://codepen.io/surchs/pen/rNYXRdO

It appears that b-table does in fact have a way of listening to changes to dependencies for the :tr-body-class via @row-clicked even when the data sent to :items is not changed. Here is a simple example of this working: https://codesandbox.io/s/reactive-table-painting-with-rowclicked-forked-y9ezz1?file=/App.vue

It's not entirely clear why this codepen works but e.g. this very similar one does not. Rather than digging deeper into the details of the Vue implementations in these web services or Vue itself, we tried out the working solution inside our Vue app and found that it does work. So we decided to go with it.

@jarmoza
Copy link
Contributor Author

jarmoza commented Mar 15, 2022

@surchs Here are notes for updates made in commit 4be1cca

Components

category-select-table: This is the former coloring-listgroup component.
It's now a table based on the categories list in the store with rows styled via tbody-tr-class method that
returns the proper color and opacity classes. The first category is the default selection.

column-linking-table: This is the former filedata-table component.

  1. Rows are styled via tbody-tr-class. Clicks style the row, but the categorization page handles category-column linking in the store.
  2. There is no longer a category map in the store for that purpose. Instead columns are linked with categories in dataTable.annotated table data in the store.
  3. This componenet now gets needsRefresh boolean prop from the categorization page, watches it to see if the categorization page has turned it on, and will redraw the table when it is. It emits an event back up to the categorization page once redrawing has been initiated to flip that flag back to 'false.'

tool-navbar:

  1. The navbar component has been cleaned up and refactored to look for page names and accessibility status in the global store it receives from its parent pages.
  2. The title (tool name) is now dynamic and the color for nav items is determined via their accessibility status (green or gray) and whether or not the nav item represents the current page (black).

Pages

annotation: The annotation placeholder page has just been updated to use the changed tool-navbar component and uses the Vuex mapState functionality for the page data store items it needs.

categorization:

  1. The categorization page now uses the new category-select-table and column-linking-table components. Props for those components have been updated for their new needs, including the passing of information from the global store like categories and categoryClasses.
  2. Unnecessary or one use data members have been removed or slightly refactored (see categorySelectText and columnLinkingTable fields, for instance).
  3. Next page access (like with index) is now dependent on whether or not the accessible flag for the 'next' page is 'true' in the global store.
  4. Like with the other pages, Vuex's mapState (and also mapGetters, in this case) is used to simplify references to values and getters in the global store.
  5. If this page is navigated to from another page, it will trigger a redraw of its column-linking-table via needsRefresh. (It also currently attempts to create the annoted data table upon being mounted, but this is a redundancy that might be eliminated in future commits. Currently, the annotated data table is constructed after categorization page access is made available in index via the createAnnotatedDataTable store action.)
  6. Once access to the annotation page is made available it tells the global store via the enablePageNavigation action in order to enable the 'Annotation' navitem. (Similar to the index page.)
  7. Current category is now saved in selectedCategory, a data member on the categorization page.
  8. tableClick handles the linking and unlinking of columns with categories. This affects the annotated data table in the global store.
  9. Methods have been updated to use new store value names (e.g. dataTable and dataDictionary)
  10. Unused page-specific styles have been removed

index:

  1. Content type and text area dimensions have been made data members. The latter for better Vue form, and the former if/when we handle different file formats in upcoming iterations of the tool.
  2. index also uses Vuex's mapState functionality for a few global store values.
  3. Methods have been updated to use new store value names (e.g. dataTable and dataDictionary)
  4. Similar changes to the categorization page for navbar and next page access.
  5. Functions and variables have been renamed to reflect the more generic concepts of data table and dictionary (vs. tsv and json files).
  6. Unused page-specific styles have been removed

Vuex Store

index.js: Store has been reworked and extraneous fields and functions been removed. In particular,

  1. The ground truth for page access for the tool is now in pageData. It has a companion field pageOrder to indicate our order of the pages while allowing access to page names as keys via pageData.
  2. Former tsv and json file data has been reorganized into dataTable and dataDictionary objects with original and annotated members. Original file type for the data is also stored in each.
  3. categories (formerly categoryList) and categoryClasses are now the two main fields to access category data. The latter is computed via the getter categoryClasses, mapping category names to their color style classes via the two 'private' store fields, categoryToColorMap and toolColorPalette.
  4. Actions and mutations have been cleaned up with appropriate renames and changing of functionality (e.g. category-column linking now switches annotated table field category in each column between null and the category name to indicate linkage status). The newest piece of functionality is the moving of the initial creation of the annotated data table to the store via createAnnotatedDataTable and its corresponding mutation, setupAnnotatedDataTable. Also, new is the enablePageNavigation action for switching on and off access to individual pages of the tool.
  5. Getters have been cleaned up with all redundancies removed that could be transformed into implicit mapState getters. categories remains as it is sometimes needed before page/component creation finishes. categoryClasses is the computed mapping between category names and color classes. It currently sits here but may be moved in the future when annotation type selection is made possible. Several convenient boolean getters are now also present to check for category-column link and data table and dictionary load status.
  6. Of note, the unusual syntax for getter isColumnLinkedToCategory - isColumnLinkedToCategory: (p_state) => (p_matchData) => { ... } - is the arrow syntax for how one can pass an argument to a Vuex getter.

Main.css

Some clean up and introduction of hidden class that can be used to make page items invisible. In this case, it's for the redundant header of the category-select-table.

@jarmoza
Copy link
Contributor Author

jarmoza commented Mar 16, 2022

Changes per our discussion yesterday plus some changes that made sense to do now: the introduction of the chance to call initialization code for the store and dynamic set up of category data structures.

  1. columnToCategoryMap has been added back into the store and code checking category-column linking has been adjusted accordingly
  2. As a result, the array used to populate the column-linking-table table has been given back to the categorization page to build and store (see columnToCategoryTable). And columnToCategoryMap is now passed to this component.
  3. The landing page now constructs categoryToColumnMap once at least a data file has been loaded (see store action createColumnToCategoryMap)
  4. It made sense at this point to have the category data structures be dynamically generated by the store based on the given categories and our color to CSS class map. This is done via the nuxt store init action nuxtServerInit. Of note is that only the color key (e.g. 'color1') to CSS class map is prepopulated in the store. Instead, now nuxtServerInit calls store mutation setupCategories with a given category list. (The default list is currently stored in the nuxtServerInit function though ideally it should be coming from some input file in the future, particularly if and when we have multiple category lists.) setupCategories goes about saving the categories list and deriving the categoryToColorMap and categoryClasses store objects.
  5. setupCategories is the mutation for action initializeCategories – which may be called in the future when we want to switch between category lists on the landing/instructions page.

@jarmoza
Copy link
Contributor Author

jarmoza commented Mar 16, 2022

Re: where the input categories come from/are initially stored. It's pretty much up in the air. If you have any opinions or preferences, let me know.

@surchs
Copy link
Contributor

surchs commented Mar 17, 2022

@jarmoza: about to review the new changes, I get a crash when I navigate upload > categorization:

client.js:103 TypeError: Cannot read properties of undefined (reading 'Subject ID')
    at VueComponent.styleTableRow (category-select-table.vue:77:1)
    at VueComponent.renderTbodyRow (mixin-tbody-row.js:253:37)
    at mixin-tbody.js:192:1
    at Array.forEach (<anonymous>)
    at VueComponent.renderTbody (mixin-tbody.js:190:1)
    at Proxy.render (mixin-table-renderer.js:132:1)
    at VueComponent.Vue._render (vue.runtime.esm.js:3569:1)
    at VueComponent.updateComponent (vue.runtime.esm.js:4070:1)
    at Watcher.get (vue.runtime.esm.js:4495:1)
    at new Watcher (vue.runtime.esm.js:4484:1)

Could you check if the branch runs for you or you may be missing some commits?

Copy link
Contributor

@surchs surchs left a comment

Choose a reason for hiding this comment

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

Thanks @jarmoza, this is good stuff. I really like the way the store is looking now, it all feels a lot cleaner and more accessible. Now that we have this great global store, I think we can save some space with the local store implementation in the index.vue and categorization.vue components. I have left some comments but I will make my suggestions via commits because I think that'll be easier.

I also noted that the setupColumnToCategoryTable method on the categorization component has some repeated sections left over but I will make my suggestions in a second commit - otherwise this might get a bit lengthy.

Looking forward to having this all merged soom! 🎉

}
},

props: ["categories", "categoryClasses", "instructions", "title"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's give these props a type and also define the ones that are required. See also the Vue style guide: https://v2.vuejs.org/v2/style-guide/?redirect=true#Prop-definitions-essential

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is good stuff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See: #70

selectCategory(p_row) {

// If a new category was selected...
if ( p_row.length ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I understand that 0 is falsey, are you OK with being more explicit and typing out the !== 0 part here?

}
},

props: [
Copy link
Contributor

Choose a reason for hiding this comment

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

here too I'd say let's type these and declare the required props.

this.$forceUpdate();

// B. Tell parent page that drawing request has been made
this.$emit("done-redraw");
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why we need this watcher. I think with our current solution for the column-linking-table, everything should be reactive. And this should include the props being passed to the component. So even if something is changing in the global store, this component should automatically refresh.

If this watcher (and the references to it elsewhere) are just left over from when the reactivity had to be forced, let's remove it. If you think this construct is still needed, could you please explain what would not work if we removed it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just double-checked. This can be removed! 🥳

},

computed: {

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// mapState will make the global store components defined in the array available inside this component under the same name
// see https://vuex.vuejs.org/guide/state.html#the-mapstate-helper for details

Let's add a comment here to explain what these strings mean and where we would look them up

color4: "category-style-3",
color5: "category-style-4",
colorDefault: "category-style-default"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

very nice and clean stuff. I really like the way the store looks now!


// 2. Save either an empty array or array of tsv dictionaries to state data
p_context.commit("setTsvFile", newTsvData);
initializeCategories(p_context, p_categories) {
Copy link
Contributor

Choose a reason for hiding this comment

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

my linter shows this as unused. Maybe it is called from outside vue?

Copy link
Contributor Author

@jarmoza jarmoza Mar 18, 2022

Choose a reason for hiding this comment

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

This is actually a function for future action calls. initializeCategories will be called when we want to change category lists for different annotators. Since I was implementing dynamic category setup and creating a mutation (setupCategories) for this purpose, a corresponding action accessible by the pages (the one that will be swapping category lists) makes sense.

p_context.commit("setupCategories", p_categories);
},

nuxtServerInit({ commit }) {
Copy link
Contributor

Choose a reason for hiding this comment

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

linter also says this is unused. I assume that's because it called by the Nuxt server?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's correct. We will not explicitly call this, but rather Nuxt will.


return ( p_state.painting.palette.backgroundColors.length > 0 );
},
isColumnLinkedToCategory: (p_state) => (p_matchData) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This also shows up as unused for me.

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 was wavering about whether or not to take this one out. One can check whether a column is linked to a category via the store by referencing columnToCategoryMap via mapState, but by keeping this function we can also use it to ask this question of the store and not have our pages/components worry about what that check entails.

This is generally considered good programming practice where the details of conditional checks are kept close to their data sources. In fact, I was thinking we may want to consider doing this throughout the app where applicable. And there are other instances of this scenario pops up. (See isDataTableLoaded and isDataDictionaryLoaded, for instance.)

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 have made an issue to discuss this potential refactor: #72

@@ -336,7 +361,7 @@ function convertTsvLinesToDict(p_tsvLines){
// 2. Create dictionaries for each tsv row keyed on the column headers
for ( let index = 1; index < p_tsvLines.length; index++ ){

let tsvRowDict = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

commenting here because I cannot comment on unchanged code: the function printArray above seems to be unused according to my linter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it was a debug function I had been using. It can be removed if you prefer.

@surchs
Copy link
Contributor

surchs commented Mar 18, 2022

Ah, sorry about that. My silly code reformatter has ruined the diff. Hope you can still make out the suggestions.

Copy link
Contributor

@surchs surchs left a comment

Choose a reason for hiding this comment

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

OK @jarmoza, as we just discussed, let's merge this now and turn the remaining comments into their own issues for later.

@jarmoza jarmoza merged commit 0e190bd into master Mar 18, 2022
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