All files / src/store/features/entities/reducers notesReducers.ts

50% Statements 16/32
0% Branches 0/3
0% Functions 0/6
50% Lines 16/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122          46x   46x         46x 46x 46x   46x 46x 46x 46x                 46x                                     46x                                                     46x                 46x                   46x               46x                                     46x  
import {
  PayloadAction,
  CaseReducer,
  SliceCaseReducers,
} from "@reduxjs/toolkit";
import uuid from "uuid";
import { EntitiesState } from "shared/lib/entities/entitiesTypes";
import {
  defaultLocalisedNoteName,
  applyReparentEntityToCollection,
} from "shared/lib/entities/entitiesHelpers";
import { Note } from "shared/lib/resources/types";
import { notesAdapter } from "store/features/entities/adapters";
import { localNoteSelectTotal } from "store/features/entities/helpers";
import { MIN_WORLD_ENTITY_X, MIN_WORLD_ENTITY_Y } from "consts";
 
const MIN_NOTE_WIDTH = 20;
const MIN_NOTE_HEIGHT = 3;
const DEFAULT_NOTE_WIDTH = 20;
const DEFAULT_NOTE_HEIGHT = 15;
 
const addNote: CaseReducer<
  EntitiesState,
  PayloadAction<{
    noteId: string;
    x: number;
    y: number;
  }>
> = (state, action) => {
  const notesTotal = localNoteSelectTotal(state);
 
  const newNote: Note = {
    name: defaultLocalisedNoteName(notesTotal),
    id: action.payload.noteId,
    x: Math.max(MIN_WORLD_ENTITY_X, action.payload.x),
    y: Math.max(MIN_WORLD_ENTITY_Y, action.payload.y),
    width: DEFAULT_NOTE_WIDTH,
    height: DEFAULT_NOTE_HEIGHT,
    content: "",
  };
 
  notesAdapter.addOne(state.notes, newNote);
};
 
const editNote: CaseReducer<
  EntitiesState,
  PayloadAction<{ noteId: string; changes: Partial<Note> }>
> = (state, action) => {
  const note = state.notes.entities[action.payload.noteId];
  const patch = { ...action.payload.changes };
 
  Iif (!note) {
    return;
  }
 
  Iif (patch.width !== undefined) {
    patch.width = Math.max(MIN_NOTE_WIDTH, patch.width);
  }
 
  Iif (patch.height !== undefined) {
    patch.height = Math.max(MIN_NOTE_HEIGHT, patch.height);
  }
 
  notesAdapter.updateOne(state.notes, {
    id: action.payload.noteId,
    changes: patch,
  });
};
 
const removeNote: CaseReducer<
  EntitiesState,
  PayloadAction<{
    noteId: string;
  }>
> = (state, action) => {
  notesAdapter.removeOne(state.notes, action.payload.noteId);
};
 
const removeNotes: CaseReducer<
  EntitiesState,
  PayloadAction<{
    noteIds: string[];
  }>
> = (state, action) => {
  notesAdapter.removeMany(state.notes, action.payload.noteIds);
};
 
const reparentNote: CaseReducer<
  EntitiesState,
  PayloadAction<{
    noteId: string;
    toPath: string;
  }>
> = (state, action) => {
  applyReparentEntityToCollection(
    state.notes.entities,
    action.payload.noteId,
    action.payload.toPath,
  );
};
 
const notesReducers = {
  addNote: {
    reducer: addNote,
    prepare: (payload: { x: number; y: number }) => {
      return {
        payload: {
          ...payload,
          noteId: uuid(),
        },
      };
    },
  },
 
  editNote,
  removeNote,
  removeNotes,
  reparentNote,
} satisfies SliceCaseReducers<EntitiesState>;
 
export default notesReducers;