Kinopio Select

· Ben’s Blog

I had some general discussion on Futureland recently around Kinopio, and also pirijan is starting to spec out a design for the feature. This engendered some tangential thoughts around more advanced selection features because part of the motivation for grouping is to make it easier to manipulate and organize cards.

I wondered whether he could expose some functionality that would allow me to implement some features in the browser:

He responded with some keywords that I could search on (veux and state) and found how I could access the app's state, which wonderfully allows me to programmatically select cards by pushing card ids into an array! Poking around, here is what I learned:

I can get the Vue state via

1document.querySelector("#app").__vue__.$store.state

There's an array in there that represents what cards are selected called multipleCardsSelectedIds. Finally, I learned that the space information is in currentSpace. So armed with that information, I cobbled to gather some logic to accomplish some of interesting selection functions.

Select direct descendant cards

There's an existing feature where you Opt-Click a card, and all the connected cards get selected. But sometimes, you only want the cards that are directly connected by one level.

Select the parent card in the UI. Then run this function:

 1let selectDirectDescendants = () => {
 2  const vueState = document.querySelector("#app").__vue__.$store.state
 3  const parentCardId = vueState.multipleCardsSelectedIds.pop()
 4  vueState.multipleCardsSelectedIds = []
 5  vueState.multipleCardsSelectedIds = vueState.currentSpace.connections
 6    .filter(c => c.startCardId === parentCardId)
 7    .map(c => c.endCardId)
 8}
 9
10selectDirectDescendants()

select direct descendants

Select cards by filtered connection

Another useful thing to select are cards by their connection. Currently, you can filter by connections, and see them visually focused. But how about then select these cards?

 1let selectByFilteredConnection = () => {
 2  const vueState = document.querySelector("#app").__vue__.$store.state
 3  const connectionId = vueState.filteredConnectionTypeIds.pop()
 4  vueState.filteredConnectionTypeIds = []
 5  const cards = []
 6  vueState.currentSpace.connections
 7    .filter(c => c.connectionTypeId == connectionId)
 8    .forEach(c => {
 9      cards.push(c.startCardId)
10      cards.push(c.endCardId)
11    })
12  vueState.multipleCardsSelectedIds = cards
13}
14
15selectByFilteredConnection()

select by filtered connection

# Next steps