Skip to content

Commit 1887c6f

Browse files
authored
Merge pull request #75 from simonhamp/feature/combinator
Feature/combinator
2 parents 7fc3386 + 183cfe7 commit 1887c6f

File tree

15 files changed

+482
-221
lines changed

15 files changed

+482
-221
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<template>
2+
<div class="border-b pb-4 space-y-4">
3+
<h4 class="text-base font-bold">Combine multiple columns</h4>
4+
5+
<p>
6+
Select any number of fields from your import file to be combined. Fields are
7+
simply concatenated. Use the <code>separator</code> field to define how they
8+
should be concatenated. If you don't choose a separator, the fields will be
9+
imported as an array.
10+
</p>
11+
12+
<SelectControl @change="(value) => rawSeparator = value" :selected="separatorOption">
13+
<option value="">- No separator -</option>
14+
<option v-for="(name, value) in separators" :value="value">{{ name }}</option>
15+
<option value="__CUSTOM__">Custom</option>
16+
</SelectControl>
17+
18+
<label v-if="rawSeparator?.startsWith('__CUSTOM__')" class="block">
19+
Custom separator
20+
<input v-model="separator" class="form-control form-input form-input-bordered mx-2">
21+
</label>
22+
23+
<draggable
24+
v-model="columns"
25+
handle=".handle"
26+
item-key="combined">
27+
28+
<template #item="{ element, index }">
29+
<div class="flex mb-2 space-x-2 items-start border-rounded bg-gray-100 p-2 handle">
30+
<div>{{ index + 1 }}</div>
31+
<SelectControl @change="(value) => columns[index] = value" :selected="columns[index]">
32+
<option value="">- Select field -</option>
33+
<option v-for="heading in headings" :value="heading">{{ heading }}</option>
34+
</SelectControl>
35+
<button @click="remove(index)">&times;</button>
36+
</div>
37+
</template>
38+
</draggable>
39+
40+
<button @click="add()"
41+
class="cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring h-7 px-1 md:px-3">
42+
Add field
43+
</button>
44+
</div>
45+
</template>
46+
47+
<script>
48+
import draggable from 'vuedraggable';
49+
50+
export default {
51+
components: {
52+
draggable,
53+
},
54+
55+
props: [
56+
'attribute',
57+
'config',
58+
'headings',
59+
],
60+
61+
data() {
62+
return {
63+
rawSeparator: '',
64+
columns: [],
65+
separators: {
66+
'__SPACE__': 'Space',
67+
'__TAB__': 'Tab',
68+
},
69+
}
70+
},
71+
72+
computed: {
73+
separator: {
74+
get() {
75+
return this.rawSeparator.replace(/__CUSTOM__\.?/, '');
76+
},
77+
set(value) {
78+
this.rawSeparator = '__CUSTOM__.' + value;
79+
}
80+
},
81+
82+
separatorOption() {
83+
return this.rawSeparator.startsWith('__CUSTOM__') ? '__CUSTOM__' : this.rawSeparator;
84+
},
85+
},
86+
87+
mounted() {
88+
this.rawSeparator = this.config?.separator || '';
89+
this.columns = this.config?.columns || [];
90+
},
91+
92+
watch: {
93+
rawSeparator: {
94+
handler() {
95+
this.update();
96+
}
97+
},
98+
99+
columns: {
100+
handler() {
101+
this.update();
102+
},
103+
deep: true,
104+
}
105+
},
106+
107+
methods: {
108+
add() {
109+
this.columns.push('');
110+
},
111+
112+
remove(index) {
113+
this.columns.splice(index, 1);
114+
},
115+
116+
update() {
117+
console.log(`Updating combinators for ${this.attribute}`, this.columns, this.rawSeparator);
118+
119+
this.$emit('update', this.attribute, {
120+
columns: this.columns,
121+
separator: this.rawSeparator,
122+
});
123+
}
124+
}
125+
}
126+
</script>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<template>
2+
<div class="space-y-4">
3+
<h4 class="text-base font-bold">Modifiers</h4>
4+
5+
<p>
6+
Use modifiers to modify the value of the source selected above <i>before</i> it gets saved to your
7+
resource. Modifiers are combinatory meaning you can stack them together to do weird and wonderful
8+
things with your data. They are executed in the order defined.
9+
</p>
10+
11+
<p>
12+
<b>TIP</b>: You can drag and drop modifiers to re-order them.
13+
</p>
14+
15+
<draggable
16+
v-model="modifiers"
17+
handle=".handle"
18+
item-key="modifier">
19+
20+
<template #item="{ element, index }">
21+
<div class="border-rounded bg-gray-100 p-2 handle mb-2">
22+
<div class="flex space-x-2 items-start">
23+
<div>{{ index + 1 }}</div>
24+
<div class="flex flex-col space-y-2">
25+
<SelectControl @change="(value) => element.name = value" :selected="element.name">
26+
<option value="">- Do not modify -</option>
27+
28+
<option v-for="mod in mods" :value="mod.name">{{ mod.title }}</option>
29+
</SelectControl>
30+
31+
<label v-for="(config, name) in mods[element.name].settings"
32+
v-if="mods[element.name]?.settings" class="flex items-center space-x-2">
33+
<span>{{ config.title }}</span>
34+
35+
<SelectControl v-if="config.type === 'select'"
36+
@change="(value) => element.settings[name] = value"
37+
:selected="element.settings[name]">
38+
<option v-for="(option, value) of config.options" :value="value"
39+
:selected="value === config.default">
40+
{{ option }}
41+
</option>
42+
</SelectControl>
43+
44+
<input type="text" v-if="config.type === 'string'" v-model="element.settings[name]"
45+
class="form-control form-input form-input-bordered ml-4" :placeholder="config.default">
46+
47+
<input type="text" v-if="config.type === 'boolean'" v-model="element.settings[name]"
48+
class="checkbox" :checked="config.default">
49+
50+
<div class="help-text" v-html="config.help"></div>
51+
</label>
52+
</div>
53+
<button @click="remove(index)">&times;</button>
54+
</div>
55+
<p v-html="mods[element.name]?.description"></p>
56+
</div>
57+
</template>
58+
</draggable>
59+
60+
<button @click="add()"
61+
class="cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring h-7 px-1 md:px-3">
62+
Add modifier
63+
</button>
64+
</div>
65+
</template>
66+
67+
<script>
68+
import draggable from 'vuedraggable';
69+
70+
export default {
71+
components: {
72+
draggable,
73+
},
74+
75+
props: [
76+
'attribute',
77+
'config',
78+
'mods',
79+
],
80+
81+
data() {
82+
return {
83+
modifiers: [],
84+
}
85+
},
86+
87+
mounted() {
88+
this.modifiers = this.config;
89+
},
90+
91+
watch: {
92+
modifiers: {
93+
handler() {
94+
this.update();
95+
},
96+
deep: true,
97+
}
98+
},
99+
100+
methods: {
101+
add() {
102+
if (Array.isArray(this.modifiers)) {
103+
this.modifiers.push(this.template());
104+
return;
105+
}
106+
107+
this.modifiers = [this.template()];
108+
},
109+
110+
remove(index) {
111+
this.modifiers.splice(index, 1);
112+
},
113+
114+
template() {
115+
return {
116+
name: '',
117+
settings: {}
118+
};
119+
},
120+
121+
update() {
122+
console.log(`Updating modifiers for ${this.attribute}`, this.modifiers);
123+
this.$emit('update', this.attribute, this.modifiers);
124+
},
125+
}
126+
}
127+
</script>

0 commit comments

Comments
 (0)