summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_wizard/components/input.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipeline_wizard/components/input.vue')
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/input.vue99
1 files changed, 99 insertions, 0 deletions
diff --git a/app/assets/javascripts/pipeline_wizard/components/input.vue b/app/assets/javascripts/pipeline_wizard/components/input.vue
new file mode 100644
index 00000000000..9a0c8026648
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/components/input.vue
@@ -0,0 +1,99 @@
+<script>
+import { isNode, isDocument, isSeq, visit } from 'yaml';
+import { capitalize } from 'lodash';
+import TextWidget from '~/pipeline_wizard/components/widgets/text.vue';
+import ListWidget from '~/pipeline_wizard/components/widgets/list.vue';
+
+const widgets = {
+ TextWidget,
+ ListWidget,
+};
+
+function isNullOrUndefined(v) {
+ return [undefined, null].includes(v);
+}
+
+export default {
+ components: {
+ ...widgets,
+ },
+ props: {
+ template: {
+ type: Object,
+ required: true,
+ validator: (v) => isNode(v),
+ },
+ compiled: {
+ type: Object,
+ required: true,
+ validator: (v) => isDocument(v) || isNode(v),
+ },
+ target: {
+ type: String,
+ required: true,
+ validator: (v) => /^\$.*/g.test(v),
+ },
+ widget: {
+ type: String,
+ required: true,
+ validator: (v) => {
+ return Object.keys(widgets).includes(`${capitalize(v)}Widget`);
+ },
+ },
+ validate: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ path() {
+ let res;
+ visit(this.template, (seqKey, node, path) => {
+ if (node && node.value === this.target) {
+ // `path` is an array of objects (all the node's parents)
+ // So this reducer will reduce it to an array of the path's keys,
+ // e.g. `[ 'foo', 'bar', '0' ]`
+ res = path.reduce((p, { key }) => (key ? [...p, `${key}`] : p), []);
+ const parent = path[path.length - 1];
+ if (isSeq(parent)) {
+ res.push(seqKey);
+ }
+ }
+ });
+ return res;
+ },
+ },
+ methods: {
+ compile(v) {
+ if (!this.path) return;
+ if (isNullOrUndefined(v)) {
+ this.compiled.deleteIn(this.path);
+ }
+ this.compiled.setIn(this.path, v);
+ },
+ onModelChange(v) {
+ this.$emit('beforeUpdate:compiled');
+ this.compile(v);
+ this.$emit('update:compiled', this.compiled);
+ this.$emit('highlight', this.path);
+ },
+ onValidationStateChange(v) {
+ this.$emit('update:valid', v);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <component
+ :is="`${widget}-widget`"
+ ref="widget"
+ :validate="validate"
+ v-bind="$attrs"
+ @input="onModelChange"
+ @update:valid="onValidationStateChange"
+ />
+ </div>
+</template>