mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
add visualize federation
This commit is contained in:
parent
47fe739c77
commit
a1b8be4329
@ -33,6 +33,7 @@
|
||||
"bootstrap": "4.3.1",
|
||||
"bootstrap-vue": "^2.21.2",
|
||||
"core-js": "^3.6.5",
|
||||
"date-fns": "^2.29.3",
|
||||
"dotenv-webpack": "^7.0.3",
|
||||
"express": "^4.17.1",
|
||||
"graphql": "^15.6.1",
|
||||
|
||||
76
admin/src/components/Fedaration/FederationVisualizeItem.vue
Normal file
76
admin/src/components/Fedaration/FederationVisualizeItem.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div class="federation-visualize-item">
|
||||
<b-row>
|
||||
<b-col cols="1"><b-icon :icon="icon" :variant="variant" class="mr-4"></b-icon></b-col>
|
||||
<b-col>
|
||||
<div>{{ item.url }}</div>
|
||||
<small>{{ `${item.publicKey.substring(0, 26)}…` }}</small>
|
||||
</b-col>
|
||||
<b-col cols="2">{{ lastAnnouncedAt }}</b-col>
|
||||
<b-col cols="2">{{ createdAt }}</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import { de, en, fr, es, nl } from 'date-fns/locale'
|
||||
|
||||
export default {
|
||||
name: 'FederationVisualizeItem',
|
||||
props: {
|
||||
item: { type: Object },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
oldPublicKey: '',
|
||||
formatDistanceToNow,
|
||||
locale: this.$i18n.locale,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
verified() {
|
||||
return new Date(this.item.verifiedAt) >= new Date(this.item.lastAnnouncedAt)
|
||||
},
|
||||
icon() {
|
||||
return this.verified ? 'check' : 'x-circle'
|
||||
},
|
||||
variant() {
|
||||
return this.verified ? 'success' : 'danger'
|
||||
},
|
||||
fnsLocale() {
|
||||
switch (this.locale) {
|
||||
case 'de':
|
||||
return de
|
||||
case 'es':
|
||||
return es
|
||||
case 'fr':
|
||||
return fr
|
||||
case 'nl':
|
||||
return nl
|
||||
default:
|
||||
return en
|
||||
}
|
||||
},
|
||||
lastAnnouncedAt() {
|
||||
if (this.item.lastAnnouncedAt) {
|
||||
return formatDistanceToNow(new Date(this.item.lastAnnouncedAt), {
|
||||
includeSecond: true,
|
||||
addSuffix: true,
|
||||
locale: this.fnsLocale,
|
||||
})
|
||||
}
|
||||
return ''
|
||||
},
|
||||
createdAt() {
|
||||
if (this.item.createdAt) {
|
||||
return formatDistanceToNow(new Date(this.item.createdAt), {
|
||||
includeSecond: true,
|
||||
addSuffix: true,
|
||||
locale: this.fnsLocale,
|
||||
})
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,44 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import FederationVisualizeItem from './FederationVisualizeItem.vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const mocks = {
|
||||
$t: (key) => key,
|
||||
$i18n: {
|
||||
locale: 'de',
|
||||
t: (key) => key,
|
||||
},
|
||||
}
|
||||
|
||||
describe('FederationVisualizeItem', () => {
|
||||
let wrapper
|
||||
|
||||
const propsData = {
|
||||
item: {
|
||||
id: 7590,
|
||||
foreign: false,
|
||||
publicKey: 'eaf6a426b24fd54f8fbae11c17700fc595080ca25159579c63d38dbc64284ba7',
|
||||
url: 'http://localhost/api/api/2_0',
|
||||
lastAnnouncedAt: null,
|
||||
verifiedAt: null,
|
||||
lastErrorAt: null,
|
||||
createdAt: '2023-03-29T04:46:38.823Z',
|
||||
updatedAt: null,
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(FederationVisualizeItem, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders the component', () => {
|
||||
expect(wrapper.find('div.federation-visualize-item').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -62,8 +62,12 @@ describe('NavBar', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('has a link to /federation', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(3).find('a').attributes('href')).toBe('/federation')
|
||||
})
|
||||
|
||||
it('has a link to /statistic', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(3).find('a').attributes('href')).toBe('/statistic')
|
||||
expect(wrapper.findAll('.nav-item').at(4).find('a').attributes('href')).toBe('/statistic')
|
||||
})
|
||||
})
|
||||
|
||||
@ -72,7 +76,7 @@ describe('NavBar', () => {
|
||||
beforeEach(async () => {
|
||||
delete window.location
|
||||
window.location = ''
|
||||
await wrapper.findAll('.nav-item').at(4).find('a').trigger('click')
|
||||
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
@ -97,7 +101,7 @@ describe('NavBar', () => {
|
||||
window.location = {
|
||||
assign: windowLocationMock,
|
||||
}
|
||||
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
||||
await wrapper.findAll('.nav-item').at(6).find('a').trigger('click')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="component-nabvar">
|
||||
<b-navbar toggleable="md" type="dark" variant="success">
|
||||
<b-navbar toggleable="lg" type="dark" class="bg-dark">
|
||||
<b-navbar-brand class="mb-2" to="/">
|
||||
<img src="img/brand/gradido_logo_w.png" class="navbar-brand-img pl-2" alt="..." />
|
||||
</b-navbar-brand>
|
||||
@ -19,6 +19,9 @@
|
||||
<b-nav-item to="/contribution-links">
|
||||
{{ $t('navbar.automaticContributions') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/federation">
|
||||
{{ $t('navbar.instances') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/statistic">{{ $t('navbar.statistic') }}</b-nav-item>
|
||||
<b-nav-item @click="wallet">{{ $t('navbar.my-account') }}</b-nav-item>
|
||||
<b-nav-item @click="logout">{{ $t('navbar.logout') }}</b-nav-item>
|
||||
|
||||
17
admin/src/graphql/getCommunities.js
Normal file
17
admin/src/graphql/getCommunities.js
Normal file
@ -0,0 +1,17 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const getCommunities = gql`
|
||||
query {
|
||||
getCommunities {
|
||||
id
|
||||
foreign
|
||||
publicKey
|
||||
url
|
||||
lastAnnouncedAt
|
||||
verifiedAt
|
||||
lastErrorAt
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -76,6 +76,13 @@
|
||||
},
|
||||
"short_hash": "({shortHash})"
|
||||
},
|
||||
"federation": {
|
||||
"gradidoInstances":"Gradido Instanzen",
|
||||
"verified":"Verifiziert",
|
||||
"url":"Url",
|
||||
"lastAnnouncedAt":"letzte Bekanntgabe",
|
||||
"createdAt":"Erstellt am"
|
||||
},
|
||||
"form": {
|
||||
"cancel": "Abbrechen",
|
||||
"submit": "Senden"
|
||||
@ -104,6 +111,7 @@
|
||||
"name": "Name",
|
||||
"navbar": {
|
||||
"automaticContributions": "Automatische Beiträge",
|
||||
"instances":"Instanzen",
|
||||
"logout": "Abmelden",
|
||||
"my-account": "Mein Konto",
|
||||
"statistic": "Statistik",
|
||||
|
||||
@ -76,6 +76,13 @@
|
||||
},
|
||||
"short_hash": "({shortHash})"
|
||||
},
|
||||
"federation": {
|
||||
"gradidoInstances":"Gradido Instances",
|
||||
"verified":"Verified",
|
||||
"url":"Url",
|
||||
"lastAnnouncedAt":"Last Announced",
|
||||
"createdAt":"Created At "
|
||||
},
|
||||
"form": {
|
||||
"cancel": "Cancel",
|
||||
"submit": "Send"
|
||||
@ -104,6 +111,7 @@
|
||||
"name": "Name",
|
||||
"navbar": {
|
||||
"automaticContributions": "Automatic Contributions",
|
||||
"instances":"Instances",
|
||||
"logout": "Logout",
|
||||
"my-account": "My Account",
|
||||
"statistic": "Statistic",
|
||||
|
||||
30
admin/src/pages/FederationVisualize.spec.js
Normal file
30
admin/src/pages/FederationVisualize.spec.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import FederationVisualize from './FederationVisualize'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const mocks = {
|
||||
$t: (key) => key,
|
||||
$i18n: {
|
||||
locale: 'de',
|
||||
t: (key) => key,
|
||||
},
|
||||
}
|
||||
|
||||
describe('Overview', () => {
|
||||
let wrapper
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(FederationVisualize, { localVue, mocks })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a DIV element with the class.component-confirm-register-mail', () => {
|
||||
expect(wrapper.find('div.federation-visualize').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
68
admin/src/pages/FederationVisualize.vue
Normal file
68
admin/src/pages/FederationVisualize.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="federation-visualize">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<span class="h2">{{ $t('federation.gradidoInstances') }}</span>
|
||||
<b-button>
|
||||
<b-icon
|
||||
icon="arrow-clockwise"
|
||||
font-scale="2"
|
||||
:animation="animation"
|
||||
@click="$apollo.queries.GetCommunities.refresh()"
|
||||
></b-icon>
|
||||
</b-button>
|
||||
</div>
|
||||
<b-list-group>
|
||||
<b-row>
|
||||
<b-col cols="1" class="ml-1">{{ $t('federation.verified') }}</b-col>
|
||||
<b-col class="ml-3">{{ $t('federation.url') }}</b-col>
|
||||
<b-col cols="2">{{ $t('federation.lastAnnouncedAt') }}</b-col>
|
||||
<b-col cols="2">{{ $t('federation.createdAt') }}</b-col>
|
||||
</b-row>
|
||||
<b-list-group-item
|
||||
v-for="item in communities"
|
||||
:key="item.id"
|
||||
:variant="!item.foreign ? 'primary' : 'warning'"
|
||||
>
|
||||
<federation-visualize-item :item="item" />
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getCommunities } from '@/graphql/getCommunities'
|
||||
|
||||
import FederationVisualizeItem from '../components/Fedaration/FederationVisualizeItem.vue'
|
||||
|
||||
export default {
|
||||
name: 'FederationVisualize',
|
||||
components: {
|
||||
FederationVisualizeItem,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
oldPublicKey: '',
|
||||
communities: [],
|
||||
icon: '',
|
||||
animation: '',
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
GetCommunities: {
|
||||
fetchPolicy: 'network-only',
|
||||
query() {
|
||||
this.animation = 'spin'
|
||||
|
||||
return getCommunities
|
||||
},
|
||||
update({ getCommunities }) {
|
||||
this.communities = getCommunities
|
||||
this.animation = ''
|
||||
},
|
||||
error({ message }) {
|
||||
this.toastError(message)
|
||||
this.animation = ''
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -45,7 +45,7 @@ describe('router', () => {
|
||||
|
||||
describe('routes', () => {
|
||||
it('has nine routes defined', () => {
|
||||
expect(routes).toHaveLength(8)
|
||||
expect(routes).toHaveLength(9)
|
||||
})
|
||||
|
||||
it('has "/overview" as default', async () => {
|
||||
@ -88,6 +88,13 @@ describe('router', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('federation', () => {
|
||||
it('loads the "FederationVisualize" page', async () => {
|
||||
const component = await routes.find((r) => r.path === '/federation').component()
|
||||
expect(component.default.name).toBe('FederationVisualize')
|
||||
})
|
||||
})
|
||||
|
||||
describe('not found page', () => {
|
||||
it('renders the "NotFound" component', async () => {
|
||||
const component = await routes.find((r) => r.path === '*').component()
|
||||
|
||||
@ -31,6 +31,10 @@ const routes = [
|
||||
path: '*',
|
||||
component: () => import('@/components/NotFoundPage.vue'),
|
||||
},
|
||||
{
|
||||
path: '/federation',
|
||||
component: () => import('@/pages/FederationVisualize.vue'),
|
||||
},
|
||||
]
|
||||
|
||||
export default routes
|
||||
|
||||
@ -5038,6 +5038,11 @@ data-urls@^2.0.0:
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
date-fns@^2.29.3:
|
||||
version "2.29.3"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
|
||||
integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user