## Spec for PageSections Package

A feature that lets users edit their pages faster

By presenting dozens of pre-built page sections, the user does not need to pre-build their pages from scratch.

Instead they can build their pages from a collection of pre-assembled starting points.

Templates are too cookie cutter, but sections provide the simplicity & speed of templates, with the flexibility and customization of components

## Table of Contents

- [Spec for PageSections Package](#spec-for-pagesections-package)
- [Table of Contents](#table-of-contents)
- [Workflow](#workflow)
- [User Stories](#user-stories)
- [Test Plan](#test-plan)
- [Acceptance Tests](#acceptance-tests)
- [Screens / States](#screens--states)
- [Components](#components)
  - [Layouts](#layouts)
  - [Containers](#containers)
  - [Components](#components-1)
- [Schema](#schema)
  - [Component Schema](#component-schema)
    - [SectionEditorWidget](#sectioneditorwidget)
      - [Schema](#schema-1)
      - [Tests](#tests)
    - [LiveSection](#livesection)
      - [Schema](#schema-2)
      - [Tests](#tests-1)
    - [EditorSection](#editorsection)
      - [Schema](#schema-3)
      - [Tests](#tests-2)
    - [SectionsLegend](#sectionslegend)
      - [Schema](#schema-4)
      - [Tests](#tests-3)
    - [SectionItem](#sectionitem)
      - [Schema](#schema-5)
      - [Tests](#tests-4)
    - [AddSectionsTab](#addsectionstab)
      - [Schema](#schema-6)
      - [Tests](#tests-5)
    - [SectionPreview](#sectionpreview)
      - [Schema](#schema-7)
      - [Tests](#tests-6)
  - [Database Schema](#database-schema)
  - [Store/Reducers](#storereducers)
  - [APIs/Hook Schema](#apishook-schema)

## Workflow

![]()

## User Stories

- As a user, I want to easily create an entire page quickly by selecting pre-built page sections or page "blocks" and drag it over to a page I'm working on.
- As a user, I would like the ability to create a block from scratch
- As a user, I would like to be able to see an indication of what section my objects are a part of as I hover over them
- As a user, I would like to see an outline/overview of the different sections that make up my page
- As a user, I would like ways to easily re-order my page sections
- As a user, I only want to move page sections up and down, not nest them inside of other page blocks/items
- As a user, I would like to be able to preview page blocks before committing to my selection
- As a user, I would like to be able to search/filter the list of sections you have available
- As a user, I would like the section to highlight if one of the child objects is activated or hovered over

## Test Plan

| Scenario  | Expected                                                                                                                                        | Automated | Type       |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ---------- |
| Rendering | Should show a new tab in the Add New Item drawer                                                                                                | Yes       | End to End |
| Rendering | Should render a list of sections according to an onListItems plugin definition                                                                  | Yes       | End to End |
| Rendering | Should show the <SectionsLegend /> component in the main canvas                                                                                 | Yes       | End to End |
| Rendering | Don't show the <SectionsLegend /> component on the canvas if there aren't any sections present on the page                                      | Yes       | End to End |
| Rendering | Don't show the <SectionsLegend /> component on the canvas if in FULL SCREEN view (or preview)                                                   | Yes       | End to End |
| Rendering | Should show the <AddSectionsTab /> as a new component in the Item Drawer                                                                        | Yes       | End to End |
| Actions   | Should highlight the associated canvas item is highlighted when section item is hovered over                                                    | Yes       | End to End |
| Actions   | Should activate the associated cavas editor item is selected when section item is active                                                        | Yes       | End to End |
| Actions   | Should be able to drag/drop a new section on to the page (from the add new item drawer)                                                         | Yes       | End to End |
| Actions   | Should be able to re-order a section on the page by dragging up and down                                                                        | Yes       | End to End |
| Actions   | Should NOT be able to drag an object so that it's nested inside another container or adjacent to another component that is not a section itself | Yes       | End to End |

## Acceptance Tests

(N/A)

## Screens / States

![](http://ambid-backups.s3.amazonaws.com/screenshots/sandcastle/components_blocks_editor_simpler.png)
![](http://ambid-backups.s3.amazonaws.com/screenshots/sandcastle/components_blocks_add.png)

## Components

### Layouts

N/A

### Containers

N/A

### Components

N/A

## Schema

### Component Schema

#### SectionEditorWidget

##### Schema

N/A

##### Tests

| It                                                                                                       | Type        |
| -------------------------------------------------------------------------------------------------------- | ----------- |
| Should show in the add new item drawer (Plugin hook is called)                                           | Integration |
| Should show in editor when page content has a section as its type (plugin hook is called)                | Integration |
| Should show up in the live page when thge page content has a section as its type (plugin hook is called) | Integration |

#### LiveSection

##### Schema

| Name       | Type                | Description | Schema Type |
| ---------- | ------------------- | ----------- | ----------- |
| mode       | EditorMode          |             | prop        |
| children   | React.ReactNode     |             | prop        |
| style      | React.CSSProperties |             | prop        |
| properties | React.CSSProperties |             | prop        |

##### Tests

| It                                                                      |
| ----------------------------------------------------------------------- |
| Should render in the dom                                                |
| Should render an inner width according to the "width" property settings |
| Should render background properly as provided by the property settings  |
| Should render padding according to the property settings if provided    |

#### EditorSection

##### Schema

N/A

##### Tests

| It                                                                                                                                                                     | Type        |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| Should render in the dom                                                                                                                                               | Integration |
| Should render an inner width according to the "width" property settings                                                                                                | Integration |
| Should render background properly as provided by the property settings                                                                                                 | Integration |
| Should render padding according to the property settings if provided                                                                                                   | Integration |
| Should render a thicker border on the EditorObject component container                                                                                                 | Integration |
| Should render an "Move Section Up" and a "Move Section Down" option the Editor Object drop down menu                                                                   | Integration |
| Should reposition the section in the page content array appropriately when the "Move up" or "Move down" button is clicked (e.g should trigger updateComponentSettings) | Integration |

#### SectionsLegend

##### Schema

| Name           | Type                                 | Description                                                                                                                                                             | Schema Type |
| -------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| title          | string                               | The caption that shows at the top of the section legend                                                                                                                 | prop        |
| sections       | SectionItemProps[]                   | An array of section item settings. Used to generate a list of sections. This is usually derived from the page content data                                              | prop        |
| onChange       | (sections:SectionItemProps[]) => any | Triggers when the user initiates a change of some kind to the sections in the section item (such as drag-and-drop to re-order). Returns an updated list of section item | prop        |
| onCreate       | () => void                           | Triggers when the user clicks the [Add Section] button                                                                                                                  | prop        |
| showHideToggle | () => void                           | Shows or Hides the <SectionLegend /> component                                                                                                                          | method      |

##### Tests

| It                                                                                                                                             | Type        |
| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| Rendering > Should render in the dom                                                                                                           | Integration |
| Rendering > Should show a title in the dom that matches the title string passed in the prosp                                                   | Integration |
| Rendering > Should show a list of <SectionItem /> elements...the amount should match the number of sections passed in the sections array       | Integration |
| Event > Should trigger the onChange event when the sections are re-ordered via drag-and-drop                                                   | Integration |
| Methods > Should return an updated list of settings from the onChange event return function when the sections are re-ordered via drag and drop | Integration |

#### SectionItem

##### Schema

| Name          | Type         | Description                                                                | Schema Type |
| ------------- | ------------ | -------------------------------------------------------------------------- | ----------- |
| label         | string       | The text to display in the section item                                    | prop        |
| type          | SectionTypes | They type of section you are representing. Used to display a relevant icon | prop        |
| settings      | any          | The specific section settings derived from the page content                | prop        |
| onClick       | () => any    | Triggers when the user clicks on the section item                          | prop        |
| onMouseEnter  | () => any    | Triggers when the users mouse enters the section item                      | prop        |
| onMouseLeave  | () => any    | Triggers when the user's mouse leaves the section item                     | prop        |
| onDoubleClick | () => any    | Triggers when the user double-clicks on the section item                   | prop        |

##### Tests

| It                                                                                                                      | Type        |
| ----------------------------------------------------------------------------------------------------------------------- | ----------- |
| Should render in the dom                                                                                                | Integration |
| Show render the component in a state (hovered, normal, active) that matches the state passed along in the settings prop | Integration |
| Should display an icon based on the section type                                                                        | Integration |
| Should show a label that represents the text provided in the label prop                                                 | Integration |
| Should trigger the onClick event when it is clicked on                                                                  | Integration |
| Should trigger the onMouseEnter event when the user double-clicks on the section item                                   | Integration |
| Should trigger the onMouseLeave event when the user's mouse leaves the section item                                     | Integration |
| Should trigger the onDoubleClick event when it is double-clicked on                                                     | Integration |

#### AddSectionsTab

##### Schema

| Name         | Type                                   | Description                                                                                               | Schema Type |
| ------------ | -------------------------------------- | --------------------------------------------------------------------------------------------------------- | ----------- |
| sections     | SectionPreviewProps[]                  | An array of section preview items to display                                                              | prop        |
| categories   | string[]                               | A list of categories that the user can quickly choose from to filter the section previews being displayed | prop        |
| onAddSection | (section: SectionPreviewProps) => void | Triggered when the [add to page] button on one of the section previews are clicked                        | prop        |

##### Tests

| It                                                                                                                                                  | Type        |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| Rendering > Should render in the dom                                                                                                                | Integration |
| Rendering > Should show a list of section previews, the number of previews shown should match the number of sections provided in the sections array | Integration |
| Rendering > Should show a list of categories (as determined by the category array in the props) that the user can filter through                    | Integration |
| Events > Should trigger the onAddSection event when one of the section preview [add to page] buttons are clicked                                    | Integration |
| Methods > Should filter the list of layouts being displayed when a category chip is toggled                                                         | Integration |
| Methods > Should filter the list of layouts being displayed when the search text field is typed in                                                  | Integration |

#### SectionPreview

##### Schema

| Name                 | Type                        | Description                                                                                                                  | Schema Type |
| -------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------- |
| label                | string                      | The label to show on the section preview object. Usually it's the name of the section                                        | prop        |
| layout               | LayoutType                  | The name of the layout being used. This is used to look up and auto-generate the preview if possible                         | prop        |
| previewImage         | string                      | Overrides the auto-generated preview image with this image                                                                   | prop        |
| onAddSection         | (layout:LayoutType) => void | Triggers when the [add to page] button is clicked                                                                            | prop        |
| handlePreviewSection | () => void                  | Triggers when the [preview] button is clicked. Will show a popup window with a larger view of the section that will be added | method      |

##### Tests

| It                                                                                                                            | Type        |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------- |
| Rendering > Should render in the dom                                                                                          | Integration |
| Rendering > Should auto generate an image based on the LayoutType passed in the props                                         | Integration |
| Rendering > Should show the previewImage (instead of the auto-generated image) when one is provided in the previewImage props | Integration |
| Events > Should trigger the onAddSection event when the [add to page] button is clicked                                       | Integration |
| Events > Should receive the LayoutType when the onAddSection event is triggered                                               | Integration |
| Methods > Should show a popup window with the actual layout displaying when the [preview] button is clicked                   | Integration |

### Database Schema

### Store/Reducers

### APIs/Hook Schema
