GridDisplay.vue 6.73 KB
Newer Older
Anton's avatar
Intial  
Anton committed
1
2
3
4
<template lang="pug">

  div.cell-grid-container
    div.cell-grid(:style="gridStyle")
5
      style-tag(v-if="styles", :styles="styles")
Anton's avatar
Intial  
Anton committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      template(v-for="(cell, index) in cells")
        .cell-item(
          :style="getCellStyle(cell)",
          :title="cell.title")
            cell(:cell="cell", display="display", :messenger="messenger")

      q-page-sticky(position="top-right", :offset="[18, 18]", v-if="$store.state.auth.user")
        q-btn(round, color="primary", small, @click="$router.push(`/mosys/grids/${$route.params.id}/annotate`)")
          q-icon(name="edit")

</template>

<script>
  import Vue from 'vue'
  import Cell from './Cell'
21
  import StyleTag from '../../shared/partials/StyleTag'
Anton's avatar
Intial  
Anton committed
22
23
24
25
26

  const MessengerComponent = Vue.component('grid-editor-messenger', {})

  export default {
    components: {
27
28
      Cell,
      StyleTag
Anton's avatar
Intial  
Anton committed
29
30
31
32
33
34
35
36
    },
    props: ['gridUuid'],
    data () {
      return {
        grid: undefined,
        annotations: [],
        cells: [],
        gridMetadata: {},
Anton's avatar
Anton committed
37
        gridDimensions: { gridWidth: 0, gridHeight: 0, cellWidth: 0, cellHeight: 0 },
Anton's avatar
Intial  
Anton committed
38
        gridStyle: {},
39
40
        messenger: new MessengerComponent(),
        styles: undefined
Anton's avatar
Intial  
Anton committed
41
42
43
44
45
46
47
48
49
50
51
      }
    },
    async mounted () {
      window.addEventListener('resize', this.updateGridDimensions)
      // this.messenger.$on('video-loaded', (/* origin */) => {
      //   // console.log('video loaded', origin.origin)
      // })
      // this.messenger.$on('video-time-changed', (/* time, globalTime, origin */) => {
      //   // console.log(videoUuid, time)
      // })
      this.grid = await this.$store.dispatch('maps/get', this.$route.params.id)
52
53
54
      if (this.grid.stylesheet && this.grid.stylesheet.value) {
        this.styles = [this.grid.stylesheet.value]
      }
Anton's avatar
Intial  
Anton committed
55
56
      await this.fetchMetadataAnnotations()
      this.updateGridDimensions()
57
      await this.fetchCellAnnotations()
Anton's avatar
Intial  
Anton committed
58
59
    },
    methods: {
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
      async fetchCellAnnotations () {
        const query = {
          'body.type': '2DCell',
          'target.id': this.grid.id
        }
        const annotations = await this.$store.dispatch('annotations/find', query)
        if (!annotations || !Array.isArray(annotations.items)) return
        const cells = []
        for (let annotation of annotations.items) {
          let cell
          try {
            cell = JSON.parse(annotation.body.value)
          }
          catch (e) {
            console.debug('Failed to parse cell annotation body', e)
          }
          if (cell) {
            cell.uuid = annotation.uuid
            cell.id = annotation.id
79
            cell.styleClass = annotation.target ? annotation.target.styleClass : undefined
80
81
82
83
84
            cells.push(cell)
          }
        }
        this.annotations = annotations.items
        this.cells = cells
Anton's avatar
Intial  
Anton committed
85
86
87
88
89
90
      },
      async fetchMetadataAnnotations () {
        const query = { 'body.type': '2DGridMetadata', 'target.id': this.grid.id }
        const annotations = await this.$store.dispatch('annotations/find', query)
        let annotation = annotations.items.shift()
        if (annotation) {
91
92
93
94
95
96
97
          let metadata
          try {
            metadata = JSON.parse(annotation.body.value)
          }
          catch (e) {
            console.debug('Failed to parse grid metadata annotation body', e)
          }
Anton's avatar
Intial  
Anton committed
98
          if (metadata) {
99
100
            metadata.uuid = annotation.uuid
            this.gridMetadata = metadata
Anton's avatar
Intial  
Anton committed
101
102
103
          }
        }
        else {
104
          this.gridMetadata = {
Anton's avatar
Intial  
Anton committed
105
106
107
108
            columns: 10,
            rows: 6,
            ratio: 16 / 9.0
          }
109
          await this.updateGridMetadataStore()
Anton's avatar
Intial  
Anton committed
110
111
112
113
        }
      },
      async updateCellStore (cell) {
        let annotation = this.getGridCellAnnotation(cell)
114
115
        if (cell.uuid) await this.$store.dispatch('annotations/patch', [cell.uuid, annotation])
        else await this.$store.dispatch('annotations/post', annotation)
Anton's avatar
Intial  
Anton committed
116
117
118
119
      },
      async updateGridMetadataStore () {
        let mapAnnotation = this.getGridMetadataAnnotation(this.grid.id, this.gridMetadata)

120
121
        if (this.gridMetadata.uuid) {
          await this.$store.dispatch('annotations/patch', [this.gridMetadata.uuid, mapAnnotation])
Anton's avatar
Intial  
Anton committed
122
        }
123
124
125

        await this.$store.dispatch('annotations/post', mapAnnotation)
        this.updateGridDimensions()
Anton's avatar
Intial  
Anton committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
      },
      updateGridDimensions () {
        let elWidth = this.$el.offsetWidth
        let elHeight = this.$el.offsetHeight
        let cellSizeRatio = this.gridMetadata.ratio
        let gridHeight = elHeight
        let cellHeight = gridHeight / this.gridMetadata.rows
        let cellWidth = elWidth / Math.round(elWidth / (cellHeight * cellSizeRatio))
        let gridWidth = cellWidth * this.gridMetadata.columns
        let cellsPerWidth = elWidth / cellWidth
        let cellWidthMini = elWidth / this.gridMetadata.columns
        let gridHeightMini = cellWidthMini / cellSizeRatio
        this.gridDimensions = {
          full: {
            width: gridWidth,
            height: gridHeight,
            cell: {
              width: cellWidth,
              height: cellHeight
            },
            cells_per_width: cellsPerWidth
          },
          mini: {
            width: elWidth,
            height: gridHeightMini * this.gridMetadata.rows,
            cell: {
              width: cellWidthMini,
              height: gridHeightMini
            }
          }
        }
        if (elWidth > 800) {
          this.gridStyle = {
            width: this.gridDimensions.full.width + 'px',
            height: '100%',
            'grid-auto-columns': this.gridDimensions.full.cell.width + 'px',
            'grid-auto-rows': this.gridDimensions.full.cell.height + 'px'
          }
        }
        else {
          this.gridStyle = {
            width: '100%',
            height: this.gridDimensions.mini.height + 'px',
            'grid-auto-columns': this.gridDimensions.mini.cell.width + 'px',
            'grid-auto-rows': this.gridDimensions.mini.cell.height + 'px'
          }
        }
      },
      getGridMetadataAnnotation (id, metadata) {
        return {
          body: {
            type: '2DGridMetadata',
            purpose: 'linking',
            value: JSON.stringify(metadata)
          },
          target: {
            id,
            type: 'Map'
          }
        }
      },
      getCellStyle (cell) {
188
189
190
191
192
193
        return {
          'grid-column-start': cell.x,
          'grid-column-end': `span ${cell.width}`,
          'grid-row-start': cell.y,
          'grid-row-end': `span ${cell.height}`
        }
Anton's avatar
Intial  
Anton committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
      }
    }
  }
</script>

<style scoped lang="stylus">

  .cell-grid
    display grid

    .cell-item
      position relative
      overflow: hidden
      grid-column-start: 1
      grid-column-end: span 1
      grid-row-start: 1
      grid-row-end: span 1

      .cell-item-inner
        width 100%
        height 100%

</style>