EditPageSectionGeneric.svelte 6.17 KB
Newer Older
1 2 3 4
<script>
  import { insertAndShift } from "../../lib/array.js"
  import deepClone from "../../lib/deepClone.js"
  import { blockOptions, blockTemplates } from "../../../data/pageConstants.js"
5 6 7 8 9 10 11 12 13 14 15 16 17
  import EditField from "./EditField.svelte"
  import DragAndDropZone from "./DragAndDropZone.svelte"
  import DragAndDropItem from "./DragAndDropItem.svelte"
  import EditPageBlockText from "./EditPageBlockText.svelte"
  import EditPageBlockQuote from "./EditPageBlockQuote.svelte"
  import EditPageBlockLink from "./EditPageBlockLink.svelte"
  import EditPageBlockCTA from "./EditPageBlockCTA.svelte"
  import EditPageBlockImage from "./EditPageBlockImage.svelte"
  import EditPageBlockHeading from "./EditPageBlockHeading.svelte"
  import EditPageBlockList from "./EditPageBlockList.svelte"
  import EditPageBlockTable from "./EditPageBlockTable.svelte"
  import EditPageBlockVideo from "./EditPageBlockVideo.svelte"
  import FullScreenWrapper from "../FullScreenWrapper.svelte"
18
  import { onMount } from "svelte"
19 20

  export let data = {
Bård's avatar
Bård committed
21
    title: ""
22 23 24 25 26
  }
  export let blocks = []
  export let newBlockType = "default"
  export let newBlockIndex = false
  export let disableTitle = false
27
  export let _id
28
  export let strings
29
  export let validMandatoryFields
30 31 32 33 34 35 36

  export let orderedSections
  $: {
    orderedSections = blocks.sort((a, b) => a.order - b.order)
  }

  onMount(() => {
Bård's avatar
Bård committed
37 38 39
    _id = Math.random()
      .toString(36)
      .substr(2, 9)
40 41
  })

Bård's avatar
Bård committed
42 43 44 45 46 47 48 49 50
  export function handleReorder(e) {
    const { draggedItem, draggedOverItem } = e.detail

    const reorderedBlocks = insertAndShift(
      blocks,
      draggedItem,
      draggedOverItem
    ).map((section, i) => Object.assign(section, { order: i }))

51
    blocks = reorderedBlocks
52 53 54 55
  }

  export function handleAddNewBlock(event) {
    const blockTemplate = blockTemplates[event.target.value] || {}
Bård's avatar
Bård committed
56 57 58
    const newBlocks = [...blocks, deepClone(blockTemplate)].map((block, i) =>
      Object.assign(block, { order: i })
    )
59

60 61 62
    newBlockType = "default"
    newBlockIndex = newBlocks.length - 1
    blocks = newBlocks
63 64 65
  }

  export function handleDeleteBlock(event) {
66
    const { indexOfItemToDelete } = event.detail
67 68
    const newBlocks = blocks
      .filter((b, i) => i !== indexOfItemToDelete)
Bård's avatar
Bård committed
69 70
      .map((block, i) => Object.assign(block, { order: i }))

71
    blocks = newBlocks
72 73
  }

74 75
  export function setValidProp(event) {
    validMandatoryFields[event.detail.prop] = event.detail.valid
76
    validMandatoryFields = validMandatoryFields
77 78
  }

Bård's avatar
Bård committed
79
  function getBlockDisplayText({ blockType, data }) {
80 81 82 83 84 85 86
    if (blockType === "image") {
      return data.image.altName || ""
    } else if (blockType === "video") {
      return data.videoType
    } else if (blockType === "list") {
      return data.items.reduce((str, item) => `${str} - ${item}`) || ""
    } else if (blockType === "table") {
Bård's avatar
Bård committed
87 88 89 90 91 92
      return (
        data.rows[0].cells.reduce(
          (str, cell) => `${str} - ${cell}`,
          "Tabell"
        ) || ""
      )
93 94 95 96 97 98
    } else {
      return data.text || ""
    }
  }
</script>

Bård's avatar
Bård committed
99
<section>
Bård's avatar
Bård committed
100

