@abi-software/gallery 0.2.2 → 0.3.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jest.config.js CHANGED
@@ -1,3 +1,3 @@
1
- module.exports = {
2
- preset: '@vue/cli-plugin-unit-jest',
3
- }
1
+ module.exports = {
2
+ preset: '@vue/cli-plugin-unit-jest',
3
+ }
package/package.json CHANGED
@@ -1,41 +1,42 @@
1
- {
2
- "name": "@abi-software/gallery",
3
- "version": "0.2.2",
4
- "repository": {
5
- "type": "git",
6
- "url": "https://github.com/hsorby/mapcore-gallery.git"
7
- },
8
- "license": "Apache-2.0",
9
- "private": false,
10
- "scripts": {
11
- "serve-no-lint": "vue-cli-service serve --skip-plugins @vue/cli-plugin-eslint",
12
- "build-dist": "vue-cli-service build",
13
- "serve": "vue-cli-service serve",
14
- "build": "vue-cli-service build",
15
- "test:unit": "vue-cli-service test:unit",
16
- "build-bundle": "vue-cli-service build --target lib --name gallery src/main-bundle.js --skip-plugins @vue/cli-plugin-eslint",
17
- "lint": "vue-cli-service lint"
18
- },
19
- "main": "dist/gallery.common.js",
20
- "dependencies": {
21
- "@babel/code-frame": "^7.12.11",
22
- "core-js": "^3.8.3",
23
- "element-ui": "^2.15.0",
24
- "vue": "^2.6.11"
25
- },
26
- "devDependencies": {
27
- "@vue/cli-plugin-babel": "^4.5.11",
28
- "@vue/cli-plugin-eslint": "^3.1.1",
29
- "@vue/cli-plugin-unit-jest": "^4.5.13",
30
- "@vue/cli-service": "^4.5.13",
31
- "@vue/eslint-config-prettier": "^6.0.0",
32
- "@vue/test-utils": "^1.1.2",
33
- "babel-eslint": "^10.1.0",
34
- "eslint": "^6.0.0",
35
- "eslint-config-prettier": "^6.15.0",
36
- "eslint-plugin-prettier": "^3.3.1",
37
- "eslint-plugin-vue": "^6.2.2",
38
- "prettier": "^2.2.1",
39
- "vue-template-compiler": "^2.6.11"
40
- }
41
- }
1
+ {
2
+ "name": "@abi-software/gallery",
3
+ "version": "0.3.0-beta.2",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/hsorby/mapcore-gallery.git"
7
+ },
8
+ "license": "Apache-2.0",
9
+ "private": false,
10
+ "scripts": {
11
+ "serve": "vue-cli-service serve",
12
+ "build": "vue-cli-service build",
13
+ "test:unit": "vue-cli-service test:unit",
14
+ "build-bundle": "vue-cli-service build --target lib --name gallery src/main.js",
15
+ "lint": "vue-cli-service lint"
16
+ },
17
+ "main": "dist/gallery.common.js",
18
+ "dependencies": {
19
+ "@babel/code-frame": "^7.12.11",
20
+ "axios": "^0.26.1",
21
+ "babel-plugin-component": "^1.1.1",
22
+ "core-js": "^3.8.3",
23
+ "element-ui": "^2.15.0",
24
+ "vue": "^2.6.11"
25
+ },
26
+ "devDependencies": {
27
+ "@vue/cli-plugin-babel": "^4.5.11",
28
+ "@vue/cli-plugin-eslint": "^3.1.1",
29
+ "@vue/cli-plugin-unit-jest": "^4.5.13",
30
+ "@vue/cli-service": "^4.5.13",
31
+ "@vue/eslint-config-prettier": "^6.0.0",
32
+ "@vue/test-utils": "^1.1.2",
33
+ "babel-eslint": "^10.1.0",
34
+ "eslint": "^6.0.0",
35
+ "eslint-config-prettier": "^6.15.0",
36
+ "eslint-plugin-prettier": "^3.3.1",
37
+ "eslint-plugin-vue": "^6.2.2",
38
+ "prettier": "^2.2.1",
39
+ "vue-svg-inline-loader": "^2.1.3",
40
+ "vue-template-compiler": "^2.6.11"
41
+ }
42
+ }
package/public/index.html CHANGED
@@ -1,17 +1,17 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
- <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
- <title><%= htmlWebpackPlugin.options.title %></title>
9
- </head>
10
- <body>
11
- <noscript>
12
- <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
- </noscript>
14
- <div id="app"></div>
15
- <!-- built files will be auto injected -->
16
- </body>
17
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
+ <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
+ <title><%= htmlWebpackPlugin.options.title %></title>
9
+ </head>
10
+ <body>
11
+ <noscript>
12
+ <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
+ </noscript>
14
+ <div id="app"></div>
15
+ <!-- built files will be auto injected -->
16
+ </body>
17
+ </html>
package/src/App.vue CHANGED
@@ -1,34 +1,28 @@
1
- <template>
2
- <div id="app">
3
- <img alt="Vue logo" src="./assets/logo.png" />
4
- <gallery :items="dataInput"/>
5
- </div>
6
- </template>
7
-
8
- <script>
9
- import Gallery from './components/Gallery'
10
-
11
- export default {
12
- name: 'App',
13
- components: {
14
- Gallery
15
- },
16
- data: function(){
17
- return{
18
- dataInput: [{name: 'test1', type: 'data'}, {name:'test2', type: 'data'}]
19
-
20
- }
21
- }
22
- };
23
- </script>
24
-
25
- <style scoped>
26
- #app {
27
- font-family: Avenir, Helvetica, Arial, sans-serif;
28
- -webkit-font-smoothing: antialiased;
29
- -moz-osx-font-smoothing: grayscale;
30
- text-align: center;
31
- color: #2c3e50;
32
- margin-top: 60px;
33
- }
34
- </style>
1
+ <template>
2
+ <div id="app">
3
+ <img alt="Vue logo" src="./assets/logo.png" />
4
+ <HelloWorld msg="Welcome to Your Vue.js App" />
5
+ </div>
6
+ </template>
7
+
8
+ <script>
9
+ import HelloWorld from './components/HelloWorld.vue'
10
+
11
+ export default {
12
+ name: 'App',
13
+ components: {
14
+ HelloWorld,
15
+ },
16
+ }
17
+ </script>
18
+
19
+ <style scoped>
20
+ #app {
21
+ font-family: Avenir, Helvetica, Arial, sans-serif;
22
+ -webkit-font-smoothing: antialiased;
23
+ -moz-osx-font-smoothing: grayscale;
24
+ text-align: center;
25
+ color: #2c3e50;
26
+ margin-top: 60px;
27
+ }
28
+ </style>
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <svg id="logo-sparc-wave-primary" data-name="logo-sparc-wave-primary" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 190.5854"><defs><linearGradient id="linear-gradient" y1="96.3505" x2="400" y2="96.3505" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0b00bf"/><stop offset="1" stop-color="#bc00fc"/></linearGradient></defs><title>SPARC Logo</title><path d="M396.6976,128.6248l-146.2735-3.38a6.5358,6.5358,0,0,0-6.1378,3.9236l-.0612.1407-13.673,31.4482L202.9416,9.5333l-.01-.0685a8.9823,8.9823,0,0,0-17.6624-.0114L163.673,125.3819,3.298,129.2886a3.38,3.38,0,0,0,.0269,6.7592L169.34,138.7635a6.5939,6.5939,0,0,0,6.5373-5.1457l.0571-.2546,17.8534-79.5649L221.26,185.1237l.0256.1243A6.7593,6.7593,0,0,0,234.092,186.52L254.9005,138.66l141.7971-3.2762a3.3805,3.3805,0,0,0,0-6.7592Z" style="fill:url(#linear-gradient)"/><path d="M25.6793,0C41.3957,0,51.057,10.0926,51.057,26.0972v9.5162H36.2053V26.0972c0-7.3532-3.8945-11.8219-10.526-11.8219-6.7768,0-10.6691,4.4687-10.6691,11.8219,0,3.8945,1.2982,7.3533,5.4786,11.3908l19.754,18.601C46.5861,62.1441,52.21,68.7778,52.21,79.88c0,16.0047-9.95,26.0973-25.9543,26.0973C10.108,105.9776.1585,95.885.1585,79.88V70.362H15.01V79.88c0,7.3533,4.0375,11.822,11.2455,11.822,7.065,0,11.1025-4.4687,11.1025-11.822,0-4.4709-2.1628-8.6514-6.0551-12.2576L11.1158,48.7357C3.043,41.2372.1585,34.8939.1585,25.666.1585,10.0926,9.82,0,25.6793,0Z" style="fill:#0e0e19"/><path d="M99.7971,69.7856v35.1821H84.9454V1.01h25.3755c16.0047,0,26.0973,10.0926,26.0973,26.0973V43.6883c0,16.15-10.0926,26.0973-26.0973,26.0973Zm10.3808-13.9849c7.2081,0,11.3908-4.3257,11.3908-11.6789V26.6759c0-7.21-4.1827-11.6811-11.3908-11.6811H99.7971V55.8007Z" style="fill:#0e0e19"/><path d="M278.5812,108.147H263.73V4.1893h26.0972c16.0047,0,26.0973,10.0926,26.0973,26.0972v14.13c0,9.95-4.3257,17.7363-11.3908,22.205,4.1827,12.6889,10.0926,29.9917,13.8418,41.5254h-15.14L290.6914,70.3708h-12.11Zm11.1-51.7632c7.21,0,11.3907-4.3257,11.3907-11.5338V29.8553c0-7.21-4.18-11.6812-11.3907-11.6812h-11.1v38.21Z" style="fill:#0e0e19"/><path d="M399.844,73.5414V83.06c0,16.0047-9.9474,26.0973-25.9521,26.0973-16.15,0-26.0972-10.0926-26.0972-26.0973V29.2766c0-16.0046,9.9473-26.0972,26.0972-26.0972,16.0047,0,25.9521,10.0926,25.9521,26.0972v9.5161h-14.85V29.2766c0-7.3532-4.0374-11.822-11.1025-11.822-7.21,0-11.2477,4.4688-11.2477,11.822V83.06c0,7.3533,4.0375,11.822,11.2477,11.822,7.0651,0,11.1025-4.4687,11.1025-11.822V73.5414Z" style="fill:#0e0e19"/></svg>
Binary file
Binary file
@@ -1,136 +1,271 @@
1
- <template>
2
- <el-card :style="{ padding: '0px', maxWidth: width + 'rem' }" class="card">
3
- <div v-loading="!isReady">
4
- <img :src="entry.thumbnail" alt="thumbnail loading ..." />
5
- <div v-if="false" class="image-overlay">
6
- <div
7
- class="triangle-right-corner"
8
- :style="`border-left-width: ${triangleHeight * 1.2}rem; border-top-width: ${triangleHeight}rem;`"
9
- @click="openLinkInNewTab"
10
- />
11
- <el-tooltip class="item" :content="`View ${entry.type}`" placement="left">
12
- <img
13
- class="triangle-icon"
14
- :style="`height: ${triangleHeight * 0.25}rem;top: ${triangleHeight * 0.15}rem;right: ${triangleHeight * 0.15}rem`"
15
- :src="typeIcon"
16
- @click="openLinkInNewTab"
17
- />
18
- </el-tooltip>
19
- </div>
20
- <div v-if="showCardDetails" class="details">
21
- <p>
22
- <b>{{ entry.type }}</b>
23
- </p>
24
- <el-tooltip :content="entry.title" placement="top">
25
- <p class="title">
26
- {{ entry.title }}
27
- </p>
28
- </el-tooltip>
29
- <el-button @click.prevent="openLinkInNewTab"> View {{ entry.type }}</el-button>
30
- </div>
31
- </div>
32
- </el-card>
33
- </template>
34
-
35
- <script>
36
- import Vue from "vue";
37
- import { Card, Button, Tooltip, Loading } from "element-ui";
38
-
39
- Vue.use(Card)
40
- Vue.use(Button)
41
- Vue.use(Tooltip)
42
- Vue.use(Loading)
43
-
44
- export default {
45
- name: 'GalleryCard',
46
- props: {
47
- entry: {
48
- type: Object,
49
- required: true,
50
- },
51
- width: {
52
- type: Number,
53
- default: 3,
54
- },
55
- height: {
56
- type: Number,
57
- default: 3,
58
- },
59
- showCardDetails: {
60
- type: Boolean,
61
- },
62
- },
63
- data() {
64
- return {
65
- ro: null,
66
- triangleSize: 4,
67
- }
68
- },
69
- computed: {
70
- isReady() {
71
- return this.entry.title && this.entry.thumbnail && this.entry.link
72
- },
73
- imageHeight() {
74
- return this.showCardDetails ? this.height * 0.525 : this.height
75
- },
76
- imageWidth() {
77
- return this.width - 2 * this.marginDetails
78
- },
79
- triangleHeight() {
80
- return this.height * 0.237
81
- },
82
- marginDetails() {
83
- return this.height * 0.076
84
- },
85
- typeIcon() {
86
- return undefined
87
- },
88
- },
89
- methods: {
90
- openLinkInNewTab() {
91
- const link = document.createElement('a')
92
- link.href = this.entry.link
93
- link.target = '_blank'
94
- document.body.appendChild(link)
95
- link.click()
96
- link.remove()
97
- },
98
- },
99
- }
100
- </script>
101
-
102
- <style scoped>
103
- .card {
104
- position: relative;
105
- }
106
- .details {
107
- text-align: left;
108
- }
109
-
110
- .title {
111
- overflow-x: hidden;
112
- text-overflow: ellipsis;
113
- white-space: nowrap;
114
- }
115
-
116
- p.bold {
117
- font-weight: bold;
118
- }
119
-
120
- .image-overlay {
121
- position: absolute;
122
- top: 0;
123
- right: 0;
124
- }
125
-
126
- .triangle-icon {
127
- position: absolute;
128
- }
129
-
130
- .triangle-right-corner {
131
- width: 0;
132
- height: 0;
133
- border-left: solid transparent;
134
- border-top: solid #8300bf;
135
- }
136
- </style>
1
+ <template>
2
+ <el-card :shadow="shadow" :body-style="bodyStyle" :style="{ padding: '0px', maxWidth: width + 'rem' }" class="card">
3
+ <div v-loading="!isReady">
4
+ <div :style="imageContainerStyle">
5
+ <img v-if="useDefaultImg" src="../assets/logo-sparc-wave-primary.svg" svg-inline :style="imageStyle" />
6
+ <img v-else :src="thumbnail" alt="thumbnail loading ..." :style="imageStyle" />
7
+ </div>
8
+ <div v-if="false" class="image-overlay">
9
+ <div
10
+ class="triangle-right-corner"
11
+ :style="`border-left-width: ${triangleHeight * 1.2}rem; border-top-width: ${triangleHeight}rem;`"
12
+ @click="openLinkInNewTab"
13
+ />
14
+ <el-tooltip class="item" :content="`View ${data.type}`" placement="left">
15
+ <img
16
+ class="triangle-icon"
17
+ :style="`height: ${triangleHeight * 0.25}rem;top: ${triangleHeight * 0.15}rem;right: ${triangleHeight * 0.15}rem`"
18
+ :src="typeIcon"
19
+ @click="openLinkInNewTab"
20
+ />
21
+ </el-tooltip>
22
+ </div>
23
+ <div v-if="showCardDetails" class="details">
24
+ <p>
25
+ <b>{{ data.type }}</b>
26
+ </p>
27
+ <el-popover ref="galleryPopover" :content="data.title" placement="top" trigger="hover" popper-class="gallery-popper" />
28
+ <p class="title" v-popover:galleryPopover>
29
+ {{ data.title }}
30
+ </p>
31
+ <el-button class="button" @click.prevent="cardClicked"> View {{ data.type }}</el-button>
32
+ </div>
33
+ </div>
34
+ </el-card>
35
+ </template>
36
+
37
+ <script>
38
+ // import { SvgIcon } from '@abi-software/svg-sprite'
39
+ import axios from 'axios'
40
+ import Vue from 'vue'
41
+ import { Button, Card, Popover } from 'element-ui'
42
+ Vue.use(Button)
43
+ Vue.use(Card)
44
+ Vue.use(Popover)
45
+
46
+ function isValidHttpUrl(string) {
47
+ let url = undefined
48
+
49
+ try {
50
+ url = new URL(string)
51
+ } catch (_) {
52
+ return false
53
+ }
54
+ return url.protocol === 'http:' || url.protocol === 'https:'
55
+ }
56
+
57
+ const getRequest = async (url, params, timeout) => {
58
+ return await axios({
59
+ method: 'get',
60
+ url,
61
+ params,
62
+ timeout,
63
+ })
64
+ }
65
+
66
+ export default {
67
+ name: 'GalleryCard',
68
+ props: {
69
+ data: {
70
+ type: Object,
71
+ required: true,
72
+ },
73
+ width: {
74
+ type: Number,
75
+ default: 3,
76
+ },
77
+ height: {
78
+ type: Number,
79
+ default: 3,
80
+ },
81
+ showCardDetails: {
82
+ type: Boolean,
83
+ },
84
+ bodyStyle: {
85
+ type: Object,
86
+ default: () => {
87
+ return { padding: '20px', background: '#ffffff' }
88
+ },
89
+ },
90
+ imageStyle: {
91
+ type: Object,
92
+ default: () => {
93
+ return {}
94
+ },
95
+ },
96
+ imageContainerStyle: {
97
+ type: Object,
98
+ default: () => {
99
+ return {}
100
+ },
101
+ },
102
+ shadow: {
103
+ type: String,
104
+ default: 'always',
105
+ },
106
+ },
107
+ data() {
108
+ return {
109
+ ro: null,
110
+ triangleSize: 4,
111
+ thumbnail: undefined,
112
+ useDefaultImg: false,
113
+ }
114
+ },
115
+ computed: {
116
+ isReady() {
117
+ return this.data.title && (this.thumbnail || this.useDefaultImg) && (this.data.link || this.data.userData)
118
+ },
119
+ imageHeight() {
120
+ return this.showCardDetails ? this.height * 0.525 : this.height
121
+ },
122
+ imageWidth() {
123
+ return this.width - 2 * this.marginDetails
124
+ },
125
+ triangleHeight() {
126
+ return this.height * 0.237
127
+ },
128
+ marginDetails() {
129
+ return this.height * 0.076
130
+ },
131
+ typeIcon() {
132
+ return undefined
133
+ },
134
+ },
135
+ methods: {
136
+ cardClicked: function () {
137
+ if (this.data.link) {
138
+ const link = document.createElement('a')
139
+ link.href = this.data.link
140
+ link.target = '_blank'
141
+ document.body.appendChild(link)
142
+ link.click()
143
+ link.remove()
144
+ }
145
+ if (this.data.userData) {
146
+ this.$emit('card-clicked', this.data.userData)
147
+ }
148
+ },
149
+ downloadThumbnail: function (url, info) {
150
+ getRequest(url, {}, 11000).then(
151
+ (response) => {
152
+ let data = response.data
153
+ if (data.startsWith('data:')) {
154
+ this.thumbnail = response.data
155
+ } else {
156
+ if (this.data.mimetype) {
157
+ this.thumbnail = `data:${this.data.mimetype};base64,${response.data}`
158
+ } else {
159
+ this.thumbnail = response.data
160
+ }
161
+ }
162
+ },
163
+ (reason) => {
164
+ if (reason.message.includes('timeout') && reason.message.includes('exceeded') && info.fetchAttempts < 3) {
165
+ info.fetchAttempts += 1
166
+ this.downloadThumbnail(url, info)
167
+ } else {
168
+ this.useDefaultImg = true
169
+ }
170
+ }
171
+ )
172
+ },
173
+ },
174
+ watch: {
175
+ data: {
176
+ deep: true,
177
+ immediate: true,
178
+ handler: function () {
179
+ this.thumbnail = undefined
180
+ this.useDefaultImg = false
181
+ if (this.data.thumbnail) {
182
+ if (isValidHttpUrl(this.data.thumbnail) && this.data.mimetype) {
183
+ this.downloadThumbnail(this.data.thumbnail, { fetchAttempts: 0 })
184
+ } else {
185
+ this.thumbnail = this.data.thumbnail
186
+ }
187
+ } else {
188
+ this.useDefaultImg = true
189
+ }
190
+ },
191
+ },
192
+ },
193
+ }
194
+ </script>
195
+
196
+ <style scoped>
197
+ .button {
198
+ z-index: 10;
199
+ font-family: Asap;
200
+ font-size: 14px;
201
+ font-weight: normal;
202
+ font-stretch: normal;
203
+ font-style: normal;
204
+ line-height: normal;
205
+ letter-spacing: normal;
206
+ background-color: #8300bf;
207
+ border: #8300bf;
208
+ color: white;
209
+ cursor: pointer;
210
+ margin-top: 8px;
211
+ }
212
+
213
+ .button:hover {
214
+ background: #8300bf;
215
+ box-shadow: -3px 2px 4px 0 rgba(0, 0, 0, 0.25);
216
+ color: #fff;
217
+ }
218
+
219
+ .card {
220
+ position: relative;
221
+ }
222
+ .details {
223
+ text-align: left;
224
+ }
225
+
226
+ .title {
227
+ overflow-x: hidden;
228
+ text-overflow: ellipsis;
229
+ white-space: nowrap;
230
+ }
231
+
232
+ p.bold {
233
+ font-weight: bold;
234
+ }
235
+
236
+ .image-overlay {
237
+ position: absolute;
238
+ top: 0;
239
+ right: 0;
240
+ }
241
+
242
+ .triangle-icon {
243
+ position: absolute;
244
+ }
245
+
246
+ .triangle-right-corner {
247
+ width: 0;
248
+ height: 0;
249
+ border-left: solid transparent;
250
+ border-top: solid #8300bf;
251
+ }
252
+ </style>
253
+
254
+ <style>
255
+ .gallery-popper {
256
+ background: #f3ecf6 !important;
257
+ border: 1px solid #8300bf;
258
+ border-radius: 4px;
259
+ color: #303133 !important;
260
+ font-size: 12px;
261
+ line-height: 1rem;
262
+ height: 1rem;
263
+ padding: 10px;
264
+ }
265
+ .gallery-popper.el-popper[x-placement^='top'] .popper__arrow {
266
+ border-top-color: #8300bf !important;
267
+ }
268
+ .gallery-popper.el-popper[x-placement^='top'] .popper__arrow:after {
269
+ border-top-color: #f3ecf6 !important;
270
+ }
271
+ </style>