web/multinode: routes restriction in no node added

checks if there is a try to navigate to some of internal route and no nodes added so far.
redirects to add first node screen if so.

Change-Id: Ibde47c5b81ae33462afe00f2fd7a54e8b295933a
This commit is contained in:
NickolaiYurchenko 2021-06-22 21:31:32 +03:00 committed by Nikolay Yurchenko
parent b8e6e5c6c8
commit 4d418c13c3
3 changed files with 117 additions and 7 deletions

View File

@ -4,6 +4,7 @@
import Router, { RouterMode } from 'vue-router';
import { Component } from 'vue-router/types/router';
import { store } from '@/app/store';
import AddFirstNode from '@/app/views/AddFirstNode.vue';
import BandwidthPage from '@/app/views/bandwidth/BandwidthPage.vue';
import Dashboard from '@/app/views/Dashboard.vue';
@ -125,3 +126,20 @@ export class Config {
}
export const router = new Router(Config);
/**
* List of allowed routes without any node added.
*/
const allowedRoutesNames = [ Config.AddFirstNode.name, Config.Welcome.name ];
/**
* Checks if redirect to some of internal routes and no nodes added so far.
* Redirect to Add first node screen if so.
*/
router.beforeEach((to, from, next) => {
if (!store.state.nodes.nodes.length && !to.matched.some(record => allowedRoutesNames.includes(<string>record.name))) {
next(Config.AddFirstNode);
} else {
next();
}
});

View File

@ -13,17 +13,26 @@
<p class="add-first-node__left-area__info">Please add authentication data below:</p>
<headered-input
class="add-first-node__left-area__input"
label="IP Address"
label="Node ID"
placeholder="Enter Node ID"
:error="idError"
@setData="setNodeId"
/>
<headered-input
class="add-first-node__left-area__input"
label="Secret Key"
label="Public IP Address"
placeholder="Enter Public IP Address"
:error="publicIPError"
@setData="setPublicIP"
/>
<headered-input
class="add-first-node__left-area__input"
label="Add name"
label="API Key"
placeholder="Enter API Key"
:error="apiKeyError"
@setData="setApiKey"
/>
<v-button class="add-first-node__left-area__button" label="Add Node" width="120px"></v-button>
<v-button class="add-first-node__left-area__button" label="Add Node" width="120px" :on-press="onCreate"></v-button>
</div>
<div class="add-first-node__right-area">
<img src="@/../static/images/Illustration.png" alt="Storj Logo Illustration">
@ -37,13 +46,90 @@ import { Component, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/app/components/common/HeaderedInput.vue';
import VButton from '@/app/components/common/VButton.vue';
import { Config as RouterConfig } from '@/app/router';
import { CreateNodeFields } from '@/nodes';
@Component({
components: {
HeaderedInput,
VButton,
},
})
export default class AddFirstNode extends Vue {}
export default class AddFirstNode extends Vue {
private nodeToAdd: CreateNodeFields = new CreateNodeFields();
private isLoading: boolean = false;
// errors
private idError: string = '';
private publicIPError: string = '';
private apiKeyError: string = '';
/**
* Sets node id field from value string.
*/
public setNodeId(value: string): void {
this.nodeToAdd.id = value.trim();
this.idError = '';
}
/**
* Sets node public ip field from value string.
*/
public setPublicIP(value: string): void {
this.nodeToAdd.publicAddress = value.trim();
this.publicIPError = '';
}
/**
* Sets API key field from value string.
*/
public setApiKey(value: string): void {
this.nodeToAdd.apiSecret = value.trim();
this.apiKeyError = '';
}
public async onCreate(): Promise<void> {
if (this.isLoading) return;
this.isLoading = true;
if (!this.validateFields()) {
this.isLoading = false;
return;
}
try {
await this.$store.dispatch('nodes/add', this.nodeToAdd);
} catch (error) {
console.error(error.message);
this.isLoading = false;
}
await this.$router.push(RouterConfig.MyNodes.path);
}
private validateFields(): boolean {
let hasNoErrors: boolean = true;
if (!this.nodeToAdd.id) {
this.idError = 'This field is required. Please enter a valid node ID';
hasNoErrors = false;
}
if (!this.nodeToAdd.publicAddress) {
this.publicIPError = 'This field is required. Please enter a valid node Public Address';
hasNoErrors = false;
}
if (!this.nodeToAdd.apiSecret) {
this.apiKeyError = 'This field is required. Please enter a valid API Key';
hasNoErrors = false;
}
return hasNoErrors;
}
}
</script>
<style lang="scss">

View File

@ -11,7 +11,7 @@
</svg>
<h1 class="welcome-container__left-area__title">Welcome to Multinode Dashboard</h1>
<p class="welcome-container__left-area__info">This App allow Storage Node Operators to add one or multiple nodes that are under their control to a single dashboard to easily monitor combined data about storage&bandwidth usage, payouts across multiple nodes and satellites, interact with nodes config, etc.</p>
<v-button class="welcome-container__left-area__button" label="Get Started" width="155px"></v-button>
<v-button class="welcome-container__left-area__button" label="Get Started" width="155px" :on-press="redirectToAddFirstNode"></v-button>
</div>
<div class="welcome-container__right-area">
<img src="@/../static/images/Illustration.png" alt="Storj Logo Illustration">
@ -24,10 +24,16 @@ import { Component, Vue } from 'vue-property-decorator';
import VButton from '@/app/components/common/VButton.vue';
import { Config as RouterConfig } from '@/app/router';
@Component({
components: { VButton },
})
export default class WelcomeScreen extends Vue {}
export default class WelcomeScreen extends Vue {
public async redirectToAddFirstNode(): Promise<void> {
await this.$router.push(RouterConfig.AddFirstNode.path);
}
}
</script>
<style lang="scss" scoped>