Creating a New Layer in Frontend

This document gives guidelines on how to implement a new layer in the frontend.

Folder Structure

  • Navigate to the layers directory in your project (features/map_planning/layers).
  • Create a new folder named after the type of layer you want to add (e.g., new_layer).

Add Necessary Files and Folders

  • Inside the "newLayer" folder:
    • If your layer requires API interactions, create an api folder and place your .ts files in there or place them into the map_planning api folder depending on whether it's a special api that is part of the layer or it's just for initiating the layer in general.
    • For React components or custom hooks specific to this layer, add a components or hooks folder.
    • Create a main TypeScript file for the layer (e.g., NewLayer.tsx).
    • Inside components create a NewLayerLeftToolbar.tsx and a NewLayerRightToolbar.tsx.
    • Inside the newLayer folder create a file actions.ts.

Define the Layer Component

  • In NewLayer.tsx:
    • Import Konva and other dependencies.
    • Define a functional component that returns a Konva Layer.
  • In mapEditorHookApi.ts:
    • Define a hook for your layer (e.g., useNewLayer.tsx).
    • Add states (see next section) that need to be saved across components.
    • Add an init function (e.g., initNewLayer) which is then defined inside the TrackedMapStore.ts.

Implement Layer Logic

  • Use hooks (starting with use in the name) and the global MapStore (tracked & untracked) to manage state and interactions.
  • Ensure proper interaction with other layers and elements.
  • In EditorMap.getToolbarContent replace the empty divs for left and right with the toolbars for your layer.
  • The NewLayerLeftToolbar.tsx should be used for manipulating attributes of the selected element in the map.
  • The NewLayerRightToolbar.tsx should be used to select elements to be placed/drawn on the map.
  • For selecting an element to be placed add a function to UntrackedMapStore.ts and a state to MapStoreTypes.ts.
  • For placing an element on the map create a class for creating the element inside actions.ts.
    • This has to be done for every (tracked) action the user can take like deleting, moving and so on.
    • In every action the following functions are needed:
      • entityIds: entity ids that are affected by this action
      • execute: commits the changes over the api
      • reverse: undoes the action
      • apply: applies the given tracked state
  • Use the actions within NewLayer.tsx in listeners or hooks.

Test Your Layer

  • Write tests for hooks (in the same folder as hooks) if feasible/useful (see plant/hooks) to verify functionality.
    • Especially if side effects or wrong behaviour can not be easily seen in manual tests!