diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.vue | 20 | ||||
-rw-r--r-- | src/assets/app.scss | 68 | ||||
-rw-r--r-- | src/assets/defaults.yml | 6 | ||||
-rw-r--r-- | src/components/Navbar.vue | 20 | ||||
-rw-r--r-- | src/components/Service.vue | 35 | ||||
-rw-r--r-- | src/components/Subcard.vue | 12 |
6 files changed, 140 insertions, 21 deletions
diff --git a/src/App.vue b/src/App.vue index 17c3214..747d279 100644 --- a/src/App.vue +++ b/src/App.vue | |||
@@ -10,7 +10,7 @@ | |||
10 | > | 10 | > |
11 | <DynamicTheme :themes="config.colors" /> | 11 | <DynamicTheme :themes="config.colors" /> |
12 | <div id="bighead"> | 12 | <div id="bighead"> |
13 | <section v-if="config.header" class="first-line"> | 13 | <section v-if="config.header" class="first-line is-hidden-touch"> |
14 | <div v-cloak class="container"> | 14 | <div v-cloak class="container"> |
15 | <div class="logo"> | 15 | <div class="logo"> |
16 | <img v-if="config.logo" :src="config.logo" alt="dashboard logo" /> | 16 | <img v-if="config.logo" :src="config.logo" alt="dashboard logo" /> |
@@ -27,6 +27,8 @@ | |||
27 | :open="showMenu" | 27 | :open="showMenu" |
28 | :links="config.links" | 28 | :links="config.links" |
29 | @navbar:toggle="showMenu = !showMenu" | 29 | @navbar:toggle="showMenu = !showMenu" |
30 | :navigateToFirstService="navigateToFirstService" | ||
31 | :filterServices="filterServices" | ||
30 | > | 32 | > |
31 | <DarkMode @updated="isDark = $event" /> | 33 | <DarkMode @updated="isDark = $event" /> |
32 | 34 | ||
@@ -36,14 +38,6 @@ | |||
36 | icon="fa-list" | 38 | icon="fa-list" |
37 | iconAlt="fa-columns" | 39 | iconAlt="fa-columns" |
38 | /> | 40 | /> |
39 | |||
40 | <SearchInput | ||
41 | class="navbar-item is-inline-block-mobile" | ||
42 | @input="filterServices" | ||
43 | @search:focus="showMenu = true" | ||
44 | @search:open="navigateToFirstService" | ||
45 | @search:cancel="filterServices" | ||
46 | /> | ||
47 | </Navbar> | 41 | </Navbar> |
48 | </div> | 42 | </div> |
49 | 43 | ||
@@ -68,7 +62,7 @@ | |||
68 | v-for="item in group.items" | 62 | v-for="item in group.items" |
69 | :key="item.name" | 63 | :key="item.name" |
70 | v-bind:item="item" | 64 | v-bind:item="item" |
71 | :class="['column', `is-${12 / config.columns}`]" | 65 | class="column is-half-tablet is-one-third-widescreen is-half-desktop" |
72 | /> | 66 | /> |
73 | </template> | 67 | </template> |
74 | </div> | 68 | </div> |
@@ -79,7 +73,7 @@ | |||
79 | class="columns is-multiline layout-vertical" | 73 | class="columns is-multiline layout-vertical" |
80 | > | 74 | > |
81 | <div | 75 | <div |
82 | :class="['column', `is-${12 / config.columns}`]" | 76 | class="column is-half-tablet is-one-third-widescreen is-half-desktop" |
83 | v-for="group in services" | 77 | v-for="group in services" |
84 | :key="group.name" | 78 | :key="group.name" |
85 | > | 79 | > |
@@ -118,7 +112,6 @@ import Navbar from "./components/Navbar.vue"; | |||
118 | import ConnectivityChecker from "./components/ConnectivityChecker.vue"; | 112 | import ConnectivityChecker from "./components/ConnectivityChecker.vue"; |
119 | import Service from "./components/Service.vue"; | 113 | import Service from "./components/Service.vue"; |
120 | import Message from "./components/Message.vue"; | 114 | import Message from "./components/Message.vue"; |
121 | import SearchInput from "./components/SearchInput.vue"; | ||
122 | import SettingToggle from "./components/SettingToggle.vue"; | 115 | import SettingToggle from "./components/SettingToggle.vue"; |
123 | import DarkMode from "./components/DarkMode.vue"; | 116 | import DarkMode from "./components/DarkMode.vue"; |
124 | import DynamicTheme from "./components/DynamicTheme.vue"; | 117 | import DynamicTheme from "./components/DynamicTheme.vue"; |
@@ -132,7 +125,6 @@ export default { | |||
132 | ConnectivityChecker, | 125 | ConnectivityChecker, |
133 | Service, | 126 | Service, |
134 | Message, | 127 | Message, |
135 | SearchInput, | ||
136 | SettingToggle, | 128 | SettingToggle, |
137 | DarkMode, | 129 | DarkMode, |
138 | DynamicTheme, | 130 | DynamicTheme, |
@@ -143,7 +135,7 @@ export default { | |||
143 | services: null, | 135 | services: null, |
144 | offline: false, | 136 | offline: false, |
145 | filter: "", | 137 | filter: "", |
146 | vlayout: true, | 138 | vlayout: false, |
147 | isDark: null, | 139 | isDark: null, |
148 | showMenu: false, | 140 | showMenu: false, |
149 | }; | 141 | }; |
diff --git a/src/assets/app.scss b/src/assets/app.scss index ab067e6..2408d60 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss | |||
@@ -55,6 +55,23 @@ body { | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | .subcard { | ||
59 | background-color: var(--subcard-background); | ||
60 | color: var(--subcard-a); | ||
61 | |||
62 | a { | ||
63 | color: var(--subcard-a); | ||
64 | &:hover { | ||
65 | color: var(--subcard-a-hover); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | a.card-arrow { | ||
71 | color: var(--subcard-a); | ||
72 | background-color: var(--subcard-background); | ||
73 | } | ||
74 | |||
58 | .footer { | 75 | .footer { |
59 | background-color: var(--card-background); | 76 | background-color: var(--card-background); |
60 | box-shadow: 0 2px 15px 0 var(--card-shadow); | 77 | box-shadow: 0 2px 15px 0 var(--card-shadow); |
@@ -214,8 +231,7 @@ body { | |||
214 | } | 231 | } |
215 | } | 232 | } |
216 | 233 | ||
217 | .card { | 234 | .card, .card-arrow { |
218 | border-radius: 5px; | ||
219 | border: none; | 235 | border: none; |
220 | box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); | 236 | box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); |
221 | transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; | 237 | transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; |
@@ -225,6 +241,32 @@ body { | |||
225 | } | 241 | } |
226 | } | 242 | } |
227 | 243 | ||
244 | .card { | ||
245 | border-radius: 5px; | ||
246 | } | ||
247 | |||
248 | .card-arrow { | ||
249 | border-radius: 0px 5px 5px 0px; | ||
250 | } | ||
251 | |||
252 | .card-arrow.active { | ||
253 | border-radius: 0px 5px 0px 0px; | ||
254 | box-shadow: none; | ||
255 | } | ||
256 | |||
257 | .subcard { | ||
258 | border-radius: 0px 0px 5px 5px; | ||
259 | display: none; | ||
260 | list-style: disc inside; | ||
261 | padding: 0.8rem; | ||
262 | } | ||
263 | .subcard.active { | ||
264 | display: block; | ||
265 | } | ||
266 | .subcard a { | ||
267 | padding: 10px; | ||
268 | } | ||
269 | |||
228 | .card:hover { | 270 | .card:hover { |
229 | transform: translate(0, -3px); | 271 | transform: translate(0, -3px); |
230 | 272 | ||
@@ -239,6 +281,14 @@ body { | |||
239 | } | 281 | } |
240 | } | 282 | } |
241 | 283 | ||
284 | .card-arrow { | ||
285 | height: 85px; | ||
286 | display: flex; | ||
287 | align-items: center; | ||
288 | float: right; | ||
289 | padding: 10px; | ||
290 | } | ||
291 | |||
242 | .card-content { | 292 | .card-content { |
243 | height: 85px; | 293 | height: 85px; |
244 | padding: 1.3rem; | 294 | padding: 1.3rem; |
@@ -259,10 +309,6 @@ body { | |||
259 | } | 309 | } |
260 | 310 | ||
261 | .footer { | 311 | .footer { |
262 | position: fixed; | ||
263 | left: 0; | ||
264 | right: 0; | ||
265 | bottom: 0; | ||
266 | padding: 0.5rem; | 312 | padding: 0.5rem; |
267 | text-align: left; | 313 | text-align: left; |
268 | color: #676767; | 314 | color: #676767; |
@@ -318,6 +364,16 @@ body { | |||
318 | } | 364 | } |
319 | } | 365 | } |
320 | 366 | ||
367 | .search-bar-mobile { | ||
368 | input { | ||
369 | margin-top: 10px; | ||
370 | margin-left: 10px; | ||
371 | } | ||
372 | .search-label::before { | ||
373 | top: 14px; | ||
374 | } | ||
375 | } | ||
376 | |||
321 | .offline-message { | 377 | .offline-message { |
322 | text-align: center; | 378 | text-align: center; |
323 | margin: 35px 0; | 379 | margin: 35px 0; |
diff --git a/src/assets/defaults.yml b/src/assets/defaults.yml index 99f5ed5..eaa345c 100644 --- a/src/assets/defaults.yml +++ b/src/assets/defaults.yml | |||
@@ -18,11 +18,14 @@ colors: | |||
18 | highlight-hover: "#5a95f5" | 18 | highlight-hover: "#5a95f5" |
19 | background: "#f5f5f5" | 19 | background: "#f5f5f5" |
20 | card-background: "#ffffff" | 20 | card-background: "#ffffff" |
21 | subcard-background: "#eeeeee" | ||
21 | text: "#363636" | 22 | text: "#363636" |
22 | text-header: "#ffffff" | 23 | text-header: "#ffffff" |
23 | text-title: "#303030" | 24 | text-title: "#303030" |
24 | text-subtitle: "#424242" | 25 | text-subtitle: "#424242" |
25 | card-shadow: rgba(0, 0, 0, 0.1) | 26 | card-shadow: rgba(0, 0, 0, 0.1) |
27 | subcard-a: "#363636" | ||
28 | subcard-a-hover: "#808080" | ||
26 | link-hover: "#363636" | 29 | link-hover: "#363636" |
27 | dark: | 30 | dark: |
28 | highlight-primary: "#3367d6" | 31 | highlight-primary: "#3367d6" |
@@ -30,11 +33,14 @@ colors: | |||
30 | highlight-hover: "#5a95f5" | 33 | highlight-hover: "#5a95f5" |
31 | background: "#131313" | 34 | background: "#131313" |
32 | card-background: "#2b2b2b" | 35 | card-background: "#2b2b2b" |
36 | subcard-background: "#444444" | ||
33 | text: "#eaeaea" | 37 | text: "#eaeaea" |
34 | text-header: "#ffffff" | 38 | text-header: "#ffffff" |
35 | text-title: "#fafafa" | 39 | text-title: "#fafafa" |
36 | text-subtitle: "#f5f5f5" | 40 | text-subtitle: "#f5f5f5" |
37 | card-shadow: rgba(0, 0, 0, 0.4) | 41 | card-shadow: rgba(0, 0, 0, 0.4) |
42 | subcard-a: "#ffdd57" | ||
43 | subcard-a-hover: "#eaeaea" | ||
38 | link-hover: "#ffdd57" | 44 | link-hover: "#ffdd57" |
39 | 45 | ||
40 | message: ~ | 46 | message: ~ |
diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue index d3ceaf8..fd57156 100644 --- a/src/components/Navbar.vue +++ b/src/components/Navbar.vue | |||
@@ -3,6 +3,12 @@ | |||
3 | <nav class="navbar" role="navigation" aria-label="main navigation"> | 3 | <nav class="navbar" role="navigation" aria-label="main navigation"> |
4 | <div class="container"> | 4 | <div class="container"> |
5 | <div class="navbar-brand"> | 5 | <div class="navbar-brand"> |
6 | <SearchInput | ||
7 | class="search-bar search-bar-mobile is-hidden-desktop" | ||
8 | @input="filterServices" | ||
9 | @search:open="navigateToFirstService" | ||
10 | @search:cancel="filterServices" | ||
11 | /> | ||
6 | <a | 12 | <a |
7 | role="button" | 13 | role="button" |
8 | aria-label="menu" | 14 | aria-label="menu" |
@@ -36,6 +42,13 @@ | |||
36 | </div> | 42 | </div> |
37 | <div class="navbar-end"> | 43 | <div class="navbar-end"> |
38 | <slot></slot> | 44 | <slot></slot> |
45 | |||
46 | <SearchInput | ||
47 | class="navbar-item is-inline-block-mobile is-hidden-touch" | ||
48 | @input="filterServices" | ||
49 | @search:open="navigateToFirstService" | ||
50 | @search:cancel="filterServices" | ||
51 | /> | ||
39 | </div> | 52 | </div> |
40 | </div> | 53 | </div> |
41 | </div> | 54 | </div> |
@@ -44,14 +57,21 @@ | |||
44 | </template> | 57 | </template> |
45 | 58 | ||
46 | <script> | 59 | <script> |
60 | import SearchInput from "./SearchInput.vue"; | ||
61 | |||
47 | export default { | 62 | export default { |
48 | name: "Navbar", | 63 | name: "Navbar", |
64 | components: { | ||
65 | SearchInput, | ||
66 | }, | ||
49 | props: { | 67 | props: { |
50 | open: { | 68 | open: { |
51 | type: Boolean, | 69 | type: Boolean, |
52 | default: false, | 70 | default: false, |
53 | }, | 71 | }, |
54 | links: Array, | 72 | links: Array, |
73 | navigateToFirstService: { type: Function }, | ||
74 | filterServices: { type: Function }, | ||
55 | }, | 75 | }, |
56 | computed: { | 76 | computed: { |
57 | showMenu: function () { | 77 | showMenu: function () { |
diff --git a/src/components/Service.vue b/src/components/Service.vue index a2448ca..80bf019 100644 --- a/src/components/Service.vue +++ b/src/components/Service.vue | |||
@@ -1,7 +1,10 @@ | |||
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | <div class="card"> | 3 | <div class="card"> |
4 | <a :href="item.url" :target="item.target" rel="noreferrer"> | 4 | <a class="card-arrow" v-bind:class="subcardClass" v-on:click="subCardActive = !subCardActive" v-if="item.links && item.links.length > 0"> |
5 | <i style="font-size: 20px" class="fa fa-arrow-circle-down" v-bind:class="arrowClass"></i> | ||
6 | </a> | ||
7 | <a style="background-color: gray" :href="item.url" :target="item.target" rel="noreferrer"> | ||
5 | <div class="card-content"> | 8 | <div class="card-content"> |
6 | <div class="media"> | 9 | <div class="media"> |
7 | <div v-if="item.logo" class="media-left"> | 10 | <div v-if="item.logo" class="media-left"> |
@@ -24,16 +27,46 @@ | |||
24 | </div> | 27 | </div> |
25 | </div> | 28 | </div> |
26 | </a> | 29 | </a> |
30 | <ul class="subcard" v-bind:class="subcardClass"> | ||
31 | <Subcard | ||
32 | v-for="link in item.links" | ||
33 | v-bind:link="link" | ||
34 | :key="link.url" | ||
35 | /> | ||
36 | </ul> | ||
27 | </div> | 37 | </div> |
28 | </div> | 38 | </div> |
29 | </template> | 39 | </template> |
30 | 40 | ||
31 | <script> | 41 | <script> |
42 | import Subcard from "./Subcard.vue"; | ||
43 | |||
32 | export default { | 44 | export default { |
33 | name: "Service", | 45 | name: "Service", |
46 | components: { | ||
47 | Subcard, | ||
48 | }, | ||
34 | props: { | 49 | props: { |
35 | item: Object, | 50 | item: Object, |
36 | }, | 51 | }, |
52 | data: function() { | ||
53 | return { | ||
54 | subCardActive: false, | ||
55 | } | ||
56 | }, | ||
57 | computed: { | ||
58 | arrowClass: function() { | ||
59 | return { | ||
60 | "fa-arrow-circle-down": !this.subCardActive, | ||
61 | "fa-arrow-circle-up": this.subCardActive | ||
62 | } | ||
63 | }, | ||
64 | subcardClass: function() { | ||
65 | return { | ||
66 | active: this.subCardActive | ||
67 | } | ||
68 | } | ||
69 | } | ||
37 | }; | 70 | }; |
38 | </script> | 71 | </script> |
39 | 72 | ||
diff --git a/src/components/Subcard.vue b/src/components/Subcard.vue new file mode 100644 index 0000000..808cd48 --- /dev/null +++ b/src/components/Subcard.vue | |||
@@ -0,0 +1,12 @@ | |||
1 | <template v-for="link in item.links"> | ||
2 | <li><a :href="link.url">{{ link.name }}</a></li> | ||
3 | </template> | ||
4 | |||
5 | <script> | ||
6 | export default { | ||
7 | name: "Subcard", | ||
8 | props: { | ||
9 | link: Object, | ||
10 | }, | ||
11 | }; | ||
12 | </script> | ||