feat(ui): add survey vars to ui

This commit is contained in:
Denis Gukov 2022-01-19 00:17:48 +05:00
parent 904fa6fcc1
commit ba8ea4c650
9 changed files with 311 additions and 129 deletions

View File

@ -103,6 +103,8 @@ func findLDAPUser(username, password string) (*db.User, error) {
return &ldapUser, nil
}
// createSession creates session for passed user and stores session details
// in cookies.
func createSession(w http.ResponseWriter, r *http.Request, user db.User) {
newSession, err := helpers.Store(r).CreateSession(db.Session{
UserID: user.ID,
@ -132,6 +134,11 @@ func createSession(w http.ResponseWriter, r *http.Request, user db.User) {
})
}
// info returns information available for unauthorized user.
// Currently, this information includes field only one
// field NewUserRequired.
// Field NewUserRequired useful for creating first admin user
// just after system installation.
func info(w http.ResponseWriter, r *http.Request) {
var info struct {
NewUserRequired bool `json:"newUserRequired"`
@ -150,6 +157,7 @@ func info(w http.ResponseWriter, r *http.Request) {
helpers.WriteJSON(w, http.StatusOK, info)
}
// register replaces placeholder user with received user details.
func register(w http.ResponseWriter, r *http.Request) {
var user db.UserWithPwd
if !helpers.Bind(w, r, &user) {

View File

@ -32,8 +32,11 @@ type Task struct {
// It is readonly by API.
CommitMessage string `db:"commit_message" json:"commit_message"`
BuildTaskID *int `db:"build_task_id" json:"build_task_id"`
Version *string `db:"version" json:"version"`
BuildTaskID *int `db:"build_task_id" json:"build_task_id"`
// Version is a build version.
// This field available only for Build tasks.
Version *string `db:"version" json:"version"`
}
func (task *Task) ValidateNewTask(template Template) error {

View File

@ -46,6 +46,9 @@ type Template struct {
LastTask *TaskWithTpl `db:"-" json:"last_task"`
Autorun bool `db:"autorun" json:"-"`
// SurveyVariables must be valid JSON array.
SurveyVariables *string `db:"survey_vars" json:"survey_vars"`
}
func (tpl *Template) Validate() error {

View File

View File

@ -0,0 +1,110 @@
<template>
<div>
<v-dialog
v-model="editDialog"
hide-overlay
width="300"
>
<v-card>
<v-card-title></v-card-title>
<v-card-text class="pb-0">
<v-form v-if="editedVar != null">
<v-text-field
label="Name"
v-model="editedVar.name"
/>
<v-text-field
label="Title"
v-model="editedVar.title"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="editDialog = false"
>
Cancel
</v-btn>
<v-btn
color="blue darken-1"
text
@click="saveVar()"
>
{{ editedVarIndex == null ? 'Add' : 'Save' }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<fieldset style="padding: 0 10px 5px 10px;
border: 1px solid rgba(0, 0, 0, 0.38);
border-radius: 4px;
font-size: 12px;">
<legend style="padding: 0 3px;">Survey Variables</legend>
<v-chip-group column>
<v-chip
v-for="(v, i) in vars"
close
@click:close="deleteVar(i)"
:key="v.name"
@click="editVar(i)"
>
{{ v.title }}
</v-chip>
<v-chip @click="editVar(null)">+</v-chip>
</v-chip-group>
</fieldset>
</div>
</template>
<style lang="scss">
</style>
<script>
export default {
props: {
json: String,
},
watch: {
json(val) {
this.var = JSON.parse(val || '[]');
},
},
created() {
this.vars = JSON.parse(this.json || '[]');
},
data() {
return {
editDialog: null,
editedVar: null,
editedVarIndex: null,
vars: null,
};
},
methods: {
editVar(index) {
this.editedVar = index != null ? { ...this.vars[index] } : {};
this.editedVarIndex = index;
this.editDialog = true;
},
saveVar() {
if (this.editedVarIndex != null) {
this.vars[this.editedVarIndex] = this.editedVar;
} else {
this.vars.push(this.editedVar);
}
this.editDialog = false;
this.editVarIndex = null;
this.editedVar = null;
this.$emit('change', JSON.stringify(this.vars));
},
deleteVar(index) {
this.vars.splice(index, 1);
this.$emit('change', JSON.stringify(this.vars));
},
},
};
</script>

View File

@ -1,21 +1,21 @@
<template>
<v-form
ref="form"
lazy-validation
v-model="formValid"
v-if="isLoaded"
ref="form"
lazy-validation
v-model="formValid"
v-if="isLoaded"
>
<v-dialog
v-model="helpDialog"
hide-overlay
width="300"
v-model="helpDialog"
hide-overlay
width="300"
>
<v-alert
border="top"
colored-border
type="info"
elevation="2"
class="mb-0 pb-0"
border="top"
colored-border
type="info"
elevation="2"
class="mb-0 pb-0"
>
<div v-if="helpKey === 'build_version'">
<p>
@ -56,9 +56,9 @@
</v-dialog>
<v-alert
:value="formError"
color="error"
class="pb-2"
:value="formError"
color="error"
class="pb-2"
>{{ formError }}
</v-alert>
@ -66,13 +66,13 @@
<v-col cols="12" md="6" class="pb-0">
<v-card class="mb-6">
<v-tabs
fixed-tabs
v-model="itemTypeIndex"
fixed-tabs
v-model="itemTypeIndex"
>
<v-tab
style="padding: 0"
v-for="(key) in Object.keys(TEMPLATE_TYPE_ICONS)"
:key="key"
style="padding: 0"
v-for="(key) in Object.keys(TEMPLATE_TYPE_ICONS)"
:key="key"
>
<v-icon small class="mr-2">{{ TEMPLATE_TYPE_ICONS[key] }}</v-icon>
{{ TEMPLATE_TYPE_TITLES[key] }}
@ -81,139 +81,159 @@
<div class="ml-4 mr-4 mt-6" v-if="item.type">
<v-text-field
v-if="item.type === 'build'"
v-model="item.start_version"
label="Start Version"
:rules="[v => !!v || 'Start Version is required']"
required
:disabled="formSaving"
placeholder="Example: 0.0.0"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('build_version')"
v-if="item.type === 'build'"
v-model="item.start_version"
label="Start Version"
:rules="[v => !!v || 'Start Version is required']"
required
:disabled="formSaving"
placeholder="Example: 0.0.0"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('build_version')"
></v-text-field>
<v-select
v-if="item.type === 'deploy'"
v-model="item.build_template_id"
label="Build Template"
:items="buildTemplates"
item-value="id"
item-text="alias"
:rules="[v => !!v || 'Build Template is required']"
required
:disabled="formSaving"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('build')"
v-if="item.type === 'deploy'"
v-model="item.build_template_id"
label="Build Template"
:items="buildTemplates"
item-value="id"
item-text="alias"
:rules="[v => !!v || 'Build Template is required']"
required
:disabled="formSaving"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('build')"
></v-select>
<v-checkbox
v-if="item.type === 'deploy'"
class="mt-0"
label="Autorun"
v-model="item.autorun"
/>
</div>
</v-card>
<v-text-field
v-model="item.alias"
label="Playbook Alias"
:rules="[v => !!v || 'Playbook Alias is required']"
required
:disabled="formSaving"
v-model="item.alias"
label="Playbook Alias"
:rules="[v => !!v || 'Playbook Alias is required']"
required
:disabled="formSaving"
></v-text-field>
<v-text-field
v-model="item.playbook"
label="Playbook Filename"
:rules="[v => !!v || 'Playbook Filename is required']"
required
:disabled="formSaving"
placeholder="Example: site.yml"
v-model="item.playbook"
label="Playbook Filename"
:rules="[v => !!v || 'Playbook Filename is required']"
required
:disabled="formSaving"
placeholder="Example: site.yml"
></v-text-field>
<v-select
v-model="item.inventory_id"
label="Inventory"
:items="inventory"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Inventory is required']"
required
:disabled="formSaving"
v-model="item.inventory_id"
label="Inventory"
:items="inventory"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Inventory is required']"
required
:disabled="formSaving"
></v-select>
<v-select
v-model="item.repository_id"
label="Playbook Repository"
:items="repositories"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Playbook Repository is required']"
required
:disabled="formSaving"
v-model="item.repository_id"
label="Playbook Repository"
:items="repositories"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Playbook Repository is required']"
required
:disabled="formSaving"
></v-select>
<v-select
v-model="item.environment_id"
label="Environment"
:items="environment"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Environment is required']"
required
:disabled="formSaving"
v-model="item.environment_id"
label="Environment"
:items="environment"
item-value="id"
item-text="name"
:rules="[v => !!v || 'Environment is required']"
required
:disabled="formSaving"
></v-select>
<v-select
v-model="item.vault_key_id"
label="Vault Password"
clearable
:items="loginPasswordKeys"
item-value="id"
item-text="name"
:disabled="formSaving"
v-model="item.vault_key_id"
label="Vault Password"
clearable
:items="loginPasswordKeys"
item-value="id"
item-text="name"
:disabled="formSaving"
></v-select>
</v-col>
<v-col cols="12" md="6" class="pb-0">
<v-textarea
outlined
v-model="item.description"
label="Description"
:disabled="formSaving"
rows="5"
outlined
v-model="item.description"
label="Description"
:disabled="formSaving"
rows="5"
></v-textarea>
<codemirror
:style="{ border: '1px solid lightgray' }"
v-model="item.arguments"
:options="cmOptions"
:disabled="formSaving"
placeholder='Enter extra CLI Arguments...
Example:
[
"-i",
"@myinventory.sh",
"--private-key=/there/id_rsa",
"-vvvv"
]'
/>
<SurveyVars :json="item.survey_vars" @change="setSurveyVars"/>
<!--
<codemirror
:style="{ border: '1px solid lightgray' }"
v-model="item.arguments"
:options="cmOptions"
:disabled="formSaving"
placeholder='Enter extra CLI Arguments...
Example:
[
"-i",
"@myinventory.sh",
"--private-key=/there/id_rsa",
"-vvvv"
]'
/>
-->
<v-select
v-model="item.view_id"
label="View"
clearable
:items="views"
item-value="id"
item-text="title"
:disabled="formSaving"
v-model="item.view_id"
label="View"
clearable
:items="views"
item-value="id"
item-text="title"
:disabled="formSaving"
></v-select>
<v-text-field
class="mt-6"
v-model="cronFormat"
label="Cron"
:disabled="formSaving"
placeholder="Example: * 1 * * * *"
v-if="schedules == null || schedules.length <= 1"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('cron')"
class="mt-6"
v-model="cronFormat"
label="Cron"
:disabled="formSaving"
placeholder="Example: * 1 * * * *"
v-if="schedules == null || schedules.length <= 1"
append-outer-icon="mdi-help-circle"
@click:append-outer="showHelpDialog('cron')"
></v-text-field>
<v-select
v-model="cronRepositoryId"
label="Cron Condition Repository"
placeholder="Cron checks new commit before run"
:items="repositories"
item-value="id"
item-text="name"
:disabled="formSaving"
></v-select>
</v-col>
</v-row>
</v-form>
@ -224,18 +244,20 @@ Example:
import ItemFormBase from '@/components/ItemFormBase';
import axios from 'axios';
import { codemirror } from 'vue-codemirror';
// import { codemirror } from 'vue-codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/vue/vue.js';
// import 'codemirror/addon/lint/json-lint.js';
import 'codemirror/addon/display/placeholder.js';
import { TEMPLATE_TYPE_ICONS, TEMPLATE_TYPE_TITLES } from '../lib/constants';
import SurveyVars from './SurveyVars';
export default {
mixins: [ItemFormBase],
components: {
codemirror,
SurveyVars,
// codemirror,
},
props: {
@ -260,9 +282,11 @@ export default {
inventory: null,
repositories: null,
environment: null,
schedules: null,
views: null,
schedules: null,
cronFormat: null,
cronRepositoryId: null,
helpDialog: null,
helpKey: null,
};
@ -293,12 +317,12 @@ export default {
}
return this.keys != null
&& this.repositories != null
&& this.inventory != null
&& this.environment != null
&& this.item != null
&& this.schedules != null
&& this.views != null;
&& this.repositories != null
&& this.inventory != null
&& this.environment != null
&& this.item != null
&& this.schedules != null
&& this.views != null;
},
loginPasswordKeys() {
@ -310,6 +334,10 @@ export default {
},
methods: {
setSurveyVars(v) {
this.item.survey_vars = v;
},
showHelpDialog(key) {
this.helpKey = key;
this.helpDialog = true;

View File

@ -53,6 +53,10 @@ const routes = [
path: '/project/:projectId/views/:viewId/templates/:templateId',
component: TemplateView,
},
// {
// path: '/project/:projectId/views/:viewId/templates/:templateId/edit',
// component: TemplateEdit,
// },
{
path: '/project/:projectId/environment',
component: Environment,

View File

@ -2,7 +2,20 @@
<div v-if="items != null">
<v-toolbar flat color="white">
<v-app-bar-nav-icon @click="showDrawer()"></v-app-bar-nav-icon>
<v-toolbar-title>Dashboard</v-toolbar-title>
<v-toolbar-title>
Dashboard
<v-btn-toggle class="ml-4" rounded>
<v-btn small>
<v-icon left>mdi-view-sequential</v-icon>
<span class="hidden-sm-and-down">Tasks</span>
</v-btn>
<v-btn small>
<v-icon left>mdi-pipe</v-icon>
<span class="hidden-sm-and-down">Pipelines</span>
</v-btn>
</v-btn-toggle>
</v-toolbar-title>
<v-spacer></v-spacer>
<div>
<v-tabs centered>

View File

@ -74,7 +74,20 @@
<v-toolbar flat color="white">
<v-app-bar-nav-icon @click="showDrawer()"></v-app-bar-nav-icon>
<v-toolbar-title>Task Templates</v-toolbar-title>
<v-toolbar-title>
Task Templates
<v-btn-toggle class="ml-4" rounded>
<v-btn small>
<v-icon left>mdi-table</v-icon>
<span class="hidden-sm-and-down">Table</span>
</v-btn>
<v-btn small>
<v-icon left>mdi-pipe</v-icon>
<span class="hidden-sm-and-down">Pipelines</span>
</v-btn>
</v-btn-toggle>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
color="primary"