Commit 7de32a2f authored by Dan Jones's avatar Dan Jones
Browse files

Merge branch '7-animated-backbone-demo-page' into 'dev'

Resolve "Animated backbone demo page"

Closes #7

See merge request !5
Pipeline #214301 passed with stages
in 3 minutes and 19 seconds
<template>
<v-app>
<v-container fluid class="pa-0 ma-0">
<v-main>
<client-only>
<v-toolbar flat dense>
<v-spacer></v-spacer>
<v-btn icon @click="reset">
<v-icon>mdi-skip-backward</v-icon>
</v-btn>
<v-btn icon @click="backward">
<v-icon>mdi-rewind</v-icon>
</v-btn>
<v-btn icon @click="play">
<v-icon>mdi-play</v-icon>
</v-btn>
<v-btn icon @click="pause">
<v-icon>mdi-pause</v-icon>
</v-btn>
<v-btn icon @click="forward">
<v-icon>mdi-fast-forward</v-icon>
</v-btn>
</v-toolbar>
<v-row>
<v-col>
<v-card flat dense>
<v-card-title class="py-0">Comms Backbone</v-card-title>
</v-card>
</v-col>
<v-col>
<v-card flat dense>
<v-card-title class="py-0">Client Adapters</v-card-title>
</v-card>
</v-col>
</v-row>
<v-row>
<v-col>
<v-card>
<v-card-text class="pa-0">
<v-card class="my-3" flat v-for="client in clients" :key="client.name + '-client'">
<v-card-text>
<v-icon>{{ client.icon }}</v-icon>
{{ client.name }}
<v-divider/>
<v-row>
<v-col>
Inbox
<v-spacer/>
<v-btn icon>
<v-icon>mdi-arrow-right</v-icon>
</v-btn>
<v-btn icon v-for="message in client.inbox">
<v-icon :color="message.color">{{ message.icon }}</v-icon>
</v-btn>
</v-col>
<v-col>
Outbox
<v-spacer/>
<v-btn icon>
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
<v-btn icon v-for="message in client.outbox">
<v-icon :color="message.color">{{ message.icon }}</v-icon>
</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-card-text>
</v-card>
</v-col>
<v-col>
<v-card flat>
<v-card-text class="pa-0">
<v-card class="my-3" v-for="client in clients" :key="client.name + '-adapter'">
<v-card-text>
<v-icon>{{ client.icon }}</v-icon>
{{ client.name }}
<template v-if="client.received">
<span class="float-right">
<v-icon :color="client.received.color">{{ client.received.icon }}</v-icon>
<v-icon :color="client.color">mdi-dots-horizontal</v-icon>
<v-icon :color="client.color">{{ client.received.transform }}</v-icon>
</span>
</template>
<v-divider/>
<v-alert outlined dense class="mt-3 mb-1" color="#333">
<v-icon :color="client.color" left>{{ client.subIcon }}</v-icon>
subscribe: "{{ client.subscription }}"
</v-alert>
</v-card-text>
</v-card>
</v-card-text>
</v-card>
</v-col>
</v-row>
<v-card flat>
<v-card-text>
There is more context about the Nucleus project on the <a href="/">home page</a>.
If you're not sure what you're looking at it's probably best to start there.
</v-card-text>
</v-card>
<v-snackbar
v-model="showMessage"
:timeout="6000"
color="success"
centered
multi-line
content-class="font-weight-bold text-center text-uppercase"
>
<pre class="flat">{{ message }}</pre>
</v-snackbar>
</client-only>
</v-main>
</v-container>
</v-app>
</template>
<script>
import { cloneDeep } from 'lodash';
import script from './script';
export default {
name: "AnimatedDemo",
data() {
return {
isPlaying: true,
timer: null,
message: "",
showMessage: false,
stepCount: 0,
clients: [],
clientConfig: [
{
name: 'Mission Controller',
icon: 'mdi-robot-industrial',
subscription: 'I want all status messages',
color: 'red',
topic: 's',
transforms: {
s: 'mdi-map',
def: 'mdi-map-marker'
},
},
{
name: 'Hydrosurv',
icon: 'mdi-ferry',
subscription: 'I want missions for Hydrosurv operated vehicles',
color: 'orange',
topic: 'h',
transforms: {
s: 'mdi-code-brackets',
def: 'mdi-code-brackets',
},
},
{
name: 'NOC',
icon: 'mdi-submarine',
subscription: 'I want all messages for NOC operated vehicles',
color: 'green',
topic: 'n',
transforms: {
s: 'mdi-code-braces',
def: 'mdi-code-braces',
},
},
{
name: 'Web Console',
icon: 'mdi-application-outline',
subscription: 'I want to see all messages',
color: 'blue',
topic: '_',
transforms: {
s: 'mdi-map',
def: 'mdi-map-marker'
},
}
],
steps: script.steps,
};
},
mounted() {
this.run();
},
methods: {
run() {
this.nextStep();
},
nextStep() {
let stepNum = this.stepCount % this.steps.length;
let step = this.steps[stepNum];
this.$set(this, 'stepCount', this.stepCount + 1);
let delay = (Object.keys(step).includes('wait')) ? step.wait*1000 : 500;
switch(step.type) {
case 'none': break;
case 'add_client': {
this.stepAddClient(step.client);
} break;
case 'send_message': {
let client = this.getClient(step.client);
this.stepSendMessage(client, step.topic);
} break;
case 'deliver_message': {
let client = this.getClient(step.client);
this.stepDeliverMessage(client);
} break;
case 'receive_message': {
let client = this.getClient(step.client);
this.stepReceiveMessage(client);
} break;
case 'reset': {
this.reset();
} break;
}
if ('message' in step) this.stepShowMessage(step.message);
if (this.isPlaying) {
if (this.timer) clearTimeout(this.timer);
let timer = setTimeout(() => {
this.$nextTick(() => {
this.nextStep();
});
}, delay);
this.$set(this, 'timer', timer);
}
return false
},
getClient(index) {
let config = this.clientConfig[index];
let client = this.clients.find((c) => c.name === config.name);
return client;
},
stepShowMessage(message) {
this.$set(this, 'message', message);
this.$set(this, 'showMessage', true);
},
stepAddClient(index) {
let config = this.clientConfig[index];
let subIcon = (config.topic === '_')
? 'mdi-star-four-points-circle'
: 'mdi-alpha-'+config.topic + '-circle';
let client = {
...config,
inbox: [],
outbox: [],
received: null,
subIcon,
};
let exists = this.clients.find((c) => c.name === client.name);
if (!exists) this.clients.push(client);
},
stepSendMessage(client, topic) {
let icon = (topic === '_') ? 'star-four-points' : `alpha-${topic}`;
icon = `mdi-${icon}-box-outline`;
client.outbox.push({
from: client.topic,
topic,
color: client.color,
icon,
});
},
stepDeliverMessage(client) {
let message = client.outbox.shift();
this.clients.forEach((c) => {
if ([c.topic, message.topic].includes('_') || c.topic === message.topic)
c.inbox.push(cloneDeep(message));
});
},
stepReceiveMessage(client) {
let message = client.inbox.shift();
if (message) {
message.transform = (message.from in client.transforms)
? client.transforms[message.from]
: client.transforms.def;
client.received = message;
console.log('received', message);
setTimeout(()=> {
client.received = null;
}, 2000);
}
},
reset() {
if (this.timer) clearTimeout(this.timer);
this.$set(this, 'stepCount', 0);
this.$set(this, 'clients', []);
if (this.isPlaying) this.run();
},
play() {
this.$set(this, 'isPlaying', true);
this.run();
},
pause() {
if (this.timer) clearTimeout(this.timer);
this.$set(this, 'isPlaying', false);
},
forward() {
this.$set(this, 'showMessage', false);
this.nextStep();
},
backward() {
this.$set(this, 'stepCount', this.stepCount - 2);
this.nextStep();
},
},
}
</script>
<style>
div.theme-default-content:not(.custom) {
max-width: 100%;
}
div.theme-default-content pre.flat {
padding: 0.2em 0.2em 0.2em 0.2em;
font: inherit;
background-color: transparent;
}
</style>
\ No newline at end of file
export default {
steps: [
{
type: 'add_client',
client: 2,
wait: 2,
},
{
type: 'none',
message: 'The backbone connects different systems together',
wait: 8,
},
{
type: 'none',
message: 'Client applications connect to the backbone via adapters',
wait: 8,
},
{
type: 'none',
message: 'Adapters handle authentication and communication with the backbone',
wait: 8,
},
{
type: 'none',
message: 'Adapters transform the client data into common agreed message formats',
wait: 8,
},
{
type: 'none',
message: 'These common messages are sent to the backbone',
wait: 8,
},
{
type: 'none',
message: 'The backbone delivers the messages to other clients',
wait: 8,
},
{
type: 'none',
message: 'Any subscriber can understand messages from any platform',
wait: 8,
},
{
type: 'none',
message: 'Common format messages are received from the backbone',
wait: 8,
},
{
type: 'none',
message: 'The adapters transform received messages into native client data',
wait: 8,
},
{
type: 'add_client',
client: 1,
},
{
type: 'none',
message: 'A backbone client could be a Command and Control system',
wait: 8,
},
{
type: 'add_client',
client: 3,
},
{
type: 'none',
message: '..or a website providing an overview of the operation',
wait: 8,
},
{
type: 'add_client',
client: 0,
},
{
type: 'none',
message: '..or a machine learning system automating the operation',
wait: 8,
},
{
type: 'none',
message: 'Clients register with the backbone',
wait: 8,
},
{
message: 'Each client has 2 queues - an inbox and an outbox',
wait: 8,
},
{
message: 'Each client has a subscription for the message types they want to receive',
wait: 8,
},
{
message: 'Each client can broadcast or publish messages',
wait: 8,
},
{
type: 'send_message',
client: 0,
topic: '_',
message: 'When messages are broadcast..',
wait: 8,
},
{
type: 'deliver_message',
client: 0,
message: 'When a messages are broadcast..\n..they are delivered to all clients',
wait: 8,
},
{
type: 'send_message',
client: 0,
topic: 'h',
message: 'When messages are published..',
},
{
type: 'send_message',
client: 0,
topic: 'n',
wait: 8,
},
{
type: 'deliver_message',
client: 0,
},
{
type: 'deliver_message',
client: 0,
message: 'When messages are published..\n..they are delivered to matching subscribers',
wait: 8,
},
{
type: 'none',
message: 'The web console is subscribed to every message',
wait: 8,
},
{
type: 'none',
message: 'Messages are queued until the client connects',
wait: 8,
},
{
type: 'none',
message: 'Inbound messages are transformed by the adapter for the client application',
wait: 8,
},
{
type: 'receive_message',
client: 0,
},
{
type: 'receive_message',
client: 1,
},
{
type: 'receive_message',
client: 2,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'receive_message',
client: 1,
},
{
type: 'receive_message',
client: 2,
wait: 2,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'receive_message',
client: 3,
wait: 2,
},
{
type: 'send_message',
client: 1,
topic: 's',
message: 'Status messages are published',
},
{
type: 'send_message',
client: 2,
topic: 's',
wait: 8,
},
{
type: 'deliver_message',
client: 1,
},
{
type: 'deliver_message',
client: 2,
message: 'And are received by matching subscribers',
wait: 8,
},
{
type: 'receive_message',
client: 0,
},
{
type: 'receive_message',
client: 0,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'send_message',
client: 0,
topic: 'h',
message: 'The mission controller can act on these messages',
},
{
type: 'send_message',
client: 0,
topic: 'n',
wait: 8,
},
{
type: 'deliver_message',
client: 0,
},
{
type: 'deliver_message',
client: 0,
message: '.. and send new instructions',
wait: 8,
},
{
type: 'receive_message',
client: 0,
},
{
type: 'receive_message',
client: 1,
},
{
type: 'receive_message',
client: 2,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'receive_message',
client: 3,
},
{
type: 'none',
message: 'The end',
wait: 10,
},
{
type: 'reset',
},
]
};
......@@ -48,7 +48,7 @@ module.exports = {
*/
//theme: 'vuetify',
themeConfig: {
colorMode: 'dark',
colorMode: 'light',
logo: '/assets/hydrogen.svg',
search: true,
repo: '',
......@@ -60,7 +60,15 @@ module.exports = {
createSidebar: true,
createNav: true,
sidebarAllSections: true
}
},
sidebar: [
{
title: 'Demo', // required
path: '/demo/', // optional, link of the title, which should be an absolute path and must exist
collapsable: false, // optional, defaults to true
sidebarDepth: 1, // optional, defaults to 1
},
],
},
markdown: {
......
......@@ -6,13 +6,17 @@
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
import '@mdi/font/css/materialdesignicons.css';
import AnimatedDemo from './components/AnimatedDemo.vue';
const opts = {
icons: {
iconfont: 'mdi',
},
variables: {
'font-size-root': '0.75rem',
},
theme: {
dark: true,
dark: false,
themes: {
light: {
primary: '#545F66',
......@@ -41,4 +45,5 @@ export default ({
// ...apply enhancements for the site.
Vue.use(Vuetify);
options.vuetify = new Vuetify(opts);
Vue.component('AnimatedDemo', AnimatedDemo);
}
<animated-demo/>
\ No newline at end of file
......@@ -9,6 +9,7 @@
},
"dependencies": {
"@mdi/font": "^7.0.96",
"lodash": "^4.17.21",
"vue": "^2.6.4",
"vuetify": "^2.6.11"
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment