Skip to content

Commit

Permalink
♻️ : migrate new stack page
Browse files Browse the repository at this point in the history
  • Loading branch information
juwit authored and cdubuisson committed Apr 9, 2020
1 parent 2c4644b commit 40ab014
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 342 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"marked": "^0.8.0",
"messenger-hubspot": "^1.5.0",
"vue": "^2.6.11",
"vue-form-wizard": "^0.8.4",
"vue-multiselect": "^2.1.6",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
Expand Down
9 changes: 9 additions & 0 deletions src/main/client/app/pages/modules/modules-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ const modulesRoutes = [
breadcrumb: [{ text: 'Modules', to: { name: 'modules' } }, { text: 'Module description' }],
},
},
{
path: '/modules/:moduleId/run',
name: 'module-run',
component: () => import(/* webpackChunkName: "chunk-modules" */ '@/pages/stacks/stack-creation.vue'),
meta: {
authorities: ['ROLE_USER'],
breadcrumb: [{ text: 'Modules', to: { name: 'modules' } }, { text: 'Stack creation' }],
},
},
];

export default modulesRoutes;
154 changes: 153 additions & 1 deletion src/main/client/app/pages/stacks/stack-creation.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,162 @@
<template>
<div>This is not the final stack creation {{ $route.params.stackId }} page xD</div>
<div
v-if="module"
class="block"
>
<form-wizard
title="Run a new stack"
subtitle="Follow the steps to start a new stack"
color="#00ab94"
error-color="#dc3545"
>
<tab-content
title="Stack"
:before-change="checkStackNameValidation"
>
<h4>{{ module.name }}</h4>
<p>{{ module.description }}</p>

<hr>

<div class="form-group">
<b-form-group
label="Name"
description="The name of your stack"
>
<b-input
v-model="stack.name"
:state="stackNameValid"
autofocus
/>
<b-form-invalid-feedback>This field is mandatory</b-form-invalid-feedback>
</b-form-group>
<b-form-group
label="Description"
description="The description of your stack"
>
<b-input v-model="stack.description" />
</b-form-group>
</div>
</tab-content>
<tab-content
title="Variables"
:before-change="checkStackVariablesValidation"
>
<h2>Input variables</h2>
<app-stack-variable
v-for="variable in stack.variables"
:key="variable.name"
v-model="variable.value"
v-bind="variable"
@valid="(isValid) => variable.isValid = isValid"
/>
</tab-content>
<tab-content title="Start">
<h2>Run</h2>
<p>Save your stack or run it !</p>
</tab-content>

<!-- customizing save button -->
<template
slot="finish"
slot-scope="props"
>
<wizard-button
v-if="props.isLastStep"
:style="props.fillButtonStyle"
class="wizard-footer-right finish-button"
@click.native="save"
>
<font-awesome-icon icon="save" /> Save
</wizard-button>
</template>

<!-- add run button -->
<template
slot="custom-buttons-right"
slot-scope="props"
>
<wizard-button
v-if="props.isLastStep"
:style="props.fillButtonStyle"
class="wizard-footer-right finish-button ml-3"
@click.native="run"
>
<font-awesome-icon icon="rocket" /> Save and run
</wizard-button>
</template>
</form-wizard>
</div>
</template>

<script>
import axios from 'axios';
import AppStackVariable from './stack-variable.vue';
export default {
name: 'AppStackCreation',
components: {
AppStackVariable,
},
data() {
return {
module: null,
stack: null,
stacksVariablesValidated: false,
};
},
computed: {
stackNameValid() {
return typeof this.stack.name !== 'undefined' && this.stack.name !== '';
},
},
async created() {
const result = await axios.get(`/api/modules/${this.$route.params.moduleId}`);
this.module = result.data;
this.stack = {};
this.stack.moduleId = this.module.id;
this.stack.variableValues = {};
this.stack.variables = this.module.variables.map((variable) => ({
...variable,
value: variable.defaultValue || '',
isValid: true,
}));
},
methods: {
async checkStackNameValidation() {
return this.stackNameValid;
},
async checkStackVariablesValidation() {
return this.stack.variables.every((variable) => variable.isValid);
},
stackVariablesMgmt() {
this.stack.variableValues = {};
this.stack.variables.forEach((variable) => {
this.stack.variableValues[variable.name] = variable.value;
});
},
async saveStack() {
const response = await axios.post('/api/stacks', this.stack);
return response.data;
},
async save() {
this.stackVariablesMgmt();
const stack = await this.saveStack();
await this.$router.push({ path: `/stacks/${stack.id}` });
},
async run() {
this.stackVariablesMgmt();
const stack = await this.saveStack();
await this.$router.push({ path: `/stacks/${stack.id}/RUN` });
},
},
};
</script>

