Code Monkey home page Code Monkey logo

Comments (3)

prakhar1989 avatar prakhar1989 commented on July 20, 2024

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

from react-surveyman.

prakhar1989 avatar prakhar1989 commented on July 20, 2024

@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.

from react-surveyman.

etosch avatar etosch commented on July 20, 2024
  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.

from react-surveyman.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.