mirror of https://github.com/statping/statping
frontend UI changes, removed sass
parent
d17a3e2384
commit
5a2afd9672
|
@ -9,6 +9,8 @@
|
|||
- Modified Service view page, updated Latency and Ping charts, added failures below
|
||||
- Modified Service chart on index page to show ping data along with latency
|
||||
- Added AWS SNS Notifier
|
||||
- Modified dashboard services UI
|
||||
- Removed sass dependency, now generates css from scss directly from go
|
||||
|
||||
# 0.90.63 (08-17-2020)
|
||||
- Modified build process to use xgo for all arch builds
|
||||
|
|
|
@ -5,14 +5,12 @@ FROM alpine:latest
|
|||
RUN apk --no-cache add libgcc libstdc++ ca-certificates curl jq && update-ca-certificates
|
||||
|
||||
COPY --from=base /go/bin/statping /usr/local/bin/
|
||||
COPY --from=base /root/sassc/bin/sassc /usr/local/bin/
|
||||
COPY --from=base /usr/local/share/ca-certificates /usr/local/share/
|
||||
|
||||
WORKDIR /app
|
||||
VOLUME /app
|
||||
|
||||
ENV IS_DOCKER=true
|
||||
ENV SASS=/usr/local/bin/sassc
|
||||
ENV STATPING_DIR=/app
|
||||
ENV PORT=8080
|
||||
|
||||
|
|
|
@ -20,11 +20,6 @@ RUN apk add --update --no-cache libstdc++ gcc g++ make git autoconf \
|
|||
libtool ca-certificates linux-headers wget curl jq && \
|
||||
update-ca-certificates
|
||||
|
||||
WORKDIR /root
|
||||
RUN git clone https://github.com/sass/sassc.git
|
||||
RUN . sassc/script/bootstrap && make -C sassc -j4
|
||||
# sassc binary: /root/sassc/bin/sassc
|
||||
|
||||
WORKDIR /go/src/github.com/statping/statping
|
||||
ADD go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
@ -41,5 +36,4 @@ RUN make clean generate embed
|
|||
RUN go build -a -ldflags "-s -w -extldflags -static -X main.VERSION=${VERSION} -X main.COMMIT=${COMMIT}" -o statping --tags "netgo linux" ./cmd
|
||||
RUN chmod a+x statping && mv statping /go/bin/statping
|
||||
# /go/bin/statping - statping binary
|
||||
# /root/sassc/bin/sassc - sass binary
|
||||
# /statping - Vue frontend (from frontend)
|
||||
|
|
|
@ -8,7 +8,7 @@ const tokenKey = "statping_auth";
|
|||
class Api {
|
||||
constructor() {
|
||||
this.version = "0.90.64";
|
||||
this.commit = "2e5fcabc96739d64903d27b3dc1884450056736f";
|
||||
this.commit = "d17a3e2384c18e41cd81109f3ac7b42c18481a6d";
|
||||
}
|
||||
|
||||
async oauth() {
|
||||
|
|
|
@ -83,13 +83,13 @@
|
|||
}
|
||||
|
||||
.chartmarker {
|
||||
padding: 5px;
|
||||
width: 240px;
|
||||
padding: 0px;
|
||||
width: 200px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.chartmarker SPAN {
|
||||
font-size: 9pt;
|
||||
font-size: 4pt;
|
||||
display: block;
|
||||
color: #8b8b8b;
|
||||
}
|
||||
|
@ -176,10 +176,6 @@
|
|||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
.service_li {
|
||||
min-height: 115px !important;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
line-height: 1.3;
|
||||
font-size: 0.75rem;
|
||||
|
@ -311,10 +307,6 @@
|
|||
color: #a0a0a0;
|
||||
}
|
||||
|
||||
.service_block {
|
||||
min-height: 340px;
|
||||
}
|
||||
|
||||
.json-field {
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
|
|
@ -92,13 +92,34 @@ A:HOVER {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.dashboard_card {
|
||||
background-color: $group-list-background;
|
||||
box-shadow: rgba(0,0,0,.05) 0px 2px 3px 1px;
|
||||
}
|
||||
|
||||
.dashboard_card:HOVER {
|
||||
background-color: lighten($group-list-background, 2%) !important;
|
||||
box-shadow: rgba(0,0,0,.05) 0px 1px 5px 3px;
|
||||
-webkit-transition-duration: 300ms;
|
||||
-moz-transition-duration: 300ms;
|
||||
-o-transition-duration: 300ms;
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
min-height: 85pt;
|
||||
background-color: $group-list-background;
|
||||
}
|
||||
|
||||
.list-group-item:HOVER {
|
||||
background-color: lighten($group-list-background, 2%) !important;
|
||||
background-color: lighten($group-list-background, 5%) !important;
|
||||
box-shadow: #00000014 0px 4px 4px 2px;
|
||||
-webkit-transition-duration: 300ms;
|
||||
-moz-transition-duration: 300ms;
|
||||
-o-transition-duration: 300ms;
|
||||
transition-duration: 300ms;
|
||||
margin-top: -1px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.list-group-item A {
|
||||
|
@ -118,18 +139,33 @@ A:HOVER {
|
|||
background-color: $container-color;
|
||||
}
|
||||
|
||||
.login_container {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, 0.15) !important;
|
||||
background-color: $container-color;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-decoration: none;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.footer A {
|
||||
.footer .links {
|
||||
color: $footer-text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer A:HOVER {
|
||||
color: #6d6d6d;
|
||||
.footer .links:HOVER {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.footer .statping {
|
||||
color: lighten($footer-text-color, 10%);
|
||||
text-decoration: none;
|
||||
}
|
||||
.footer .statping:HOVER {
|
||||
color: lighten($footer-text-color, 0%);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.no-select {
|
||||
|
|
|
@ -40,10 +40,6 @@
|
|||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.service_li {
|
||||
border: 1px solid #f3f3f3 !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0px !important;
|
||||
padding-top: 0vh !important;
|
||||
|
|
|
@ -8,7 +8,7 @@ $description-color: #828282;
|
|||
$subtitle-color: #747474;
|
||||
$mobile-card-shadow: 2px 3px 10px #b7b7b7;
|
||||
|
||||
$group-list-background: #fafafa;
|
||||
$group-list-background: #fcfcfc;
|
||||
$group-list-title: #474747;
|
||||
$navbar-color: #1c1c1c;
|
||||
$navbar-background: #ffffff;
|
||||
|
@ -35,7 +35,7 @@ $danger-color: #dd3545;
|
|||
$primary-color: #3e9bff;
|
||||
|
||||
/* Footer Settings */
|
||||
$footer-text-color: #8d8d8d;
|
||||
$footer-text-color: #b0b0b0;
|
||||
$nav-tab-color: #13a00d;
|
||||
$footer-display: block;
|
||||
|
||||
|
|
|
@ -30,13 +30,12 @@
|
|||
<span class="d-block small text-muted mt-3">
|
||||
Starts at <strong>{{niceDate(message.start_on)}}</strong> till <strong>{{niceDate(message.end_on)}}</strong>
|
||||
({{dur(parseISO(message.start_on), parseISO(message.end_on))}})
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-for="(service, index) in services" class="service_block" v-bind:key="index">
|
||||
<ServiceInfo :service=service />
|
||||
</div>
|
||||
<div class="row">
|
||||
<ServiceInfo v-for="(service, index) in services" v-bind:key="index" :service="service" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
<template>
|
||||
<div>
|
||||
<Loading :loading="!loaded"/>
|
||||
<div v-if="loaded && !service.online" class="bg-white shadow-sm mt-3 p-3 pr-4 pl-4 col-12">
|
||||
<font-awesome-icon icon="exclamation" class="mr-3" size="1x"/>
|
||||
Last failure was {{ago(service.last_error)}} ago.
|
||||
<code v-if="failure" class="d-block bg-light p-3 mt-3">
|
||||
{{failure.issue}}
|
||||
<span class="d-block text-dim float-right small mt-3 mb-1">Failure #{{failure.id}}</span>
|
||||
</code>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="message in $store.getters.serviceMessages(service.id)" class="bg-light shadow-sm p-3 pr-4 pl-4 col-12 mt-3">
|
||||
<font-awesome-icon icon="calendar" class="mr-3" size="1x"/> {{message.description}}
|
||||
<span class="d-block small text-muted mt-3">
|
||||
Starts at <strong>{{niceDate(message.start_on)}}</strong> till <strong>{{niceDate(message.end_on)}}</strong>
|
||||
({{dur(parseISO(message.start_on), parseISO(message.end_on))}})
|
||||
<div v-if="loaded && isBefore(nowSubtract(86400), service.last_error)" class="text-danger font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="exclamation" class="mr-1 text-danger" size="1x"/> Recent Failure<br>
|
||||
<span class="font-italic d-inline-block text-dim" style="max-width: 270px">
|
||||
Last failure was {{ago(service.last_error)}} ago. {{service.failures[0].issue}}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="incident in incidents" class="bg-light shadow-sm p-3 pr-4 pl-4 col-12 mt-3">
|
||||
<font-awesome-icon icon="calendar" class="mr-3" size="1x"/>
|
||||
{{incident.title}} - {{incident.description}}
|
||||
<div v-for="update in incident.updates" class="d-block small">
|
||||
<span class="font-weight-bold text-capitalize">{{update.type}}</span> - {{update.message}}
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="loaded" v-for="message in messages" class="font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="calendar" class="mr-1" size="1x"/> Upcoming Announcement<br>
|
||||
<span class="font-italic font-weight-light">{{message.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light">@ <strong>{{niceDate(message.start_on)}}</strong>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="incident in incidents" class="font-2 p-0 m-0 mb-2">
|
||||
<font-awesome-icon icon="bullhorn" class="mr-1" size="1x"/>Recent Incident<br>
|
||||
<span class="font-italic d-inline-block text-truncate" style="max-width: 270px">{{incident.title}} - {{incident.description}}</span>
|
||||
<span class="font-0 text-dim float-right font-weight-light">@ <strong>{{niceDate(incident.created_at)}}</strong></span>
|
||||
</div>
|
||||
|
||||
<div v-if="success_event" class="font-2 p-0 m-0 mt-1 mb-3">
|
||||
<span class="text-success"><font-awesome-icon icon="check" class="mr-1" size="1x"/>No New Events</span>
|
||||
<span class="font-italic d-inline-block text-truncate text-dim" style="max-width: 270px">Last failure was {{ago(service.last_error)}} ago.</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -34,7 +37,6 @@ export default {
|
|||
name: "ServiceEvents",
|
||||
components: {
|
||||
Loading
|
||||
|
||||
},
|
||||
props: {
|
||||
service: {
|
||||
|
@ -55,13 +57,19 @@ name: "ServiceEvents",
|
|||
computed: {
|
||||
messages() {
|
||||
return this.$store.getters.serviceMessages(this.service.id)
|
||||
},
|
||||
success_event() {
|
||||
if (this.service.online && this.service.messages.length === 0 && this.service.incidents.length === 0) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async load() {
|
||||
this.loaded = false
|
||||
if (!this.service.online) {
|
||||
await this.getFailure()
|
||||
this.failure = this.service.failures[0]
|
||||
}
|
||||
await this.getMessages()
|
||||
await this.getIncidents()
|
||||
|
@ -70,10 +78,6 @@ name: "ServiceEvents",
|
|||
async getMessages() {
|
||||
// this.messages = this.$store.getters.serviceMessages(this.service.id)
|
||||
},
|
||||
async getFailure() {
|
||||
const f = await Api.service_failures(this.service.id, null, null, 1)
|
||||
this.failure = f[0]
|
||||
},
|
||||
async getIncidents() {
|
||||
this.incidents = await Api.incidents_service(this.service.id)
|
||||
},
|
||||
|
|
|
@ -1,64 +1,59 @@
|
|||
<template>
|
||||
<div class="card mb-4" :class="{'offline-card': !service.online}">
|
||||
<div class="col-4">
|
||||
<div class="dashboard_card card mb-4" :class="{'offline-card': !service.online}">
|
||||
<div class="card-header pb-1">
|
||||
<h4 v-observe-visibility="setVisible">
|
||||
<h6 v-observe-visibility="setVisible">
|
||||
<router-link :to="serviceLink(service)">{{service.name}}</router-link>
|
||||
<span class="badge float-right text-uppercase" :class="{'badge-success': service.online, 'badge-danger': !service.online}">
|
||||
{{service.online ? $t('online') : $t('offline')}}
|
||||
</span>
|
||||
</h4>
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<transition name="fade">
|
||||
<div v-if="loaded" class="row pl-2 pr-2">
|
||||
<div class="col-md-6 col-sm-12 mt-2 mt-md-0 mb-3">
|
||||
<ServiceSparkLine :title="set2_name" subtitle="Latency Last 24 Hours" :series="set2"/>
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12 mt-4 mt-md-0 mb-3">
|
||||
<ServiceSparkLine :title="set1_name" subtitle="Latency Last 7 Days" :series="set1"/>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-2 mt-md-0 mb-3">
|
||||
<ServiceEvents :service="service"/>
|
||||
<div class="col-md-6 col-sm-12 mt-2 mt-md-0 mb-3 pl-0 pr-0">
|
||||
<ServiceSparkLine :title="set2_name" subtitle="Latency Last 24 Hours" :series="set2"/>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-sm-12 mt-4 mt-md-0 mb-3">
|
||||
<ServiceSparkLine :title="set1_name" subtitle="Latency Last 7 Days" :series="set1"/>
|
||||
</div>
|
||||
<ServiceEvents :service="service"/>
|
||||
</div>
|
||||
<div v-else class="row mt-5 mb-5 pt-5 pb-5">
|
||||
<div class="col-6 text-center text-muted">
|
||||
<font-awesome-icon icon="circle-notch" size="3x" spin/>
|
||||
<div v-else class="row mb-5 pt-5 pb-5">
|
||||
<div class="col-6 text-center">
|
||||
<font-awesome-icon icon="circle-notch" class="text-dim" size="3x" spin/>
|
||||
</div>
|
||||
<div class="col-6 text-center text-muted">
|
||||
<font-awesome-icon icon="circle-notch" size="3x" spin/>
|
||||
<div class="col-6 text-center text-dim">
|
||||
<font-awesome-icon icon="circle-notch" class="text-dim" size="3x" spin/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-12 col-md-3 mb-2 mb-md-0">
|
||||
<router-link :to="{path: `/dashboard/service/${service.id}/incidents`, params: {id: service.id} }" class="btn btn-block btn-white text-capitalize incident">
|
||||
{{$tc('incident', 2)}}
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="col-12 col-md-3 mb-2 mb-md-0">
|
||||
<router-link :to="{path: `/dashboard/service/${service.id}/checkins`, params: {id: service.id} }" class="btn btn-block btn-white text-capitalize checkins">
|
||||
{{$tc('checkin', 2)}}
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="col-12 col-md-3 mb-2 mb-md-0">
|
||||
<router-link :to="{path: `/dashboard/service/${service.id}/failures`, params: {id: service.id} }" class="btn btn-block btn-white text-capitalize failures">
|
||||
{{$tc('failure', 2)}} <span class="badge badge-danger float-right mt-1">{{service.stats.failures}}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="col-12 col-md-3 mb-2 mb-md-0 mt-0 mt-md-1">
|
||||
<span class="float-md-right">
|
||||
{{$t('uptime', [service.online_7_days])}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-5 pr-0">
|
||||
<span class="small text-dim"> {{ hoverbtn }}</span>
|
||||
</div>
|
||||
|
||||
<div class="col-7 pr-2 pl-0">
|
||||
<div class="btn-group float-right">
|
||||
<button @click="$router.push({path: `/dashboard/service/${service.id}/incidents`, params: {id: service.id}})" @mouseleave="unsetHover" @mouseover="setHover('Incidents')" class="btn btn-sm btn-white incident">
|
||||
<font-awesome-icon icon="bullhorn"/>
|
||||
</button>
|
||||
<button @click="$router.push({path: `/dashboard/service/${service.id}/checkins`, params: {id: service.id}})" @mouseleave="unsetHover" @mouseover="setHover('Checkins')" class="btn btn-sm btn-white checkins">
|
||||
<font-awesome-icon icon="calendar-check"/>
|
||||
</button>
|
||||
<button @click="$router.push({path: `/dashboard/service/${service.id}/failures`, params: {id: service.id}})" @mouseleave="unsetHover" @mouseover="setHover('Failures')" class="btn btn-sm btn-white failures">
|
||||
<font-awesome-icon icon="exclamation-triangle"/> <span v-if="service.stats.failures !== 0" class="badge badge-danger ml-1">{{service.stats.failures}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<span v-for="(failure, index) in failures" v-bind:key="index" class="alert alert-light">
|
||||
|
@ -67,6 +62,7 @@
|
|||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -96,6 +92,8 @@
|
|||
data() {
|
||||
return {
|
||||
uptime: null,
|
||||
hovered: false,
|
||||
hoverbtn: "",
|
||||
openTab: "",
|
||||
set1: [],
|
||||
set2: [],
|
||||
|
@ -109,7 +107,16 @@
|
|||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
mounted() {
|
||||
this.unsetHover()
|
||||
},
|
||||
methods: {
|
||||
setHover(name) {
|
||||
this.hoverbtn = name
|
||||
},
|
||||
unsetHover() {
|
||||
this.hoverbtn = this.$t('uptime', [this.service.online_7_days])
|
||||
},
|
||||
async setVisible(isVisible, entry) {
|
||||
if (isVisible && !this.visible) {
|
||||
await this.loadInfo()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template v-if="series.length">
|
||||
<apexchart width="100%" height="180" type="bar" :options="chartOpts" :series="series"></apexchart>
|
||||
<apexchart width="100%" height="100" type="bar" :options="chartOpts" :series="series"></apexchart>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -37,6 +37,9 @@
|
|||
enabled: true
|
||||
},
|
||||
},
|
||||
showPoint: false,
|
||||
fullWidth:true,
|
||||
chartPadding: {top: 0,right: 0,bottom: 0,left: 0},
|
||||
stroke: {
|
||||
curve: 'straight'
|
||||
},
|
||||
|
@ -50,12 +53,11 @@
|
|||
tooltip: {
|
||||
theme: false,
|
||||
enabled: true,
|
||||
custom: function({series, seriesIndex, dataPointIndex, w}) {
|
||||
custom: ({series, seriesIndex, dataPointIndex, w}) => {
|
||||
let ts = w.globals.seriesX[seriesIndex][dataPointIndex];
|
||||
const dt = new Date(ts).toLocaleDateString("en-us", timeoptions)
|
||||
let val = series[seriesIndex][dataPointIndex];
|
||||
val = val + " ms"
|
||||
return `<div class="chartmarker"><span>Average Response Time: </span><span class="font-3">${val}</span><span>${dt}</span></div>`
|
||||
return `<div class="chartmarker"><span>Average Response Time: </span><span class="font-3">${this.humanTime(val)}</span><span>${dt}</span></div>`
|
||||
},
|
||||
fixed: {
|
||||
enabled: true,
|
||||
|
@ -74,15 +76,16 @@
|
|||
text: this.title,
|
||||
offsetX: 0,
|
||||
style: {
|
||||
fontSize: '28px',
|
||||
fontSize: '18px',
|
||||
cssClass: 'apexcharts-yaxis-title'
|
||||
}
|
||||
},
|
||||
subtitle: {
|
||||
text: this.subtitle,
|
||||
offsetX: 0,
|
||||
offsetY: 20,
|
||||
style: {
|
||||
fontSize: '14px',
|
||||
fontSize: '9px',
|
||||
cssClass: 'apexcharts-yaxis-title'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<div v-if="!core.footer" class="footer text-center mb-4 p-2">
|
||||
<div class="d-block text-dim">
|
||||
<div class="mb-3">
|
||||
<router-link :to="admin ? '/dashboard' : '/login'">{{$t('top_nav.dashboard')}}</router-link>
|
||||
<router-link class="links" :to="admin ? '/dashboard' : '/login'">{{$t('top_nav.dashboard')}}</router-link>
|
||||
</div>
|
||||
<span class="text-muted font-1 mt-3">
|
||||
<a href="https://github.com/statping/statping" target="_blank">Statping v{{core.version}}
|
||||
made with <font-awesome-icon icon="heart" class="font-1 text-danger"/></a>
|
||||
<span class="font-1 mt-3">
|
||||
<a href="https://github.com/statping/statping" class="statping" target="_blank">
|
||||
Statping v{{core.version}} made with <font-awesome-icon icon="heart" class="hlight font-1"/></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,6 +37,8 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
.hlight {
|
||||
color: #f6cbcb;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<h4 v-if="group.name !== 'Empty Group'" class="group_header mb-3 mt-4">{{group.name}}</h4>
|
||||
<div class="list-group online_list mb-4">
|
||||
|
||||
<div v-for="(service, index) in services" v-bind:key="index" class="service_li list-group-item list-group-item-action">
|
||||
<div v-for="(service, index) in services" v-bind:key="index" class="list-group-item list-group-item-action">
|
||||
<router-link class="no-decoration font-3" :to="serviceLink(service)">{{service.name}}</router-link>
|
||||
<span class="badge text-uppercase float-right" :class="{'bg-success': service.online, 'bg-danger': !service.online }">
|
||||
{{service.online ? $t('online') : $t('offline')}}
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
<div>
|
||||
<form @submit.prevent="login" autocomplete="on">
|
||||
<div class="form-group row">
|
||||
<label for="username" class="col-sm-2 col-form-label">{{$t('username')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input @keyup="checkForm" type="text" v-model="username" autocomplete="username" name="username" class="form-control" id="username" placeholder="Username" autocorrect="off" autocapitalize="none">
|
||||
<label for="username" class="col-4 col-md-3 col-form-label">{{$t('username')}}</label>
|
||||
<div class="col-8 col-md-9">
|
||||
<input @keyup="checkForm" type="text" v-model="username" autocomplete="username" name="username" class="form-control" id="username" placeholder="admin" autocorrect="off" autocapitalize="none">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-sm-2 col-form-label">{{$t('password')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input @keyup="checkForm" type="password" v-model="password" autocomplete="current-password" name="password" class="form-control" id="password" placeholder="Password">
|
||||
<label for="password" class="col-4 col-md-3 col-form-label">{{$t('password')}}</label>
|
||||
<div class="col-8 col-md-9">
|
||||
<input @keyup="checkForm" type="password" v-model="password" autocomplete="current-password" name="password" class="form-control" id="password" placeholder="password123">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
@ -18,14 +18,14 @@
|
|||
<div v-if="error" class="alert alert-danger" role="alert">
|
||||
{{$t('dashboard.wrong_login')}}
|
||||
</div>
|
||||
<button @click.prevent="login" type="submit" class="btn btn-block mb-3 btn-primary" :disabled="disabled || loading">
|
||||
<button @click.prevent="login" type="submit" class="btn btn-block btn-primary" :disabled="disabled || loading">
|
||||
<font-awesome-icon v-if="loading" icon="circle-notch" class="mr-2" spin/>{{loading ? $t('dashboard.loading') : $t('dashboard.sign_in')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<a v-if="oauth && oauth.gh_client_id" @click.prevent="GHlogin" href="#" class="btn btn-block btn-outline-dark">
|
||||
<a v-if="oauth && oauth.gh_client_id" @click.prevent="GHlogin" href="#" class="mt-4 btn btn-block btn-outline-dark">
|
||||
<font-awesome-icon :icon="['fab', 'github']" /> Login with Github
|
||||
</a>
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
<div class="card contain-card mb-4">
|
||||
<div class="card-header">{{ $t('service.info') }}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{{ $t('service.name') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="service.name" @input="updatePermalink" id="name" type="text" name="name" class="form-control" placeholder="Server Name" required spellcheck="false" autocorrect="off">
|
||||
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{{ $t('service.name') }}</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="service.name" @input="updatePermalink" id="name" type="text" name="name" class="form-control" placeholder="Server Name" required spellcheck="false" autocorrect="off">
|
||||
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="service_type" class="col-sm-4 col-form-label">{{ $t('service.type') }}</label>
|
||||
<div class="col-sm-8">
|
||||
|
@ -61,7 +61,7 @@
|
|||
<small id="interval" class="form-text text-muted">Interval to check your service state</small>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<input v-model="service.check_interval" type="text" name="check_interval" class="form-control">
|
||||
<input v-model="service.check_interval" type="number" name="check_interval" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -73,9 +73,11 @@
|
|||
<div class="card-body">
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="service_url" class="col-sm-4 col-form-label">Service Endpoint {{service.type === 'http' ? "(URL)" : "(Domain)"}}</label>
|
||||
<label for="service_url" class="col-sm-4 col-form-label">
|
||||
Service Endpoint {{service.type === 'http' ? "(URL)" : "(Domain)"}}
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
<input v-model="service.domain" type="text" class="form-control" id="service_url" :placeholder="service.type === 'http' ? 'https://google.com' : '192.168.1.1'" required autocapitalize="none" spellcheck="false">
|
||||
<input v-model="service.domain" type="url" class="form-control" id="service_url" :placeholder="service.type === 'http' ? 'https://google.com' : '192.168.1.1'" required autocapitalize="none" spellcheck="false">
|
||||
<small class="form-text text-muted">Statping will attempt to connect to this address</small>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -110,7 +112,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<input v-model="service.timeout" type="text" name="service_timeout" class="form-control">
|
||||
<input v-model="service.timeout" type="number" name="service_timeout" class="form-control">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import Vue from "vue";
|
||||
const { startOfToday, startOfMonth, lastDayOfMonth, subSeconds, getUnixTime, fromUnixTime, differenceInSeconds, formatDistance, addMonths, addSeconds, isWithinInterval } = require('date-fns')
|
||||
const { endOfTomorrow, endOfToday, endOfDay, startOfToday, startOfMonth, lastDayOfMonth, subSeconds, getUnixTime, fromUnixTime, differenceInSeconds, formatDistance, addMonths, addSeconds, isWithinInterval } = require('date-fns')
|
||||
import formatDistanceToNow from 'date-fns/formatDistanceToNow'
|
||||
import format from 'date-fns/format'
|
||||
import parseISO from 'date-fns/parseISO'
|
||||
import isBefore from 'date-fns/isBefore'
|
||||
import isAfter from 'date-fns/isAfter'
|
||||
import { roundToNearestMinutes } from 'date-fns'
|
||||
|
||||
export default Vue.mixin({
|
||||
methods: {
|
||||
|
@ -53,6 +54,20 @@ export default Vue.mixin({
|
|||
parseISO(v) {
|
||||
return parseISO(v)
|
||||
},
|
||||
round(minutes) {
|
||||
return roundToNearestMinutes(minutes)
|
||||
},
|
||||
endOf(method, val) {
|
||||
switch (val) {
|
||||
case "day":
|
||||
return endOfDay(val)
|
||||
case "today":
|
||||
return endOfToday()
|
||||
case "tomorrow":
|
||||
return endOfTomorrow()
|
||||
}
|
||||
return roundToNearestMinutes(val)
|
||||
},
|
||||
isZero(val) {
|
||||
return getUnixTime(parseISO(val)) <= 0
|
||||
},
|
||||
|
|
|
@ -2275,7 +2275,7 @@ OluFxewsEO0QNDrfFb+0gnjYlnGqOFcZjUMXbDdY5oLSPtXohynuTK1qyQ==
|
|||
</div>
|
||||
|
||||
<div class="text-center small text-dim" v-pre>
|
||||
Automatically generated from Statping's Wiki on 2020-08-20 20:45:46.398081 +0000 UTC
|
||||
Automatically generated from Statping's Wiki on 2020-08-21 04:07:11.080469 +0000 UTC
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<div class="col-12 full-col-12">
|
||||
<div v-for="service in services_no_group" v-bind:key="service.id" class="list-group online_list mb-4">
|
||||
<div class="service_li list-group-item list-group-item-action">
|
||||
<div class="list-group-item list-group-item-action">
|
||||
<router-link class="no-decoration font-3" :to="serviceLink(service)">{{service.name}}</router-link>
|
||||
<span class="badge float-right" :class="{'bg-success': service.online, 'bg-danger': !service.online }">{{service.online ? "ONLINE" : "OFFLINE"}}</span>
|
||||
<GroupServiceFailures :service="service"/>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<template>
|
||||
<div class="container col-md-7 col-sm-12 mt-md-5">
|
||||
<div class="col-10 offset-1 col-md-8 offset-md-2 mt-md-2">
|
||||
<div class="col-12 col-md-8 offset-md-2 mb-4">
|
||||
<img alt="Statping Login" class="col-12 mt-5 mt-md-0" style="max-width:650px" src="banner.png">
|
||||
</div>
|
||||
<div class="offset-md-3 offset-0 col-md-6 mt-5">
|
||||
|
||||
<div class="offset-1 col-10 mb-4 mb-md-3">
|
||||
<img alt="Statping Login" class="embed-responsive" src="banner.png">
|
||||
</div>
|
||||
|
||||
<div class="login_container col-12 p-4">
|
||||
<FormLogin/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
3
go.mod
3
go.mod
|
@ -13,7 +13,6 @@ require (
|
|||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/getsentry/sentry-go v0.5.1
|
||||
github.com/go-mail/mail v2.3.1+incompatible
|
||||
github.com/gomarkdown/markdown v0.0.0-20200817091206-6efd7696db82
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/hako/durafmt v0.0.0-20200605151348-3a43fc422dd9
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
|
@ -30,7 +29,7 @@ require (
|
|||
github.com/spf13/viper v1.6.3
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1
|
||||
github.com/tdewolff/minify/v2 v2.8.0 // indirect
|
||||
github.com/wellington/go-libsass v0.9.2
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
|
|
14
go.sum
14
go.sum
|
@ -114,7 +114,6 @@ github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
@ -254,8 +253,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200817091206-6efd7696db82 h1:2EHQMBglPpettuq2LG+2NRGHhVaRYhxgwPTcgpXVXz8=
|
||||
github.com/gomarkdown/markdown v0.0.0-20200817091206-6efd7696db82/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
@ -400,7 +397,6 @@ github.com/liquidweb/liquidweb-go v1.6.1/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVL
|
|||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
|
@ -578,13 +574,6 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
|
|||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1 h1:HGVkRrwDCbmSP6h1CoBDj6l/mhnvsP5JbYaQ4ss0R6o=
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1/go.mod h1:I3xbaE9ud9/TEXzehwkHx86SyJwqeSNsX2X5oV61jIg=
|
||||
github.com/tdewolff/minify v1.1.0 h1:nxHQi1ML+g3ZbZHffiZ6eC7vMqNvSRfX3KB5Y5y/kfw=
|
||||
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
|
||||
github.com/tdewolff/minify/v2 v2.8.0 h1:t3tOPWkTpKhsgxm3IM9Sy8hE2eIt30Oaa+2havJGGIE=
|
||||
github.com/tdewolff/minify/v2 v2.8.0/go.mod h1:6zN8VLhMfFxNrwHROcboYNo2+huPNu4SV8DPh3PUQ8E=
|
||||
github.com/tdewolff/parse/v2 v2.4.4 h1:uMdbQRtYbKR/msP9CbI7li9wK6pionYiH6s7ipltyGY=
|
||||
github.com/tdewolff/parse/v2 v2.4.4/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -608,6 +597,8 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV
|
|||
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
|
||||
github.com/vultr/govultr v0.3.3 h1:fVaF4h9u3VzTXxFsxvgBUCiM52EiahLqAPkizamLzYM=
|
||||
github.com/vultr/govultr v0.3.3/go.mod h1:TUuUizMOFc7z+PNMssb6iGjKjQfpw5arIaOLfocVudQ=
|
||||
github.com/wellington/go-libsass v0.9.2 h1:6Ims04UDdBs6/CGSVK5JC8FNikR5ssrsMMKE/uaO5Q8=
|
||||
github.com/wellington/go-libsass v0.9.2/go.mod h1:mxgxgam0N0E+NAUMHLcu20Ccfc3mVpDkyrLDayqfiTs=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
|
@ -634,7 +625,6 @@ go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZ
|
|||
go.uber.org/ratelimit v0.1.0 h1:U2AruXqeTb4Eh9sYQSTrMhH8Cb7M0Ian2ibBOnBcnAw=
|
||||
go.uber.org/ratelimit v0.1.0/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
|
|
@ -22,8 +22,3 @@ func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
returnJson(health, w, r)
|
||||
}
|
||||
|
||||
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
ExecuteResponse(w, r, "base.gohtml", core.App, nil)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/statping/statping/utils"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"time"
|
||||
|
||||
_ "github.com/statping/statping/types/metrics"
|
||||
)
|
||||
|
@ -38,7 +39,7 @@ func Router() *mux.Router {
|
|||
}
|
||||
|
||||
bPath := utils.Params.GetString("BASE_PATH")
|
||||
sentryHandler := sentryhttp.New(sentryhttp.Options{})
|
||||
sentryHandler := sentryhttp.New(sentryhttp.Options{Timeout: 5 * time.Second})
|
||||
|
||||
if bPath != "" {
|
||||
basePath = "/" + bPath + "/"
|
||||
|
@ -180,7 +181,7 @@ func Router() *mux.Router {
|
|||
// API Generic Routes
|
||||
r.Handle("/metrics", readOnly(promhttp.Handler(), false))
|
||||
r.Handle("/health", http.HandlerFunc(healthCheckHandler))
|
||||
r.NotFoundHandler = http.HandlerFunc(notFoundHandler)
|
||||
r.NotFoundHandler = http.HandlerFunc(indexHandler)
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,13 @@ package source
|
|||
//go:generate go run generate_version.go
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.rice"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/statping/statping/utils"
|
||||
"github.com/wellington/go-libsass"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
@ -58,30 +59,28 @@ func scssRendered(name string) string {
|
|||
|
||||
// CompileSASS will attempt to compile the SASS files into CSS
|
||||
func CompileSASS() error {
|
||||
sassBin := utils.Params.GetString("SASS")
|
||||
if sassBin == "" {
|
||||
bin, err := exec.LookPath("sass")
|
||||
if err != nil {
|
||||
log.Warnf("could not find sass executable in PATH: %s", err)
|
||||
return err
|
||||
}
|
||||
sassBin = bin
|
||||
}
|
||||
|
||||
scssFile := filepath.Join(utils.Params.GetString("STATPING_DIR"), "assets", "scss", "index.scss")
|
||||
log.Infoln(fmt.Sprintf("Compiling SASS %v into %v", scssFile, scssRendered(scssFile)))
|
||||
indexCSS := filepath.Join(utils.Params.GetString("STATPING_DIR"), "assets", "scss", "index.css")
|
||||
partials := filepath.Join(utils.Params.GetString("STATPING_DIR"), "assets", "scss")
|
||||
|
||||
stdout, stderr, err := utils.Command(sassBin, scssFile, scssRendered(scssFile))
|
||||
index, err := utils.OpenFile(scssFile)
|
||||
if err != nil {
|
||||
log.Errorln(fmt.Sprintf("Failed to compile assets with SASS %v", err))
|
||||
log.Errorln(fmt.Sprintf("%s %s %s", sassBin, scssFile, scssRendered(scssFile)))
|
||||
return errors.Wrapf(err, "failed to compile assets, %s %s %s", err, stdout, stderr)
|
||||
return err
|
||||
}
|
||||
|
||||
if stdout != "" || stderr != "" {
|
||||
log.Infoln(fmt.Sprintf("out: %v | error: %v", stdout, stderr))
|
||||
w := bytes.NewBuffer(nil)
|
||||
comp, err := libsass.New(w, bytes.NewBufferString(index))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = comp.Option(libsass.IncludePaths([]string{partials})); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := comp.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := utils.SaveFile(indexCSS, w.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infoln("SASS Compiling is complete!")
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue