CivicTechFredericton / mealplanner

Primary Meal Planner repo
MIT License
9 stars 18 forks source link

Mealplanner v2 #250

Open shanthisa opened 2 years ago

shanthisa commented 2 years ago

Upgrade relay to the latest version.

We are using an older version of Relay and the deprecated component style for query renderers, fragment containers and refetch containers. The latest version of relay uses hooks and is better suited with the latest version of React with support for Suspense and Concurrent fetching.

We need to upgrade to the latest version of Relay to suppor the subsequent story to implement local state with Relay.

Implement local state with relay

When using relay, it is beneficial to stuff local state also into Relay. This allows us to reuse the local state in multiple fragments without having to rely on props drilling as we are currently doing in the code base. This is also better than using a state framework like Redux as we can use Relay as a single source of truth. The components can mix server state and client state and can seamlessly respond when the data behind these components change.

New features:

  1. Drag and drop is replaced with select and click
  2. Search of meals while constructing meal plan is provided.
  3. While multiple select of meals is implemented we need to implementing cancelling the selection (deselect).
  4. While searching, whichever meal plan is already selected should remain visible and provide the list based on the search criteria.

Tech impact

List of changes🤘

Upgrading Relay as we are going to use hooks such as PreLoadedQuery as the version 9.1.0 used in the current code doesn’t support.

  1. DashBoard
    1. Dashboard component will be simplifed by extracting them as different components
      1. QueryRenderer and Refetch container becomes PreloadedQuery in Dashboard component.
      2. The people filter menu will be its own component with its associated fragment.
      3. DeleteDialog - use @deleteEdge on the commit mutation to automatically drop the edge and avoid a refetch.
    2. Extract selected person into its own local state. (Implementing state using Relay - commitLocalUpdate and seperate graphQL file for state extending the Query type.)
    3. If and when pagination is implemented this client side filter will break i.e. if the record is not present for that user in the first page, but in the subsequent pages, it will show as no records found. So we need to use the condition in graphQL and refetch when the peoplefilter changes.
  2. Mealplan page
    1. Create Plan option: a better name would be meal selector.
      1. create plan options - currently lists all meal plans together. Need to implement pagination
      2. When the list grows, it will be difficult to scroll through. Search would need to be implemented
      3. edges → node is not required. Instead just nodes is sufficient. This would reduce one .map function in CreatePlanOptions.
      4. CreateMealOptions defaultProps - remove the onSelectMeals and implement localState.
    2. Meal option - drag and drop requires a long way to drag and drop. As of now can only drag and drop one item at a time. A better approach is to tap to select multiple items and click to drop.
    3. MealplansToolbar - Currently the problem is when the meal plan is created, the mealplan toolbar is not updated. This can be implemented in the new / duplicate mutations using the @prependEdge and @appendEdge to automatically add the record to the combo box. We can also use @refetchable directives to places where the data requires additional fields.
    4. MealplansToolbar - It unnecessarily queries all the fields on the meal plan while it displays only the meal plan name and the user name. So query needs to be modified to include only the meal plan name and username.
    5. CreatePlanTable - should contain the meal plan entry details for the current meal plan. As of now that part of the query fragment is in MealplansToolbar.
    6. Create a type for global state to include isCreateMPModalOpen, isDuplicateMPModalOpen, createMPConfig, duplicateMPConfig instead of using local state such as newModalOpen and selectedPlan controlled by the toolbar so that eventually we avoid prop drilling. Remove unnecessary states such as alreadySelectedMealAfterNav.
    7. New, Duplicate, Save is as 3 different buttons in the current release. This can all be combined to one. There can be just one modal which gives the option for the new meal plan which offers existing meal plan as template option and the other as from scratch. We can save as an when the meal is getting dropped instead of having a seperate save button.
    8. MealplansToolbar - We will use the mealplan ID in the url and avoid using useLocation and useEffect. Instead we can use useParams.
    9. MealPlanAssignment - This assigns users. mutation will move from PlanPage to MealPlanAssignment and eliminating the need of a save button or props drilling. This will also read from the global state.
    10. Duplicate meal plan is going part of new meal plan itself as an option to select mealplan from a template rather than a seperate button.
    11. The mutation of NewMealPlanModal is containing mealplan entries which is not available in a new mealplan. We need not query for it. NewMealPlanModal is in MealplanToolbar, but it should be in PlanPage.
    12. In Delete functionality as of now I am doing relay.refetch(). This can be avoided with @deleteEdge with connections.
    13. createMealPlanEntry is creating an array of promises and making so many network calls in a single SAVE button click. However we can push those entries to the database as and when it is created. This would eliminate requirement for mealEntryAlreadyExists, mealEntryHasBeenRemoved.
    14. As of now updateAssignment, doDeleteMealPlanEntry, doCreateMealPlanEntry is implemented as different promises and tracked in different states. Instead we can have the actions done right away.
    15. As of now, mealsAtTimes is dealt like a matrix of day and category and hence is passed on to CreateNewMealPlan from PlanPage on save. But this can be sorted in the backend and brought in the view page avoiding bugs created by handling localstate of mealsAtTimes. This removes putMealsAtTime, removeMealsAtTime.
    16. onMealDropped and onMealSelect should have been inside MealTableCell component instead of creating outside and passing on as props. However instead of drag and drop, click at source and then click at the destination would be easier for touch screens and people with accessibility issues. So these functions would not be required. We will create a global state for any meal selected (mealSelected) and while a table cell is clicked on, we will check whether the mealSelected property has a value and create a meal plan entry accordingly.
    17. MealTime is called from CreateMealPlanTable to drop the target. Since we are not going to use drag and drop, we would modify this to access the global state of meal when mealtime component is clicked.
  3. Catalog page. We would refactor layout to its component and accept props.children and merge catalogue and catalogueGridList into the same component.
    1. Use useQuery hook instead of QueryRenderer component in catalogue (QueryRenderer is in catalogueGridList).
  4. When a infoIcon is clicked in the Catalogue page, it opens the link /meal/id This link renders the DisplayMeal component reading the route from App.jsx. In DisplayMeal use useQuery hook instead of QueryRenderer.
  5. In ShoppingList also use useQuery hook instead of QueryRenderer.
shanthisa commented 2 years ago
shanthisa commented 2 years ago

ENUM - Convert Category ENUM to text so that we can allow Beverages or any future requirement. Also it will be useful for localisation Units - Add units table and make measures refer to unit. This will enable supporting unit conversion later. If we ship it with text then introducing specific units will become difficult

shanthisa commented 2 years ago

After selecting meals, the cell in the table on hover should change to a different color. Also the mouse should show a different pointer The delete button should be in the same line as the meal. Only on hover, or on focus only, the delete button should appear next to the meal. By default it should be hidden The background colours of the meals and meal button should be inversed.

shanthisa commented 2 years ago

Pending work:

Admin UI:

Products

Measure

Users

Nutrition

mealplanner-ui:

Mealplans:

Individual Mealplan page:

Meals page

Meals details page