diff options
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | app.css | 35 | ||||
-rw-r--r-- | app.js | 13 | ||||
-rw-r--r-- | app.scss | 30 | ||||
-rw-r--r-- | config.yml | 9 | ||||
-rw-r--r-- | index.html | 165 |
6 files changed, 151 insertions, 111 deletions
@@ -8,7 +8,7 @@ If you need authentication support, you're on your own (it can be secured using | |||
8 | 8 | ||
9 | **How to build / install it? Where is the webpack config?** | 9 | **How to build / install it? Where is the webpack config?** |
10 | There is no build system (😱), use it like that! It'meant to be stupid simple & zero maintenance required. just copy the static files somewhere, and visit the `index.html`. | 10 | There is no build system (😱), use it like that! It'meant to be stupid simple & zero maintenance required. just copy the static files somewhere, and visit the `index.html`. |
11 | 11 | ||
12 | 12 | ||
13 | ## configuration | 13 | ## configuration |
14 | 14 | ||
@@ -18,11 +18,13 @@ Title, icons, links, colors, and services can be configured in the `config.yml` | |||
18 | ```yaml | 18 | ```yaml |
19 | --- | 19 | --- |
20 | # Homepage configuration | 20 | # Homepage configuration |
21 | # See https://fontawesome.com/v4.7.0/icons/ for icons options | 21 | # See https://fontawesome.com/icons for icons options |
22 | 22 | ||
23 | title: "Simple homepage" | 23 | title: "Simple homepage" |
24 | subtitle: "Homer" | 24 | subtitle: "Homer" |
25 | logo: "assets/homer.png" | 25 | logo: "assets/homer.png" |
26 | # Alternatively a fa icon can be provided: | ||
27 | # icon: "fas fa-skull-crossbones" | ||
26 | 28 | ||
27 | # Optional message | 29 | # Optional message |
28 | message: | 30 | message: |
@@ -48,6 +50,8 @@ services: | |||
48 | items: | 50 | items: |
49 | - name: "Jenkins" | 51 | - name: "Jenkins" |
50 | logo: "/assets/tools/jenkins.png" | 52 | logo: "/assets/tools/jenkins.png" |
53 | # Alternatively a fa icon can be provided: | ||
54 | # icon: "fab fa-jenkins" | ||
51 | subtitle: "Continuous integration server" | 55 | subtitle: "Continuous integration server" |
52 | tag: "CI" | 56 | tag: "CI" |
53 | url: "#" | 57 | url: "#" |
@@ -79,4 +83,4 @@ services: | |||
79 | tag: "CI" | 83 | tag: "CI" |
80 | url: "#" | 84 | url: "#" |
81 | 85 | ||
82 | ``` \ No newline at end of file | 86 | ``` |
@@ -1,3 +1,6 @@ | |||
1 | html { | ||
2 | height: 100%; } | ||
3 | |||
1 | body { | 4 | body { |
2 | font-family: 'Raleway', sans-serif; | 5 | font-family: 'Raleway', sans-serif; |
3 | background-color: #F5F5F5; | 6 | background-color: #F5F5F5; |
@@ -10,9 +13,8 @@ body { | |||
10 | font-size: 1.7rem; | 13 | font-size: 1.7rem; |
11 | margin-top: 3rem; | 14 | margin-top: 3rem; |
12 | margin-bottom: 1rem; } | 15 | margin-bottom: 1rem; } |
13 | body h2 .fa { | 16 | body h2 .fas, body h2 .fab, body h2 .far { |
14 | margin-right: 10px; | 17 | margin-right: 10px; } |
15 | color: #4285f4; } | ||
16 | body h2 span { | 18 | body h2 span { |
17 | font-weight: bold; | 19 | font-weight: bold; |
18 | color: #4285f4; } | 20 | color: #4285f4; } |
@@ -35,15 +37,20 @@ body { | |||
35 | body #bighead .first-line .container { | 37 | body #bighead .first-line .container { |
36 | height: 80px; | 38 | height: 80px; |
37 | padding: 10px 0; } | 39 | padding: 10px 0; } |
38 | body #bighead .first-line img { | 40 | body #bighead .first-line .logo { |
39 | float: left; | 41 | float: left; } |
40 | max-height: 70px; | 42 | body #bighead .first-line .logo i { |
41 | max-width: 70px; | 43 | vertical-align: top; |
42 | padding: 10px; } | 44 | padding: 8px 15px; |
45 | font-size: 50px; } | ||
46 | body #bighead .first-line .logo img { | ||
47 | padding: 10px; | ||
48 | max-height: 70px; | ||
49 | max-width: 70px; } | ||
43 | body #bighead .navbar { | 50 | body #bighead .navbar { |
44 | background-color: #4285f4; } | 51 | background-color: #4285f4; } |
45 | body #bighead .navbar a { | 52 | body #bighead .navbar a { |
46 | color: #152138; } | 53 | color: #ffffff; } |
47 | body #bighead .navbar a:hover { | 54 | body #bighead .navbar a:hover { |
48 | background-color: #5a95f5; } | 55 | background-color: #5a95f5; } |
49 | body #main-section { | 56 | body #main-section { |
@@ -55,7 +62,10 @@ body { | |||
55 | body #main-section .title { | 62 | body #main-section .title { |
56 | font-size: 1.1em; } | 63 | font-size: 1.1em; } |
57 | body #main-section .subtitle { | 64 | body #main-section .subtitle { |
58 | font-size: .9em; } | 65 | font-size: .9em; |
66 | white-space: nowrap; | ||
67 | overflow: hidden; | ||
68 | text-overflow: ellipsis; } | ||
59 | body #main-section .column { | 69 | body #main-section .column { |
60 | padding: 1.2rem .75rem; } | 70 | padding: 1.2rem .75rem; } |
61 | body #main-section .message { | 71 | body #main-section .message { |
@@ -90,7 +100,8 @@ body { | |||
90 | color: #ffffff; | 100 | color: #ffffff; |
91 | padding: 0 0.75em; } | 101 | padding: 0 0.75em; } |
92 | body .card-content { | 102 | body .card-content { |
93 | height: 110px; } | 103 | height: 85px; |
104 | padding: 1.3rem; } | ||
94 | body .footer { | 105 | body .footer { |
95 | position: fixed; | 106 | position: fixed; |
96 | left: 0; | 107 | left: 0; |
@@ -126,5 +137,3 @@ body { | |||
126 | height: 20px; } | 137 | height: 20px; } |
127 | body .search-bar:focus-within .search-label::before { | 138 | body .search-bar:focus-within .search-label::before { |
128 | color: #4a4a4a; } | 139 | color: #4a4a4a; } |
129 | |||
130 | /*# sourceMappingURL=app.css.map */ | ||
@@ -4,13 +4,12 @@ var app = new Vue({ | |||
4 | config: null, | 4 | config: null, |
5 | filter: '' | 5 | filter: '' |
6 | }, | 6 | }, |
7 | beforeCreate () { | 7 | beforeCreate() { |
8 | let that = this; | 8 | let that = this; |
9 | 9 | ||
10 | return getConfig().then(function (config) { | 10 | return getConfig().then(function (config) { |
11 | console.log(config); | ||
12 | const size = 3; | 11 | const size = 3; |
13 | config.services.forEach(function(service) { | 12 | config.services.forEach(function (service) { |
14 | service.rows = []; | 13 | service.rows = []; |
15 | items = service.items; | 14 | items = service.items; |
16 | while (items.length) { | 15 | while (items.length) { |
@@ -18,7 +17,7 @@ var app = new Vue({ | |||
18 | } | 17 | } |
19 | 18 | ||
20 | if (service.rows.length) { | 19 | if (service.rows.length) { |
21 | let last = service.rows.length-1; | 20 | let last = service.rows.length - 1; |
22 | service.rows[last] = service.rows[last].concat(Array(size - service.rows[last].length)); | 21 | service.rows[last] = service.rows[last].concat(Array(size - service.rows[last].length)); |
23 | } | 22 | } |
24 | }); | 23 | }); |
@@ -31,13 +30,13 @@ var app = new Vue({ | |||
31 | 30 | ||
32 | 31 | ||
33 | function getConfig() { | 32 | function getConfig() { |
34 | return fetch('config.yml').then(function(response) { | 33 | return fetch('config.yml').then(function (response) { |
35 | if (response.status !== 200) { | 34 | if (response.status !== 200) { |
36 | return; | 35 | return; |
37 | } | 36 | } |
38 | 37 | ||
39 | return response.text().then(function(body){ | 38 | return response.text().then(function (body) { |
40 | return jsyaml.load(body); | 39 | return jsyaml.load(body); |
41 | }); | 40 | }); |
42 | }); | 41 | }); |
43 | } \ No newline at end of file | 42 | } |
@@ -1,6 +1,8 @@ | |||
1 | $primary-color: #3367d6; | 1 | $primary-color: #3367d6; |
2 | $secondary-color: #4285f4; | 2 | $secondary-color: #4285f4; |
3 | 3 | ||
4 | html { height: 100%; } | ||
5 | |||
4 | body { | 6 | body { |
5 | font-family: 'Raleway', sans-serif; | 7 | font-family: 'Raleway', sans-serif; |
6 | background-color: #F5F5F5; | 8 | background-color: #F5F5F5; |
@@ -19,9 +21,8 @@ body { | |||
19 | margin-top: 3rem; | 21 | margin-top: 3rem; |
20 | margin-bottom: 1rem; | 22 | margin-bottom: 1rem; |
21 | 23 | ||
22 | .fa { | 24 | .fas, .fab, .far { |
23 | margin-right: 10px; | 25 | margin-right: 10px; |
24 | color: $secondary-color; | ||
25 | } | 26 | } |
26 | 27 | ||
27 | span { | 28 | span { |
@@ -61,19 +62,26 @@ body { | |||
61 | padding: 10px 0; | 62 | padding: 10px 0; |
62 | } | 63 | } |
63 | 64 | ||
64 | img { | 65 | .logo { |
65 | float: left; | 66 | float: left; |
66 | max-height: 70px; | 67 | i { |
67 | max-width: 70px; | 68 | vertical-align: top; |
68 | padding: 10px; | 69 | padding: 8px 15px; |
70 | font-size: 50px | ||
71 | } | ||
72 | |||
73 | img { | ||
74 | padding: 10px; | ||
75 | max-height: 70px; | ||
76 | max-width: 70px; | ||
77 | } | ||
69 | } | 78 | } |
70 | } | 79 | } |
71 | .navbar { | 80 | .navbar { |
72 | background-color: $secondary-color; | 81 | background-color: $secondary-color; |
73 | 82 | ||
74 | a { | 83 | a { |
75 | color: #152138; | 84 | color: #ffffff; |
76 | |||
77 | &:hover { | 85 | &:hover { |
78 | background-color: lighten( $secondary-color, 5% ); | 86 | background-color: lighten( $secondary-color, 5% ); |
79 | } | 87 | } |
@@ -96,6 +104,9 @@ body { | |||
96 | 104 | ||
97 | .subtitle { | 105 | .subtitle { |
98 | font-size: .9em; | 106 | font-size: .9em; |
107 | white-space: nowrap; | ||
108 | overflow: hidden; | ||
109 | text-overflow: ellipsis; | ||
99 | } | 110 | } |
100 | 111 | ||
101 | .column { | 112 | .column { |
@@ -151,7 +162,8 @@ body { | |||
151 | } | 162 | } |
152 | 163 | ||
153 | .card-content { | 164 | .card-content { |
154 | height: 110px; | 165 | height: 85px; |
166 | padding: 1.3rem; | ||
155 | } | 167 | } |
156 | 168 | ||
157 | .footer { | 169 | .footer { |
@@ -5,6 +5,7 @@ | |||
5 | title: "Simple homepage" | 5 | title: "Simple homepage" |
6 | subtitle: "Homer" | 6 | subtitle: "Homer" |
7 | logo: "assets/homer.png" | 7 | logo: "assets/homer.png" |
8 | icon: "fas fa-skull-crossbones" | ||
8 | 9 | ||
9 | # Optional message | 10 | # Optional message |
10 | # See https://bulma.io/documentation/components/message/#colors for styling options. | 11 | # See https://bulma.io/documentation/components/message/#colors for styling options. |
@@ -16,10 +17,10 @@ message: | |||
16 | # Optional navbar | 17 | # Optional navbar |
17 | links: | 18 | links: |
18 | - name: "ansible" | 19 | - name: "ansible" |
19 | icon: "fa-github" | 20 | icon: "fab fa-github" |
20 | url: "https://github.com/xxxxx/ansible/" | 21 | url: "https://github.com/xxxxx/ansible/" |
21 | - name: "Wiki" | 22 | - name: "Wiki" |
22 | icon: "fa-book" | 23 | icon: "fas fa-book" |
23 | url: "https://wiki.xxxxxx.com/" | 24 | url: "https://wiki.xxxxxx.com/" |
24 | 25 | ||
25 | # Services | 26 | # Services |
@@ -27,7 +28,7 @@ links: | |||
27 | # Leave only a "items" key if not using group (group name & icon are optional, section separation will not be displayed). | 28 | # Leave only a "items" key if not using group (group name & icon are optional, section separation will not be displayed). |
28 | services: | 29 | services: |
29 | - name: "DevOps" | 30 | - name: "DevOps" |
30 | icon: "fa-code-fork" | 31 | icon: "fas fa-code-branch" |
31 | items: | 32 | items: |
32 | - name: "Jenkins" | 33 | - name: "Jenkins" |
33 | logo: "/assets/tools/jenkins.png" | 34 | logo: "/assets/tools/jenkins.png" |
@@ -40,7 +41,7 @@ services: | |||
40 | tag: "haproxy" | 41 | tag: "haproxy" |
41 | url: "#" | 42 | url: "#" |
42 | - name: "Monitoring" | 43 | - name: "Monitoring" |
43 | icon: "fa-heartbeat" | 44 | icon: "fas fa-heartbeat" |
44 | items: | 45 | items: |
45 | - name: "M/Monit" | 46 | - name: "M/Monit" |
46 | logo: "/assets/tools/monit.png" | 47 | logo: "/assets/tools/monit.png" |
@@ -1,107 +1,122 @@ | |||
1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
2 | <html> | 2 | <html> |
3 | |||
3 | <head> | 4 | <head> |
4 | <meta charset="utf-8"> | 5 | <meta charset="utf-8"> |
5 | <meta name="viewport" content="width=device-width, initial-scale=1"> | 6 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
6 | <meta name="robots" content="noindex"> | 7 | <meta name="robots" content="noindex"> |
7 | <link rel="icon" type="image/png" href="assets/favicon.png"> | 8 | <link rel="icon" type="image/png" href="assets/favicon.png"> |
8 | <title>Homer</title> | 9 | <title>Homer</title> |
9 | <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> | 10 | <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" |
10 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css"> | 11 | crossorigin="anonymous"> |
12 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css"> | ||
11 | <link href="https://fonts.googleapis.com/css?family=Lato|Raleway" rel="stylesheet"> | 13 | <link href="https://fonts.googleapis.com/css?family=Lato|Raleway" rel="stylesheet"> |
12 | <link rel="stylesheet" href="app.css"> | 14 | <link rel="stylesheet" href="app.css"> |
13 | </head> | 15 | </head> |
16 | |||
14 | <body> | 17 | <body> |
15 | <div id="app" v-if="config"> | 18 | <div id="app" v-if="config"> |
16 | <div id="bighead"> | 19 | <div id="bighead"> |
17 | <section class="first-line"> | 20 | <section class="first-line"> |
18 | <div class="container"> | ||
19 | <img v-if="config.logo" :src="config.logo" /> | ||
20 | <div class="dashboard-title"> | ||
21 | <span v-cloak class="headline">{{ config.subtitle }}</span> | ||
22 | <h1 v-cloak>{{ config.title }}</h1> | ||
23 | </div> | ||
24 | </div> | ||
25 | </section> | ||
26 | <div v-if="config.links" class="container-fluid"> | ||
27 | <nav class="navbar" role="navigation" aria-label="main navigation"> | ||
28 | <div class="container"> | 21 | <div class="container"> |
29 | <div class="navbar-menu"> | 22 | <div class="logo"> |
30 | <div class="navbar-start"> | 23 | <img v-if="config.logo" :src="config.logo" /> |
31 | <a v-for="link in config.links" class="navbar-item" :href="link.url"> | 24 | <i v-if="config.icon" :class="config.icon"></i> |
32 | <i v-if="link.icon" style="margin-right: 6px;" class="fa" :class="link.icon"></i> | 25 | </div> |
33 | {{ link.name }} | 26 | <div class="dashboard-title"> |
34 | </a> | 27 | <span v-cloak class="headline">{{ config.subtitle }}</span> |
35 | </div> | 28 | <h1 v-cloak>{{ config.title }}</h1> |
36 | <div class="end"> | 29 | </div> |
37 | <div class="search-bar"> | 30 | </div> |
38 | <label for="search" class="search-label"></label> | 31 | </section> |
39 | <input type="text" id="search" v-model="filter"/> | 32 | <div v-if="config.links" class="container-fluid"> |
33 | <nav class="navbar" role="navigation" aria-label="main navigation"> | ||
34 | <div class="container"> | ||
35 | <div class="navbar-menu"> | ||
36 | <div class="navbar-start"> | ||
37 | <a v-for="link in config.links" class="navbar-item" :href="link.url"> | ||
38 | <i v-if="link.icon" style="margin-right: 6px;" :class="link.icon"></i> | ||
39 | {{ link.name }} | ||
40 | </a> | ||
41 | </div> | ||
42 | <div class="end"> | ||
43 | <div class="search-bar"> | ||
44 | <label for="search" class="search-label"></label> | ||
45 | <input type="text" id="search" v-model="filter" /> | ||
46 | </div> | ||
40 | </div> | 47 | </div> |
41 | </div> | 48 | </div> |
42 | </div> | 49 | </div> |
43 | </div> | 50 | </nav> |
44 | </nav> | 51 | </div> |
45 | </div> | 52 | </div> |
46 | </div> | ||
47 | 53 | ||
48 | <section id="main-section" class="section"> | 54 | <section id="main-section" class="section"> |
49 | <div class="container"> | 55 | <div class="container"> |
50 | <!-- Optional messages --> | 56 | <!-- Optional messages --> |
51 | <article v-cloak v-if="config && config.message" class="message" :class="config.message.style"> | 57 | <article v-cloak v-if="config && config.message" class="message" :class="config.message.style"> |
52 | <div v-if="config.message.title" class="message-header"> | 58 | <div v-if="config.message.title" class="message-header"> |
53 | <p>{{ config.message.title }}</p> | 59 | <p>{{ config.message.title }}</p> |
54 | </div> | 60 | </div> |
55 | <div v-if="config.message.content" class="message-body"> | 61 | <div v-if="config.message.content" class="message-body"> |
56 | {{ config.message.content }} | 62 | {{ config.message.content }} |
57 | </div> | 63 | </div> |
58 | </article> | 64 | </article> |
59 | 65 | ||
60 | <h2 v-cloak v-if="filter"><i class="fa fa-search"></i> Search</h2> | 66 | <h2 v-cloak v-if="filter"><i class="fas fa-search"></i> Search</h2> |
61 | 67 | ||
62 | <div v-for="(group, index) in config.services"> | 68 | <div v-for="(group, index) in config.services"> |
63 | <h2 v-if="!filter && group.name"><i v-if="group.icon" class="fa" :class="group.icon"></i><span v-else>#</span> {{ group.name }}</h2> | 69 | <h2 v-if="!filter && group.name"><i v-if="group.icon" :class="group.icon"></i><span v-else>#</span> |
64 | <div v-for="items in group.rows"> | 70 | {{ group.name }}</h2> |
65 | <div class="columns"> | 71 | <div v-for="items in group.rows"> |
66 | <div v-for="item in items" v-if="!filter || (item && (item.name.toLowerCase().includes(filter.toLowerCase()) || (item.tag && item.tag.toLowerCase().includes(filter.toLowerCase()))))" class="column"> | 72 | <div class="columns"> |
67 | <div> | 73 | <div v-for="item in items" v-if="!filter || (item && (item.name.toLowerCase().includes(filter.toLowerCase()) || (item.tag && item.tag.toLowerCase().includes(filter.toLowerCase()))))" |
68 | <div v-if='item' class="card"> | 74 | class="column"> |
69 | <a :href="item.url"> | 75 | <div> |
70 | <div class="card-content"> | 76 | <div v-if='item' class="card"> |
71 | <div class="media"> | 77 | <a :href="item.url"> |
72 | <div v-if="item.logo" class="media-left"> | 78 | <div class="card-content"> |
73 | <figure class="image is-48x48"> | 79 | <div class="media"> |
74 | <img :src="item.logo" /> | 80 | <div v-if="item.logo" class="media-left"> |
75 | </figure> | 81 | <figure class="image is-48x48"> |
76 | </div> | 82 | <img :src="item.logo" /> |
77 | <div class="media-content"> | 83 | </figure> |
78 | <p class="title is-4">{{ item.name }}</p> | 84 | </div> |
79 | <p class="subtitle is-6">{{ item.subtitle }}</p> | 85 | <div v-if="item.icon" class="media-left"> |
86 | <figure class="image is-48x48"> | ||
87 | <i style="font-size: 35px" :class="item.icon"></i> | ||
88 | </figure> | ||
89 | </div> | ||
90 | <div class="media-content"> | ||
91 | <p class="title is-4">{{ item.name }}</p> | ||
92 | <p class="subtitle is-6">{{ item.subtitle }}</p> | ||
93 | </div> | ||
80 | </div> | 94 | </div> |
95 | <strong v-if="item.tag" class="tag">#{{ item.tag }}</strong> | ||
81 | </div> | 96 | </div> |
82 | <strong v-if="item.tag" class="tag">#{{ item.tag }}</strong> | 97 | </a> |
83 | </div> | 98 | </div> |
84 | </a> | ||
85 | </div> | 99 | </div> |
86 | </div> | 100 | </div> |
87 | </div> | 101 | </div> |
88 | </div> | 102 | </div> |
89 | </div> | 103 | </div> |
90 | </div> | 104 | </div> |
91 | </div> | 105 | </section> |
92 | </section> | 106 | </div> |
93 | </div> | ||
94 | 107 | ||
95 | <footer class="footer"> | 108 | <footer class="footer"> |
96 | <div class="container"> | 109 | <div class="container"> |
97 | <div class="content has-text-centered"> | 110 | <div class="content has-text-centered"> |
98 | <p>Created with <span class="has-text-danger">❤️</span> with <a href="#">bulma</a>, <a href="#">vuejs</a> & <a href="#">font awesome</a>// Fork me on <a href="https://github.com/bastienwirtz/homer"><i class="fa fa-github-alt"></i></a>.</p> | 111 | <p>Created with <span class="has-text-danger">❤️</span> with <a href="https://bulma.io/">bulma</a>, <a href="https://vuejs.org/">vuejs</a> |
112 | & <a href="#">font awesome</a> // Fork me on <a href="https://github.com/bastienwirtz/homer"><i class="fab fa-github-alt"></i></a></p> | ||
113 | </div> | ||
99 | </div> | 114 | </div> |
100 | </div> | 115 | </footer> |
101 | </footer> | ||
102 | 116 | ||
103 | <script src="https://unpkg.com/vue"></script> | 117 | <script src="https://unpkg.com/vue"></script> |
104 | <script src="vendors/js-yaml.min.js"></script> | 118 | <script src="vendors/js-yaml.min.js"></script> |
105 | <script src="app.js"></script> | 119 | <script src="app.js"></script> |
106 | </body> | 120 | </body> |
107 | </html> \ No newline at end of file | 121 | |
122 | </html> | ||