101 102
  {#if !disableTitle}
    <EditField
Bård's avatar
Bård committed
103
      strings="{strings.sections.title}"
104
      bind:value="{data.title}"
Bård's avatar
Bård committed
105 106
      required="{true}"
      hideHelpText />
107 108
  {/if}

Bård's avatar
Bård committed
109 110 111
  <div class="block block--top-4">
    <label>Blokker</label>
  </div>
Bård's avatar
Bård committed
112

Bård's avatar
Bård committed
113
  <div class="block block--top-2">
114
    <DragAndDropZone
115
      zone="blocks-{_id}"
116
      on:reorder="{handleReorder}"
Bård's avatar
Bård committed
117
      on:deleteItem="{handleDeleteBlock}">
118
      {#each blocks as block, index (index)}
Bård's avatar
Bård committed
119 120 121 122 123 124 125 126
        <DragAndDropItem
          order="{index}"
          zone="blocks-{_id}"
          isNested
          expandedByDefault="{index === newBlockIndex}">
          <span slot="label">{blockOptions[block.blockType]}</span>
          <span slot="title">{getBlockDisplayText(block)}</span>
          <span slot="content">
Bård's avatar
Bård committed
127
            {#if block.blockType === "text"}
Bård's avatar
Bård committed
128 129 130
              <EditPageBlockText
                bind:data="{block.data}"
                strings="{strings.blocks}" />
131
            {/if}
Bård's avatar
Bård committed
132
            {#if block.blockType === "quote"}
Bård's avatar
Bård committed
133 134 135
              <EditPageBlockQuote
                bind:data="{block.data}"
                strings="{strings.blocks}" />
136
            {/if}
Bård's avatar
Bård committed
137
            {#if block.blockType === "link"}
Bård's avatar
Bård committed
138 139 140
              <EditPageBlockLink
                bind:data="{block.data}"
                strings="{strings.blocks}" />
141
            {/if}
Bård's avatar
Bård committed
142
            {#if block.blockType === "cta"}
Bård's avatar
Bård committed
143 144 145
              <EditPageBlockCTA
                bind:data="{block.data}"
                strings="{strings.blocks}" />
Bård's avatar
Bård committed
146
            {/if}
Bård's avatar
Bård committed
147
            {#if block.blockType === "image"}
Bård's avatar
Bård committed
148 149 150
              <EditPageBlockImage
                bind:data="{block.data}"
                strings="{strings.blocks}" />
151
            {/if}
Bård's avatar
Bård committed
152
            {#if block.blockType === "heading"}
Bård's avatar
Bård committed
153 154 155
              <EditPageBlockHeading
                bind:data="{block.data}"
                strings="{strings.blocks}" />
156
            {/if}
Bård's avatar
Bård committed
157
            {#if block.blockType === "list"}
Bård's avatar
Bård committed
158 159 160
              <EditPageBlockList
                bind:data="{block.data}"
                strings="{strings.blocks}" />
Bård's avatar
Bård committed
161
            {/if}
Bård's avatar
Bård committed
162
            {#if block.blockType === "video"}
Bård's avatar
Bård committed
163 164 165
              <EditPageBlockVideo
                bind:data="{block.data}"
                strings="{strings.blocks}" />
Bård's avatar
Bård committed
166
            {/if}
Bård's avatar
Bård committed
167
            {#if block.blockType === "table"}
Bård's avatar
Bård committed
168 169 170 171 172
              <FullScreenWrapper>
                <EditPageBlockTable
                  bind:data="{block.data}"
                  strings="{strings.blocks}" />
              </FullScreenWrapper>
173
            {/if}
Bård's avatar
Bård committed
174 175 176
          </span>
          <span slot="deleteLabel">Slett blokk</span>
        </DragAndDropItem>
Bård's avatar
Bård committed
177 178 179
      {/each}
    </DragAndDropZone>
  </div>
Bård's avatar
Bård committed
180

Bård's avatar
Bård committed
181 182 183 184
  <div class="block block--top-4">
    <div class="select">
      <div class="select__arrow">
        <div class="icon">
Bård's avatar
Bård committed
185 186 187
          <svg width="24" height="24" class="icon">
            <use href="/icons.svg#arrow-down"></use>
          </svg>
Bård's avatar
Bård committed
188 189
        </div>
      </div>
Bård's avatar
Bård committed
190 191 192 193 194 195 196 197
      <select
        class="select__field"
        bind:value="{newBlockType}"
        on:change="{handleAddNewBlock}">
        <option value="default">Legg til ny blokk</option>
        {#each Object.entries(blockOptions) as [key, value]}
          <option value="{key}">{value}</option>
        {/each}
Bård's avatar
Bård committed
198 199 200
      </select>
    </div>
  </div>
Bård's avatar
Bård committed
201

Bård's avatar
Bård committed
202
</section>