mirror of
https://github.com/semaphoreui/semaphore.git
synced 2025-01-20 15:29:28 +01:00
feat(ui): add survey vars to ui
This commit is contained in:
parent
904fa6fcc1
commit
ba8ea4c650
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
0
web2/src/components/CronInput.vue
Normal file
0
web2/src/components/CronInput.vue
Normal file
110
web2/src/components/SurveyVars.vue
Normal file
110
web2/src/components/SurveyVars.vue
Normal 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>
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user