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

Add support for Subblocks #26

Open
prakhar1989 opened this issue Jun 22, 2015 · 3 comments
Open

Add support for Subblocks #26

prakhar1989 opened this issue Jun 22, 2015 · 3 comments
Labels

Comments

@prakhar1989
Copy link
Owner

Schemata - https://github.com/SurveyMan/Schemata/blob/gh-pages/survey_block.json. Subblocks can be nested arbitrarily.

@prakhar1989
Copy link
Owner Author

Approach

As per the underlying Flux philosophy, the SurveyStore is the one source of truth for all data. It is responsible for maintaining its state and carrying out all mutations as dictated by the order of Actions that are dispatched to it.

All data in the store is in the form of Immutable.js Maps which means that we need to use the API that the Map interface exposes in order to efficiently query and mutate the data. To this end, there are 3 main methods using which data is mutated - setIn, updateIn and deleteIn. These methods provide an easy way to make deep persistent changes.

The API for these functions looks like this -

Map.setIn([.. array of indices], value)
Map.updateIn([... array of indices], (value) => newValue)
Map.deleteIn([... array of indices])

In order to construct these arrays, the SurveyStore has it's own suite of helper functions. These helper functions relied on the assumption that blocks are top-level and questions are the immediate children for the block. For example

getQuestionIndex(questionId, block) {  
   return block.get('questions').findIndex(q => q.get('id') === questionId);
},

Challenge

The challenge now is to rewrite these helpers (& and its calling functions) making no such assumptions of the structure i.e. blocks, questions & options can be nested arbitrarily. Ideally, the signatures of these functions can be like so -

/**
* Returns an array of indices that can be directly go in first arguments to Immutable deep persistent functions.
* @param blockId - id of the block who's index is required
* @param parentBlock (optional) - The parent block at which to begin the search. If left out, the search starts from the top of the survey
*/
function getBlockIndex(blockId, parentBlock = 'top') {
  // recursively build the array
}

These functions can then be used like so -

// when adding a new block
let newSurvey = survey.updateIn(this.getBlockIndex(blockId), list =>
   list.splice(0, 0, newBlock)
);

// when deleting a block
let newSurvey = survey.deleteIn(this.getBlockIndex(blockId));

// when toggling params
let newSurvey = survey.updateIn(this.getBlockIndex(blockId), b => 
   b.set(toggleName, !b.get(toggleName))
);

Similar functions for Questions & Options can be written which expose the same API.

Todo

List of tasks required to complete this feature

  • Rewrite getBlockIndex to handle nested survey (called getBlockPath)
  • Rewrite getQuestionIndex to handle nested survey (called getQuestionPath)
  • Refactor the following to use these new functions
    • Block add
    • Block delete
    • Block toggle param
    • Question add
    • Question edit
    • Question delete
    • Question toggle param
    • Option add
    • Option delete
    • Block / Subblock / Question Cloning

prakhar1989 added a commit that referenced this issue Jul 5, 2015
prakhar1989 added a commit that referenced this issue Jul 10, 2015
@prakhar1989
Copy link
Owner Author

@etosch - The last part pending in this feature is the ability to allow items to be dragged and dropped on subblocks. I wanted to quickly clarify on what all kinds of interactions should I work on. I have started with an example below -

  • Questions inside subblocks should be draggable (outside the block) and droppable (inside the block).

A counter example might be that subblocks might not be required to be re-orderable inside a Block. Basically, this is to finalize what all functionality is required in the minimap as far as subblocks are concerned.

@etosch
Copy link
Contributor

etosch commented Jul 15, 2015

  1. Yes, definitely make questions draggable from their blocks to other blocks (top-level or sub). Reordering questions inside a block should have no effect (since they are randomized).
  2. Perhaps have some way to freeze blocks (both top-level and sub). Sub blocks can float, and it follows from the randomization-first philosophy that we should assume they are floating by default. If someone "freezes" a block, it should be in relation to other blocks within that block's parent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants