feat(environment): add user friendly editor for extra variables

This commit is contained in:
fiftin 2024-07-04 01:52:34 +05:00
parent e247c05cfb
commit adda0a12bc
No known key found for this signature in database
GPG Key ID: 044381366A5D4731

View File

@ -44,19 +44,73 @@
tile tile
group group
> >
<v-btn value="json" small class="mr-0" style="border-radius: 4px;" disabled> <v-btn value="table" small class="mr-0" style="border-radius: 4px;">
Table
</v-btn>
<v-btn value="json" small class="mr-0" style="border-radius: 4px;">
JSON JSON
</v-btn> </v-btn>
</v-btn-toggle> </v-btn-toggle>
</v-subheader> </v-subheader>
<codemirror <codemirror
v-if="extraVarsEditMode === 'json'"
:style="{ border: '1px solid lightgray' }" :style="{ border: '1px solid lightgray' }"
v-model="json" v-model="json"
:options="cmOptions" :options="cmOptions"
:placeholder="$t('enterExtraVariablesJson')" :placeholder="$t('enterExtraVariablesJson')"
/> />
<div v-else-if="extraVarsEditMode === 'table'">
<v-data-table
v-if="extraVars != null"
:items="extraVars"
:items-per-page="-1"
class="elevation-1"
hide-default-footer
no-data-text="No values"
>
<template v-slot:item="props">
<tr>
<td class="pa-1">
<v-text-field
solo-inverted
flat
hide-details
v-model="props.item.name"
class="v-text-field--solo--no-min-height"
></v-text-field>
</td>
<td class="pa-1">
<v-text-field
solo-inverted
flat
hide-details
v-model="props.item.value"
class="v-text-field--solo--no-min-height"
></v-text-field>
</td>
<td style="width: 38px;">
<v-icon
small
class="pa-1"
@click="removeExtraVar(props.item)"
>
mdi-delete
</v-icon>
</td>
</tr>
</template>
</v-data-table>
<div class="mt-2 mb-4 mx-1" v-if="extraVars != null">
<v-btn
color="primary"
@click="addExtraVar()"
>New Variable</v-btn>
</div>
<v-alert color="error" v-else>Can't be displayed table.</v-alert>
</div>
<div> <div>
<v-subheader class="px-0 mt-4"> <v-subheader class="px-0 mt-4">
{{ $t('environmentVariables') }} {{ $t('environmentVariables') }}
@ -202,14 +256,15 @@ import { codemirror } from 'vue-codemirror';
import 'codemirror/lib/codemirror.css'; import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/vue/vue.js'; import 'codemirror/mode/vue/vue.js';
import 'codemirror/addon/display/placeholder.js'; import 'codemirror/addon/display/placeholder.js';
import EventBus from '@/event-bus';
import { getErrorMessage } from '@/lib/error'; import { getErrorMessage } from '@/lib/error';
// import EventBus from '@/event-bus';
// import { getErrorMessage } from '@/lib/error';
const PREDEFINED_ENV_VARS = [{ // const PREDEFINED_ENV_VARS = [{
name: 'ANSIBLE_HOST_KEY_CHECKING', // name: 'ANSIBLE_HOST_KEY_CHECKING',
value: 'False', // value: 'False',
description: 'Avoid host key checking by the tools Ansible uses to connect to the host.', // description: 'Avoid host key checking by the tools Ansible uses to connect to the host.',
}]; // }];
export default { export default {
mixins: [ItemFormBase], mixins: [ItemFormBase],
@ -220,15 +275,56 @@ export default {
created() { created() {
}, },
watch: {
extraVarsEditMode(val) {
let extraVars;
switch (val) {
case 'json':
if (this.extraVars == null) {
return;
}
this.json = JSON.stringify(this.extraVars.reduce((prev, curr) => ({
...prev,
[curr.name]: curr.value,
}), {}), null, 2);
break;
case 'table':
try {
extraVars = JSON.parse(this.json);
this.formError = null;
} catch (err) {
this.formError = getErrorMessage(err);
this.extraVars = null;
return;
}
if (Object.keys(extraVars).some((x) => typeof extraVars[x] === 'object')) {
this.extraVars = null;
} else {
this.extraVars = Object.keys(extraVars)
.map((x) => ({
name: x,
value: extraVars[x],
}));
}
break;
default:
throw new Error(`Invalid extra variables edit mode: ${val}`);
}
},
},
data() { data() {
return { return {
PREDEFINED_ENV_VARS, // PREDEFINED_ENV_VARS,
images: [ images: [
'dind-runner:latest', 'dind-runner:latest',
], ],
advancedOptions: false, advancedOptions: false,
json: '{}', json: '{}',
extraVars: [],
env: [], env: [],
secrets: [], secrets: [],
@ -242,11 +338,22 @@ export default {
}, },
extraVarsEditMode: 'json', extraVarsEditMode: 'json',
predefinedEnvVars: [], // predefinedEnvVars: [],
}; };
}, },
methods: { methods: {
addExtraVar(name = '', value = '') {
this.extraVars.push({ name, value });
},
removeExtraVar(val) {
const i = this.extraVars.findIndex((v) => v.name === val.name);
if (i > -1) {
this.extraVars.splice(i, 1);
}
},
addEnvVar(name = '', value = '') { addEnvVar(name = '', value = '') {
this.env.push({ name, value }); this.env.push({ name, value });
}, },
@ -277,31 +384,51 @@ export default {
} }
}, },
setExtraVar(name, value) { // setExtraVar(name, value) {
try { // try {
const obj = JSON.parse(this.json || '{}'); // const obj = JSON.parse(this.json || '{}');
obj[name] = value; // if (value == null) {
this.json = JSON.stringify(obj, null, 2); // delete obj[name];
} catch (err) { // } else {
EventBus.$emit('i-snackbar', { // obj[name] = value;
color: 'error', // }
text: getErrorMessage(err), // this.json = JSON.stringify(obj, null, 2);
}); // } catch (err) {
} // EventBus.$emit('i-snackbar', {
}, // color: 'error',
// text: getErrorMessage(err),
// });
// }
// },
beforeSave() { beforeSave() {
switch (this.extraVarsEditMode) {
case 'json':
this.item.json = this.json; this.item.json = this.json;
break;
case 'table':
if (this.extraVars == null) {
this.item.json = this.json;
} else {
this.item.json = JSON.stringify(this.extraVars.reduce((prev, curr) => ({
...prev,
[curr.name]: curr.value,
}), {}));
}
break;
default:
throw new Error(`Invalid extra variables edit mode: ${this.extraVarsEditMode}`);
}
const env = (this.env || []).reduce((prev, curr) => ({ const env = (this.env || []).reduce((prev, curr) => ({
...prev, ...prev,
[curr.name]: curr.value, [curr.name]: curr.value,
}), {}); }), {});
this.predefinedEnvVars.forEach((index) => { // this.predefinedEnvVars.forEach((index) => {
const predefinedVar = PREDEFINED_ENV_VARS[index]; // const predefinedVar = PREDEFINED_ENV_VARS[index];
env[predefinedVar.name] = predefinedVar.value; // env[predefinedVar.name] = predefinedVar.value;
}); // });
const secrets = (this.secrets || []).map((s) => { const secrets = (this.secrets || []).map((s) => {
let operation; let operation;
@ -325,17 +452,31 @@ export default {
}, },
afterLoadData() { afterLoadData() {
this.json = this.item?.json || '{}'; this.json = JSON.stringify(JSON.parse(this.item?.json || '{}'), null, 2);
const json = JSON.parse(this.item?.json || '{}');
const env = JSON.parse(this.item?.env || '{}'); const env = JSON.parse(this.item?.env || '{}');
const secrets = this.item?.secrets || []; const secrets = this.item?.secrets || [];
if (Object.keys(json).some((x) => typeof json[x] === 'object')) {
this.extraVars = null;
this.extraVarsEditMode = 'json';
} else {
this.extraVars = Object.keys(json)
.map((x) => ({
name: x,
value: json[x],
}));
this.extraVarsEditMode = 'table';
}
this.env = Object.keys(env) this.env = Object.keys(env)
.filter((x) => { // .filter((x) => {
const index = PREDEFINED_ENV_VARS.findIndex((v) => v.name === x); // const index = PREDEFINED_ENV_VARS.findIndex((v) => v.name === x);
return index === -1 || PREDEFINED_ENV_VARS[index].value !== env[x]; // return index === -1 || PREDEFINED_ENV_VARS[index].value !== env[x];
}) // })
.map((x) => ({ .map((x) => ({
name: x, name: x,
value: env[x], value: env[x],
@ -347,12 +488,12 @@ export default {
value: '', value: '',
})); }));
Object.keys(env).forEach((x) => { // Object.keys(env).forEach((x) => {
const index = PREDEFINED_ENV_VARS.findIndex((v) => v.name === x); // const index = PREDEFINED_ENV_VARS.findIndex((v) => v.name === x);
if (index !== -1 && PREDEFINED_ENV_VARS[index].value === env[x]) { // if (index !== -1 && PREDEFINED_ENV_VARS[index].value === env[x]) {
this.predefinedEnvVars.push(index); // this.predefinedEnvVars.push(index);
} // }
}); // });
}, },
getItemsUrl() { getItemsUrl() {