2021-06-25 13:55:49 +00:00
< template >
2021-08-19 18:37:59 +00:00
< transition name = "slide-fade" appear >
2021-08-23 08:59:27 +00:00
< div v-if = "monitor" >
2021-08-19 18:37:59 +00:00
< h1 > { { monitor . name } } < / h1 >
2021-08-26 10:55:19 +00:00
< div class = "tags" >
< Tag v-for = "tag in monitor.tags" :key="tag.id" :item="tag" :size="'sm'" / >
< / div >
2021-08-19 18:37:59 +00:00
< p class = "url" >
< a v-if = "monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank" > {{ monitor.url }} < / a >
< span v-if = "monitor.type === 'port'" > TCP Ping {{ monitor.hostname }} : {{ monitor.port }} < / span >
< span v-if = "monitor.type === 'ping'" > Ping : {{ monitor.hostname }} < / span >
< span v-if = "monitor.type === 'keyword'" >
< br >
2021-08-26 00:43:26 +00:00
< span > { { $t ( "Keyword" ) } } : < / span > < span class = "keyword" > { { monitor . keyword } } < / span >
2021-08-19 18:37:59 +00:00
< / span >
2021-08-29 01:57:26 +00:00
< span v-if = "monitor.type === 'dns'" > [ {{ monitor.dns_resolve_type }} ] {{ monitor.hostname }}
< br >
< span > { { $t ( "Last Result" ) } } : < / span > < span class = "keyword" > { { monitor . dns _last _result } } < / span >
< / span >
2021-08-19 18:37:59 +00:00
< / p >
2021-06-25 13:55:49 +00:00
2021-08-19 18:37:59 +00:00
< div class = "functions" >
< button v-if = "monitor.active" class="btn btn-light" @click="pauseDialog" >
2021-08-24 10:26:44 +00:00
< font-awesome-icon icon = "pause" / > { { $t ( "Pause" ) } }
2021-08-19 18:37:59 +00:00
< / button >
< button v-if = "! monitor.active" class="btn btn-primary" @click="resumeMonitor" >
2021-08-24 10:26:44 +00:00
< font-awesome-icon icon = "play" / > { { $t ( "Resume" ) } }
2021-08-19 18:37:59 +00:00
< / button >
< router-link : to = " '/edit/' + monitor.id " class = "btn btn-secondary" >
2021-08-24 10:26:44 +00:00
< font-awesome-icon icon = "edit" / > { { $t ( "Edit" ) } }
2021-08-19 18:37:59 +00:00
< / router-link >
< button class = "btn btn-danger" @click ="deleteDialog" >
2021-08-24 10:26:44 +00:00
< font-awesome-icon icon = "trash" / > { { $t ( "Delete" ) } }
2021-08-19 18:37:59 +00:00
< / button >
2021-06-25 13:55:49 +00:00
< / div >
2021-08-19 18:37:59 +00:00
< div class = "shadow-box" >
< div class = "row" >
< div class = "col-md-8" >
< HeartbeatBar :monitor-id = "monitor.id" / >
2021-08-24 10:26:44 +00:00
< span class = "word" > { { $t ( "checkEverySecond" , [ monitor . interval ] ) } } < / span >
2021-08-19 18:37:59 +00:00
< / div >
< div class = "col-md-4 text-center" >
2021-10-16 09:32:15 +00:00
< span class = "badge rounded-pill" : class = " 'bg-' + status.color " style = "font-size: 30px;" > { { $t ( status . text ) } } < / span >
2021-08-19 18:37:59 +00:00
< / div >
< / div >
2021-06-30 13:04:58 +00:00
< / div >
2021-07-26 14:53:07 +00:00
2021-08-19 18:37:59 +00:00
< div class = "shadow-box big-padding text-center stats" >
< div class = "row" >
< div class = "col" >
2021-09-19 13:15:12 +00:00
< h4 > { { pingTitle ( ) } } < / h4 >
2021-08-24 10:26:44 +00:00
< p > ( { { $t ( "Current" ) } } ) < / p >
2021-08-19 18:37:59 +00:00
< span class = "num" >
< a href = "#" @ click.prevent = " showPingChartBox = ! showPingChartBox " >
< CountUp :value = "ping" / >
< / a >
< / span >
< / div >
< div class = "col" >
2021-09-19 13:15:12 +00:00
< h4 > { { pingTitle ( true ) } } < / h4 >
2021-08-24 10:26:44 +00:00
< p > ( 24 { { $t ( "-hour" ) } } ) < / p >
2021-08-19 18:37:59 +00:00
< span class = "num" > < CountUp :value = "avgPing" / > < / span >
< / div >
< div class = "col" >
2021-08-24 10:26:44 +00:00
< h4 > { { $t ( "Uptime" ) } } < / h4 >
< p > ( 24 { { $t ( "-hour" ) } } ) < / p >
2021-08-19 18:37:59 +00:00
< span class = "num" > < Uptime :monitor = "monitor" type = "24" / > < / span >
< / div >
< div class = "col" >
2021-08-24 10:26:44 +00:00
< h4 > { { $t ( "Uptime" ) } } < / h4 >
< p > ( 30 { { $t ( "-day" ) } } ) < / p >
2021-08-19 18:37:59 +00:00
< span class = "num" > < Uptime :monitor = "monitor" type = "720" / > < / span >
< / div >
2021-10-01 10:44:32 +00:00
< div v-if = "tlsInfo" class="col" >
2021-08-24 10:26:44 +00:00
< h4 > { { $t ( "Cert Exp." ) } } < / h4 >
2021-10-01 10:44:32 +00:00
< p > ( < Datetime :value = "tlsInfo.certInfo.validTo" date -only / > ) < / p >
2021-08-19 18:37:59 +00:00
< span class = "num" >
2021-10-01 10:44:32 +00:00
< a href = "#" @ click.prevent = " toggleCertInfoBox = ! toggleCertInfoBox " > { { tlsInfo . certInfo . daysRemaining } } { { $t ( "days" ) } } < / a >
2021-08-19 18:37:59 +00:00
< / span >
< / div >
< / div >
2021-07-26 14:53:07 +00:00
< / div >
2021-06-30 13:04:58 +00:00
2021-10-09 11:08:38 +00:00
<!-- Cert Info Box -- >
2021-08-19 18:37:59 +00:00
< transition name = "slide-fade" appear >
< div v-if = "showCertInfoBox" class="shadow-box big-padding text-center" >
< div class = "row" >
< div class = "col" >
2021-10-01 10:44:32 +00:00
< certificate-info :certInfo = "tlsInfo.certInfo" :valid = "tlsInfo.valid" / >
2021-08-19 18:37:59 +00:00
< / div >
< / div >
< / div >
< / transition >
2021-10-09 11:08:38 +00:00
<!-- Ping Chart -- >
2021-08-19 18:37:59 +00:00
< div v-if = "showPingChartBox" class="shadow-box big-padding text-center ping-chart-wrapper" >
< div class = "row" >
< div class = "col" >
< PingChart :monitor-id = "monitor.id" / >
< / div >
< / div >
2021-08-10 11:34:47 +00:00
< / div >
2021-08-23 18:02:38 +00:00
< div class = "shadow-box table-shadow-box" >
2021-08-29 16:47:01 +00:00
< div class = "dropdown dropdown-clear-data" >
< button class = "btn btn-sm btn-outline-danger dropdown-toggle" type = "button" data -bs -toggle = " dropdown " >
< font-awesome-icon icon = "trash" / > { { $t ( "Clear Data" ) } }
< / button >
< ul class = "dropdown-menu dropdown-menu-end" >
< li >
< button type = "button" class = "dropdown-item" @click ="clearEventsDialog" >
{ { $t ( "Events" ) } }
< / button >
< / li >
< li >
< button type = "button" class = "dropdown-item" @click ="clearHeartbeatsDialog" >
{ { $t ( "Heartbeats" ) } }
< / button >
< / li >
< / ul >
< / div >
2021-08-19 18:37:59 +00:00
< table class = "table table-borderless table-hover" >
< thead >
< tr >
2021-08-24 10:26:44 +00:00
< th > { { $t ( "Status" ) } } < / th >
< th > { { $t ( "DateTime" ) } } < / th >
< th > { { $t ( "Message" ) } } < / th >
2021-07-21 04:09:09 +00:00
< / tr >
2021-08-19 18:37:59 +00:00
< / thead >
< tbody >
2021-08-22 23:22:55 +00:00
< tr v-for = "(beat, index) in displayedRecords" :key="index" :class="{ 'shadow-box': $root.windowWidth <= 550}" style="padding: 10px;" >
2021-08-19 18:37:59 +00:00
< td > < Status :status = "beat.status" / > < / td >
2021-08-22 23:22:55 +00:00
< td : class = "{ 'border-0':! beat.msg}" > < Datetime :value = "beat.time" / > < / td >
< td class = "border-0" > { { beat . msg } } < / td >
2021-07-21 04:09:09 +00:00
< / tr >
2021-08-19 18:37:59 +00:00
< tr v-if = "importantHeartBeatList.length === 0" >
< td colspan = "3" >
2021-08-24 10:26:44 +00:00
{ { $t ( "No important events" ) } }
2021-07-27 17:47:13 +00:00
< / td >
2021-07-21 04:09:09 +00:00
< / tr >
< / tbody >
< / table >
2021-08-19 18:37:59 +00:00
< div class = "d-flex justify-content-center kuma_pagination" >
< pagination
v - model = "page"
: records = "importantHeartBeatList.length"
: per - page = "perPage"
2021-09-26 15:20:12 +00:00
: options = "paginationConfig"
2021-08-19 18:37:59 +00:00
/ >
< / div >
< / div >
2021-06-30 13:04:58 +00:00
2021-08-29 02:03:55 +00:00
< Confirm ref = "confirmPause" :yes-text = "$t('Yes')" :no-text = "$t('No')" @yes ="pauseMonitor" >
{ { $t ( "pauseMonitorMsg" ) } }
2021-08-19 18:37:59 +00:00
< / Confirm >
2021-07-18 01:04:40 +00:00
2021-08-26 00:43:26 +00:00
< Confirm ref = "confirmDelete" btn -style = " btn -danger " :yes-text = "$t('Yes')" :no-text = "$t('No')" @yes ="deleteMonitor" >
{ { $t ( "deleteMonitorMsg" ) } }
2021-08-19 18:37:59 +00:00
< / Confirm >
2021-08-29 16:47:01 +00:00
< Confirm ref = "confirmClearEvents" btn -style = " btn -danger " :yes-text = "$t('Yes')" :no-text = "$t('No')" @yes ="clearEvents" >
{ { $t ( "clearEventsMsg" ) } }
< / Confirm >
< Confirm ref = "confirmClearHeartbeats" btn -style = " btn -danger " :yes-text = "$t('Yes')" :no-text = "$t('No')" @yes ="clearHeartbeats" >
{ { $t ( "clearHeartbeatsMsg" ) } }
< / Confirm >
2021-07-18 01:04:40 +00:00
< / div >
2021-08-19 18:37:59 +00:00
< / transition >
2021-06-25 13:55:49 +00:00
< / template >
< script >
2021-08-11 16:47:58 +00:00
import { defineAsyncComponent } from "vue" ;
2021-10-01 10:44:32 +00:00
import { useToast } from "vue-toastification" ;
const toast = useToast ( ) ;
2021-06-25 13:55:49 +00:00
import Confirm from "../components/Confirm.vue" ;
2021-06-25 19:03:06 +00:00
import HeartbeatBar from "../components/HeartbeatBar.vue" ;
2021-06-30 13:04:58 +00:00
import Status from "../components/Status.vue" ;
import Datetime from "../components/Datetime.vue" ;
import CountUp from "../components/CountUp.vue" ;
2021-07-01 05:11:16 +00:00
import Uptime from "../components/Uptime.vue" ;
2021-07-18 01:04:40 +00:00
import Pagination from "v-pagination-3" ;
2021-08-11 16:47:58 +00:00
const PingChart = defineAsyncComponent ( ( ) => import ( "../components/PingChart.vue" ) ) ;
2021-08-26 10:55:19 +00:00
import Tag from "../components/Tag.vue" ;
2021-10-01 10:44:32 +00:00
import CertificateInfo from "../components/CertificateInfo.vue" ;
2021-06-25 13:55:49 +00:00
export default {
components : {
2021-07-01 05:11:16 +00:00
Uptime ,
2021-06-30 13:04:58 +00:00
CountUp ,
Datetime ,
2021-06-25 19:03:06 +00:00
HeartbeatBar ,
2021-06-30 13:04:58 +00:00
Confirm ,
Status ,
2021-07-18 01:04:40 +00:00
Pagination ,
2021-08-10 11:34:47 +00:00
PingChart ,
2021-08-26 10:55:19 +00:00
Tag ,
2021-10-01 10:44:32 +00:00
CertificateInfo ,
2021-06-25 13:55:49 +00:00
} ,
data ( ) {
return {
2021-07-18 01:04:40 +00:00
page : 1 ,
perPage : 25 ,
heartBeatList : [ ] ,
2021-07-26 14:53:07 +00:00
toggleCertInfoBox : false ,
2021-08-11 12:59:33 +00:00
showPingChartBox : true ,
2021-09-26 15:20:12 +00:00
paginationConfig : {
2021-10-01 10:44:32 +00:00
texts : {
count : ` ${ this . $t ( "Showing {from} to {to} of {count} records" ) } |{count} ${ this . $t ( "records" ) } | ${ this . $t ( "One record" ) } ` ,
first : this . $t ( "First" ) ,
last : this . $t ( "Last" ) ,
nextPage : ">" ,
nextChunk : ">>" ,
prevPage : "<" ,
prevChunk : "<<"
2021-09-26 15:20:12 +00:00
}
}
2021-10-01 10:44:32 +00:00
} ;
2021-06-25 13:55:49 +00:00
} ,
computed : {
monitor ( ) {
2021-10-01 10:44:32 +00:00
let id = this . $route . params . id ;
2021-06-27 08:10:55 +00:00
return this . $root . monitorList [ id ] ;
} ,
2021-06-25 13:55:49 +00:00
2021-06-27 08:10:55 +00:00
lastHeartBeat ( ) {
if ( this . monitor . id in this . $root . lastHeartbeatList && this . $root . lastHeartbeatList [ this . monitor . id ] ) {
2021-10-01 10:44:32 +00:00
return this . $root . lastHeartbeatList [ this . monitor . id ] ;
2021-07-27 17:47:13 +00:00
}
return {
status : - 1 ,
2021-10-01 10:44:32 +00:00
} ;
2021-06-25 13:55:49 +00:00
} ,
2021-06-27 08:10:55 +00:00
2021-06-30 13:04:58 +00:00
ping ( ) {
2021-07-12 03:20:18 +00:00
if ( this . lastHeartBeat . ping || this . lastHeartBeat . ping === 0 ) {
2021-06-30 13:04:58 +00:00
return this . lastHeartBeat . ping ;
}
2021-07-27 17:47:13 +00:00
2021-10-01 10:44:32 +00:00
return this . $t ( "notAvailableShort" ) ;
2021-06-30 13:04:58 +00:00
} ,
avgPing ( ) {
2021-07-12 03:20:18 +00:00
if ( this . $root . avgPingList [ this . monitor . id ] || this . $root . avgPingList [ this . monitor . id ] === 0 ) {
2021-06-30 13:04:58 +00:00
return this . $root . avgPingList [ this . monitor . id ] ;
}
2021-07-27 17:47:13 +00:00
2021-10-01 10:44:32 +00:00
return this . $t ( "notAvailableShort" ) ;
2021-06-30 13:04:58 +00:00
} ,
importantHeartBeatList ( ) {
if ( this . $root . importantHeartbeatList [ this . monitor . id ] ) {
2021-09-04 18:03:40 +00:00
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
2021-07-18 01:04:40 +00:00
this . heartBeatList = this . $root . importantHeartbeatList [ this . monitor . id ] ;
2021-10-01 10:44:32 +00:00
return this . $root . importantHeartbeatList [ this . monitor . id ] ;
2021-06-30 13:04:58 +00:00
}
2021-07-27 17:47:13 +00:00
return [ ] ;
2021-06-30 13:04:58 +00:00
} ,
2021-06-27 08:10:55 +00:00
status ( ) {
if ( this . $root . statusList [ this . monitor . id ] ) {
2021-10-01 10:44:32 +00:00
return this . $root . statusList [ this . monitor . id ] ;
2021-06-27 08:10:55 +00:00
}
2021-07-27 17:47:13 +00:00
2021-10-01 10:44:32 +00:00
return { } ;
2021-07-18 01:04:40 +00:00
} ,
2021-06-27 08:10:55 +00:00
2021-10-01 10:44:32 +00:00
tlsInfo ( ) {
2021-10-09 11:08:38 +00:00
// Add: this.$root.tlsInfoList[this.monitor.id].certInfo
// Fix: TypeError: Cannot read properties of undefined (reading 'validTo')
// Reason: TLS Info object format is changed in 1.8.0, if for some reason, it cannot connect to the site after update to 1.8.0, the object is still in the old format.
if ( this . $root . tlsInfoList [ this . monitor . id ] && this . $root . tlsInfoList [ this . monitor . id ] . certInfo ) {
2021-10-01 10:44:32 +00:00
return this . $root . tlsInfoList [ this . monitor . id ] ;
2021-07-21 04:09:09 +00:00
}
2021-07-27 17:47:13 +00:00
2021-10-01 10:44:32 +00:00
return null ;
2021-07-21 04:09:09 +00:00
} ,
2021-07-26 14:53:07 +00:00
showCertInfoBox ( ) {
2021-10-01 10:44:32 +00:00
return this . tlsInfo != null && this . toggleCertInfoBox ;
2021-07-26 14:53:07 +00:00
} ,
2021-07-18 01:04:40 +00:00
displayedRecords ( ) {
const startIndex = this . perPage * ( this . page - 1 ) ;
const endIndex = startIndex + this . perPage ;
return this . heartBeatList . slice ( startIndex , endIndex ) ;
} ,
2021-07-27 17:47:13 +00:00
} ,
mounted ( ) {
2021-06-25 13:55:49 +00:00
} ,
methods : {
2021-06-30 13:04:58 +00:00
testNotification ( ) {
2021-10-01 10:44:32 +00:00
this . $root . getSocket ( ) . emit ( "testNotification" , this . monitor . id ) ;
toast . success ( "Test notification is requested." ) ;
2021-06-30 13:04:58 +00:00
} ,
2021-06-25 13:55:49 +00:00
pauseDialog ( ) {
this . $refs . confirmPause . show ( ) ;
} ,
2021-06-30 13:04:58 +00:00
2021-06-25 13:55:49 +00:00
resumeMonitor ( ) {
this . $root . getSocket ( ) . emit ( "resumeMonitor" , this . monitor . id , ( res ) => {
2021-10-01 10:44:32 +00:00
this . $root . toastRes ( res ) ;
} ) ;
2021-06-25 13:55:49 +00:00
} ,
2021-06-30 13:04:58 +00:00
2021-06-25 13:55:49 +00:00
pauseMonitor ( ) {
this . $root . getSocket ( ) . emit ( "pauseMonitor" , this . monitor . id , ( res ) => {
2021-10-01 10:44:32 +00:00
this . $root . toastRes ( res ) ;
} ) ;
2021-06-25 13:55:49 +00:00
} ,
2021-06-30 13:04:58 +00:00
2021-06-25 13:55:49 +00:00
deleteDialog ( ) {
this . $refs . confirmDelete . show ( ) ;
} ,
2021-06-30 13:04:58 +00:00
2021-08-29 16:47:01 +00:00
clearEventsDialog ( ) {
this . $refs . confirmClearEvents . show ( ) ;
} ,
clearHeartbeatsDialog ( ) {
this . $refs . confirmClearHeartbeats . show ( ) ;
} ,
2021-06-25 13:55:49 +00:00
deleteMonitor ( ) {
this . $root . deleteMonitor ( this . monitor . id , ( res ) => {
if ( res . ok ) {
toast . success ( res . msg ) ;
2021-10-01 10:44:32 +00:00
this . $router . push ( "/dashboard" ) ;
2021-06-25 13:55:49 +00:00
} else {
toast . error ( res . msg ) ;
}
2021-10-01 10:44:32 +00:00
} ) ;
2021-07-27 17:47:13 +00:00
} ,
2021-06-30 13:04:58 +00:00
2021-08-29 16:47:01 +00:00
clearEvents ( ) {
this . $root . clearEvents ( this . monitor . id , ( res ) => {
2021-09-04 18:03:40 +00:00
if ( ! res . ok ) {
2021-08-29 16:47:01 +00:00
toast . error ( res . msg ) ;
}
2021-10-01 10:44:32 +00:00
} ) ;
2021-08-29 16:47:01 +00:00
} ,
clearHeartbeats ( ) {
this . $root . clearHeartbeats ( this . monitor . id , ( res ) => {
2021-09-04 18:03:40 +00:00
if ( ! res . ok ) {
2021-08-29 16:47:01 +00:00
toast . error ( res . msg ) ;
}
2021-10-01 10:44:32 +00:00
} ) ;
2021-08-29 16:47:01 +00:00
} ,
2021-09-19 13:15:12 +00:00
pingTitle ( average = false ) {
2021-10-01 10:44:32 +00:00
let translationPrefix = "" ;
2021-09-19 13:15:12 +00:00
if ( average ) {
2021-10-01 10:44:32 +00:00
translationPrefix = "Avg. " ;
2021-09-19 13:15:12 +00:00
}
if ( this . monitor . type === "http" ) {
return this . $t ( translationPrefix + "Response" ) ;
}
return this . $t ( translationPrefix + "Ping" ) ;
} ,
2021-07-27 17:47:13 +00:00
} ,
2021-10-01 10:44:32 +00:00
} ;
2021-06-25 13:55:49 +00:00
< / script >
< style lang = "scss" scoped >
@ import "../assets/vars.scss" ;
2021-08-18 04:22:45 +00:00
@ media ( max - width : 767 px ) {
2021-08-11 09:16:53 +00:00
. badge {
margin - top : 14 px ;
}
}
2021-08-18 04:22:45 +00:00
@ media ( max - width : 550 px ) {
2021-08-10 16:29:47 +00:00
. functions {
text - align : center ;
2021-08-29 16:47:01 +00:00
button , a {
margin - left : 10 px ! important ;
margin - right : 10 px ! important ;
}
2021-08-10 16:29:47 +00:00
}
2021-08-18 04:22:45 +00:00
. ping - chart - wrapper {
padding : 10 px ! important ;
}
2021-08-29 16:47:01 +00:00
. dropdown - clear - data {
margin - bottom : 10 px ;
}
2021-08-10 16:29:47 +00:00
}
2021-08-18 04:22:45 +00:00
@ media ( max - width : 400 px ) {
2021-08-10 16:29:47 +00:00
. btn {
display : inline - flex ;
flex - direction : column ;
align - items : center ;
padding - top : 10 px ;
}
a . btn {
padding - left : 25 px ;
padding - right : 25 px ;
}
2021-08-29 16:47:01 +00:00
. dropdown - clear - data {
button {
display : block ;
padding - top : 4 px ;
}
}
2021-08-10 16:29:47 +00:00
}
2021-06-27 08:10:55 +00:00
. url {
2021-06-25 13:55:49 +00:00
color : $primary ;
margin - bottom : 20 px ;
2021-06-27 08:10:55 +00:00
font - weight : bold ;
a {
color : $primary ;
}
2021-06-25 13:55:49 +00:00
}
. functions {
button , a {
margin - right : 20 px ;
}
}
. shadow - box {
padding : 20 px ;
margin - top : 25 px ;
}
2021-06-27 08:10:55 +00:00
. word {
2021-08-24 15:38:25 +00:00
color : # aaa ;
2021-06-27 08:10:55 +00:00
font - size : 14 px ;
}
2021-06-30 13:04:58 +00:00
table {
font - size : 14 px ;
tr {
transition : all ease - in - out 0.2 ms ;
}
}
. stats p {
font - size : 13 px ;
2021-08-24 15:38:25 +00:00
color : # aaa ;
2021-06-30 13:04:58 +00:00
}
2021-07-26 14:53:07 +00:00
. stats {
padding : 10 px ;
. col {
margin : 20 px 0 ;
}
}
2021-08-08 05:47:29 +00:00
. keyword {
color : black ;
}
2021-08-29 16:47:01 +00:00
. dropdown - clear - data {
float : right ;
}
2021-08-24 15:38:25 +00:00
. dark {
2021-08-08 05:47:29 +00:00
. keyword {
color : $dark - font - color ;
}
2021-08-29 16:47:01 +00:00
. dropdown - clear - data {
ul {
background - color : $dark - bg ;
border - color : $dark - bg2 ;
border - width : 2 px ;
2021-09-04 18:03:40 +00:00
li button {
2021-08-29 16:47:01 +00:00
color : $dark - font - color ;
}
li button : hover {
background - color : $dark - bg2 ;
}
}
}
2021-08-08 05:47:29 +00:00
}
2021-08-29 18:22:49 +00:00
2021-08-26 10:55:19 +00:00
. tags {
margin - bottom : 0.5 rem ;
}
. tags > div : first - child {
margin - left : 0 ! important ;
}
2021-06-25 13:55:49 +00:00
< / style >