Expand Down
104 changes: 104 additions & 0 deletions src/main/client/app/pages/stacks/stack-variable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<b-form-group
:label="name"
:description="description"
>
<b-input
v-if="! isListRegex"
v-model="editableValue"
:state="validAndEmit().result"
trim
@input="$emit('input', editableValue)"
/>
<b-select
v-if="isListRegex"
v-model="editableValue"
:state="validAndEmit().result"
:options="listOptions"
@input="$emit('input', editableValue)"
/>
<b-form-invalid-feedback>{{ valid().message }}</b-form-invalid-feedback>
</b-form-group>
</template>

<script>
export default {
name: 'StackVariable',
props: {
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
value: {
type: String,
required: true,
},
validationRegex: {
type: String,
default: '',
},
mandatory: {
type: Boolean,
required: true,
},
},
data() {
return {
editableValue: this.value,
};
},
computed: {
isListRegex() {
const listRegex = /^\(([^|]*)(\|([^|]*))*\)$/;
return listRegex.test(this.validationRegex);
},
listOptions() {
const listExtractRegex = /[^()|]+/g;
// extracting the values from the regex
// also adding empty string to the result to be able to not select anything !
return ['', ...this.validationRegex.match(listExtractRegex)];
},
},
methods: {
validAndEmit() {
const validationResult = this.valid();
this.$emit('valid', validationResult.result !== false);
return validationResult;
},
valid() {
// no validation needed if variable is not mandatory and if no validation regex
if (!this.mandatory && !this.validationRegex) {
return { result: null };
}
// checking for empty values
if (this.editableValue === null
|| typeof this.editableValue === 'undefined'
|| this.editableValue.trim().length === 0) {
// mandatory variables cannot be empty
if (this.mandatory) {
return { result: false, message: 'This field is mandatory' };
}
// stop checks is fields is empty
return { result: null };
}
// check regex if defined
if (this.validationRegex) {
if (!new RegExp(this.validationRegex).test(this.editableValue)) {
return { result: false, message: `This field must match the regex ${this.validationRegex}` };
}
}
return { result: true };
},
},
};
</script>
9 changes: 0 additions & 9 deletions src/main/client/app/pages/stacks/stacks-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ const stacksRoutes = [
breadcrumb: [{ text: 'Stacks', to: { name: 'stacks' } }, { text: 'Stack' }],
},
children: [
{
path: 'add',
name: 'stack_creation',
component: () => import(/* webpackChunkName: "chunk-stacks" */ '@/pages/stacks/stack-creation.vue'),
meta: {
authorities: ['ROLE_USER'],
breadcrumb: [{ text: 'Modules', to: { name: 'modules' } }, { text: 'Stack creation' }],
},
},
{
path: 'edit',
name: 'stack_edition',
Expand Down
5 changes: 5 additions & 0 deletions src/main/client/app/shared/config/bootstrap-vue-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import {
} from 'bootstrap-vue';
import { Multiselect } from 'vue-multiselect';

import VueFormWizard from 'vue-form-wizard';
import 'vue-form-wizard/dist/vue-form-wizard.min.css';

export default {
init: () => {
Vue.use(ButtonPlugin);
Expand All @@ -38,6 +41,8 @@ export default {
Vue.use(NavPlugin);
Vue.use(BreadcrumbPlugin);

Vue.use(VueFormWizard);

Vue.component('vue-multiselect', Multiselect);
},
};

0 comments on commit 40ab014

Please sign in to comment.