Skip to content

Commit

Permalink
Merge pull request #764 from InternetHealthReport/dev
Browse files Browse the repository at this point in the history
Integrating latest changes
  • Loading branch information
dpgiakatos authored Mar 11, 2024
2 parents 7ba872e + 898158c commit f7b345a
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 25 deletions.
36 changes: 27 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,16 @@ <h1>L<span> </span>ading...</h1>

.loading .imageLoading h1 {
font-family: 'Montserrat', sans-serif;
font-size: 100px !important;
font-size: 90px;
font-weight: 700;
margin: 0px;
color: #232323;
}

.loading .imageLoading h1>span {
display: inline-block;
width: 50px;
height: 50px;
width: 45px;
height: 45px;
background-image: url('https://avatars1.githubusercontent.com/u/40665700?s=200&v=4');
background-size: cover;
-webkit-transform: scale(1.4);
Expand All @@ -129,31 +129,49 @@ <h1>L<span> </span>ading...</h1>
margin: 0px 15px 0px 15px;
}

@media screen and (max-width: 320px) {
@media screen and (max-width: 820px) {
.loading .imageLoading {
height: 85px;
}
.loading .imageLoading h1 {
font-size: 66px;
font-size: 50px;
}
.loading .imageLoading h1>span {
width: 40px;
height: 40px;
margin: 0px 10px 0px 10px;
}
}

@media screen and (max-width: 767px) {
@media screen and (max-width: 580px) {
.loading .imageLoading {
height: 115px;
}
.loading .imageLoading h1 {
font-size: 86px;
font-size: 37px;
}
.loading .imageLoading h1>span {
width: 60px;
height: 60px;
width: 20px;
height: 20px;
margin: 0px 8px 0px 8px;
}
}

@media screen and (max-width: 375px) {
.loading .imageLoading {
height: 115px;
}
.loading .imageLoading h1 {
font-size: 28px;
}
.loading .imageLoading h1>span {
width: 18px;
height: 18px;
margin: 0px 8px 0px 8px;
}
}


</style>
</body>
</html>
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ihr",
"version": "1.2.0",
"version": "1.2.1",
"private": true,
"type": "module",
"scripts": {
Expand All @@ -27,7 +27,7 @@
"@babel/preset-env": "^7.23.6",
"@quasar/vite-plugin": "^1.6.0",
"@rushstack/eslint-patch": "^1.3.3",
"@vitejs/plugin-vue": "^4.4.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
Expand Down
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { QLayout, QPageContainer, QIcon } from 'quasar'
import { onBeforeUnmount, onMounted, ref } from 'vue'
import Header from './components/Header.vue';
import Footer from './components/Footer.vue'
import CookieBanner from './components/CookieBanner.vue'
let scrollPosition = ref(0)
Expand Down Expand Up @@ -41,6 +42,7 @@ onBeforeUnmount(() => {
<Footer></Footer>
<button v-if="showScrollTopButton" @click="scrollToTop" class="IHR_scroll-btn bg-primary text-white"><QIcon name="fas fa-arrow-up"></QIcon></button>
</QLayout>
<CookieBanner/>
</template>

<style lang="stylus">
Expand Down
67 changes: 67 additions & 0 deletions src/components/CookieBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script setup>
import { ref, onMounted } from 'vue'
import { QDialog, QCard, QCardSection, QBtn } from 'quasar'
const dialog = ref(false)
const openDialog = () => {
dialog.value = true
}
const closeDialog = () => {
dialog.value = false
}
const onAcceptClick = () => {
localStorage.setItem('cookie-preference', true)
closeDialog()
}
const onDeclineClick = () => {
closeDialog()
}
onMounted(() => {
const preferenceValue = localStorage.getItem('cookie-preference')
if (preferenceValue === null || preferenceValue === undefined || preferenceValue !== 'true') {
openDialog()
}
})
</script>

<template>
<QDialog v-model="dialog" persistent no-shake seamless :position="'bottom'">
<QCard style="width: 350px; border-radius: 6px; background-color: #323232">
<QCardSection class="items-center no-wrap cookieBanner_Container">
<p class="cookieBanner_Message">
This website use cookies, which are necessary for its functioning and required to achieve
the purposes illustrated in the Data and Cookie policy.
</p>
<div class="cookieBanner_Buttons">
<QBtn flat style="color: yellow" label="Accept" @click="onAcceptClick" />
<QBtn flat style="color: darkgray" label="Decline" @click="onDeclineClick" />
</div>
</QCardSection>
</QCard>
</QDialog>
</template>

<style>
.fixed-bottom {
right: 0px !important;
bottom: 10px !important;
left: auto !important;
}
.q-dialog__inner--minimized {
padding: 10px !important;
}
.cookieBanner_Buttons {
align-self: flex-end;
}
.cookieBanner_Container {
display: flex;
flex-direction: column;
}
.cookieBanner_Message {
font-size: 16px;
font-weight: 600;
font-family: inherit;
color: white;
}
</style>
2 changes: 1 addition & 1 deletion src/components/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,4 @@ menu-delinkify(val)
@media screen and (max-width: 1024px)
.col-12.row.no-wrap.items-center
justify-content space-around
</style>
</style>
2 changes: 1 addition & 1 deletion src/components/charts/NetworkDelayChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ const fetchNetworkDelay = (data) => {
let currDate = new Date(elem.timebin).getTime()
if (currDate > prevDate + timeResolution + 1) {
trace.y.push(null)
trace.x.push(elem.timbin)
trace.x.push(elem.timebin)
}
trace.y.push(elem.median)
Expand Down
4 changes: 2 additions & 2 deletions src/components/iyp/as/ASConnectedASes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const peers = ref({
query: `MATCH (a:AS {asn: $asn})-[:PEERS_WITH]-(peer:AS)
OPTIONAL MATCH (peer)-[:NAME]->(n:Name)
OPTIONAL MATCH (peer)-[:COUNTRY {reference_name: 'nro.delegated_stats'}]->(c:Country)
RETURN c.country_code AS cc, 'AS'+peer.asn AS asn, head(collect(DISTINCT(n.name))) AS name`,
RETURN c.country_code AS cc, peer.asn AS asn, head(collect(DISTINCT(n.name))) AS name`,
columns: [
{ name: 'Country', label: 'Country', align: 'left', field: row => row.cc, format: val => `${val}`, sortable: true, sortOrder: 'ad' },
{ name: 'ASN', label: 'ASN', align: 'left', field: row => row.asn, format: val => `${val}`, sortable: true },
{ name: 'ASN', label: 'ASN', align: 'left', field: row => row.asn, format: val => `AS${val}`, sortable: true },
{ name: 'Name', label: 'Name', align: 'left', field: row => row.name, format: val => `${val}`, sortable: true },
]
})
Expand Down
2 changes: 1 addition & 1 deletion src/components/iyp/as/ASPopularHostNames.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const domains = ref({
data: [],
show: false,
loading: true,
query: `MATCH (:AS {asn: $asn})-[:ORIGINATE]->(p:Prefix)<-[:PART_OF]-(:IP)<-[:RESOLVES_TO]-(h:HostName)-[:PART_OF]->(d:DomainName)-[rr:RANK]->(rn:Ranking)
query: `MATCH (:AS {asn: $asn})-[:ORIGINATE]->(p:Prefix)<-[:PART_OF]-(:IP)<-[:RESOLVES_TO]-(h:HostName & !AuthoritativeNameServer)-[:PART_OF]->(d:DomainName)-[rr:RANK]->(rn:Ranking)
WHERE rr.rank < 100000 and rr.reference_name = 'tranco.top1m'
RETURN DISTINCT h.name AS hostName, rr.rank AS rank, rn.name AS rankingName, split(h.name, '.')[-1] AS tld, 1/toFloat(rr.rank) AS inv_rank, COLLECT(DISTINCT p.prefix) AS prefix
ORDER BY rank`,
Expand Down
2 changes: 1 addition & 1 deletion src/components/iyp/prefix/PrefixPopularHostNames.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const domains = ref({
data: [],
show: false,
loading: true,
query: `MATCH (p:Prefix {prefix: $prefix})<-[:PART_OF]-(i:IP)<-[:RESOLVES_TO]-(h:HostName)-[:PART_OF]-(d:DomainName)-[ra:RANK {reference_name:'tranco.top1m'}]->(rn:Ranking)
query: `MATCH (p:Prefix {prefix: $prefix})<-[:PART_OF]-(i:IP)<-[:RESOLVES_TO]-(h:HostName & !AuthoritativeNameServer)-[:PART_OF]-(d:DomainName)-[ra:RANK {reference_name:'tranco.top1m'}]->(rn:Ranking)
OPTIONAL MATCH (h)<-[:PART_OF]-(p)-[:CATEGORIZED]->(t:Tag)
RETURN COLLECT(DISTINCT i.ip) AS ip, h.name as hostName, collect(DISTINCT t.label) as tags, ra.rank AS rank, split(h.name, '.')[-1] AS tld, 1/toFloat(ra.rank) AS inv_rank, rn.name as rankingName
ORDER BY rank`,
Expand Down
2 changes: 1 addition & 1 deletion src/components/iyp/tag/TagPopularHostNames.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const domains = ref({
data: [],
show: false,
loading: true,
query: `MATCH (t:Tag {label: $tag})<-[cat:CATEGORIZED]-(:URL)-[:PART_OF]-(h:HostName)-[:PART_OF]-(d:DomainName)
query: `MATCH (t:Tag {label: $tag})<-[cat:CATEGORIZED]-(:URL)-[:PART_OF]-(h:HostName & !AuthoritativeNameServer)-[:PART_OF]-(d:DomainName)
OPTIONAL MATCH (d)-[ra:RANK]->(rn:Ranking {name: 'Tranco top 1M'})
OPTIONAL MATCH (h)-[:PART_OF]-(:URL)-[:CATEGORIZED]->(to:Tag) WHERE t <> to
RETURN h.name AS hostname, collect(DISTINCT to.label) AS other_tags, ra.rank AS rank, split(d.name, '.')[-1] AS tld, rn.name AS rankingName, cat.reference_org AS classifier_org, split(cat.reference_name, '.')[-1] AS classifier_name, cat.reference_url AS classifier_url`,
Expand Down
94 changes: 94 additions & 0 deletions src/components/maps/WorldMap.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<script setup>
import { ref, onMounted, inject } from 'vue'
import ReactiveChart from '@/components/charts/ReactiveChart.vue'
import { CountryQuery } from '@/plugins/IhrApi'
const ihr_api = inject('ihr_api')
const countryQuery = ref(new CountryQuery().orderedByCode())
const countryNames = ref([])
const countryCodes = ref([])
const loading = ref(false)
const emit = defineEmits(['country-selected'])
const layout = {
title: 'Select a country',
geo: {
showframe: false,
projection: {
type: 'equirectangular'
},
showcountries: true,
showcoastlines: 'yes'
},
autosize: true
}
const traces = ref([{
type: 'choropleth',
locationmode: 'country names',
locations: [],
z: [],
text: [],
hoverinfo: 'text',
autocolorscale: false,
showscale: false
}])
const fetchData = async () => {
try {
loading.value = true
countryQuery.value.containsName('')
ihr_api.country(countryQuery.value, (result) => {
result.results.forEach((country) => {
countryNames.value.push(country.name)
countryCodes.value.push(country.code)
})
traces.value[0].locations = countryNames.value
traces.value[0].text = countryNames.value
traces.value[0].z = countryNames.value.map(() => 0)
loading.value = false
})
} catch (error) {
console.error('Error loading data:', error)
loading.value = false
}
}
onMounted(()=>{
fetchData()
})
const onCountryClick = (eventData) => {
if (eventData && eventData.points && eventData.points[0]) {
const countryCodeIndex = eventData.points[0].pointIndex
const countryCode = countryCodes.value[countryCodeIndex]
emit('country-selected', countryCode)
}
}
</script>

<template>
<div>
<div class="map-container">
<ReactiveChart
:layout="layout"
:traces="traces"
@plotly-click="onCountryClick"
/>
</div>
</div>
</template>

<style scoped>
.map-container {
width: 100%;
}
@media screen and (max-width: 768px) {
.map-container {
display: none;
}
}
</style>
29 changes: 24 additions & 5 deletions src/components/search/SearchBar.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script setup>
import { QSelect, QIcon, QSpinner, QItem, QItemSection } from 'quasar'
import { QSelect, QIcon, QSpinner, QItem, QItemSection, QDialog } from 'quasar'
import { ref, inject, computed, watch, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import Tr from '@/i18n/translation'
import { NetworkQuery, CountryQuery } from '@/plugins/IhrApi'
import getCountryName from '@/plugins/countryName'
import * as ipAddress from 'ip-address'
import WorldMap from '../maps/WorldMap.vue'
const { t } = useI18n()
Expand Down Expand Up @@ -304,6 +305,10 @@ const routeToCountry = (cc) => {
}))
}
const handleCountryClicked = (cc) => {
routeToCountry(cc) ;
}
const routeToHostName = (hostName) => {
const oldhostName = paramExists('hostName')
if (oldhostName) {
Expand Down Expand Up @@ -343,6 +348,12 @@ const routeToRank = (rank) => {
}))
}
const showMapDialog = ref(false)
const showMap = () => {
showMapDialog.value = true
}
const placeholder = computed(() => {
if (props.labelTxt == null) {
return `${t('searchBar.placeholder')}`
Expand All @@ -368,11 +379,19 @@ const placeholder = computed(() => {
hide-selected
>
<template v-slot:append>
<div v-if="!loading">
<QIcon :color="label" name="fas fa-search q-mb-xs" width="0.82em" />
<div v-if="!props.noCountry" @click="showMap">
<QIcon :color="label" type="button" name="fas fa-map q-pa-sm" width="0.82em" />
<QDialog v-model="showMapDialog">
<WorldMap @country-selected="handleCountryClicked" />
</QDialog>
</div>
<div v-else>
<QSpinner :color="label" size="0.82em" />
<div>
<div v-if="!loading">
<QIcon :color="label" name="fas fa-search q-mb-xs" width="0.82em" />
</div>
<div v-else>
<QSpinner :color="label" size="0.82em" />
</div>
</div>
</template>
<template v-slot:loading> </template>
Expand Down
Loading

0 comments on commit f7b345a

Please sign in to comment.