diff --git a/frontend-reactive/app/components/util/map-edit.hbs b/frontend-reactive/app/components/util/map-edit.hbs
new file mode 100644
index 0000000..3cf3845
--- /dev/null
+++ b/frontend-reactive/app/components/util/map-edit.hbs
@@ -0,0 +1,27 @@
+
+
+ {{#each this.args.list as |element index|}}
+ -
+
+
+ {{/each}}
+
+
+
+ Add element
+
+
\ No newline at end of file
diff --git a/frontend-reactive/app/components/util/map-edit.ts b/frontend-reactive/app/components/util/map-edit.ts
new file mode 100644
index 0000000..851809e
--- /dev/null
+++ b/frontend-reactive/app/components/util/map-edit.ts
@@ -0,0 +1,36 @@
+import MutableArray from '@ember/array/mutable';
+import { action } from '@ember/object';
+import Component from '@glimmer/component';
+
+export interface UtilMapEditSignature {
+ // The arguments accepted by the component
+ Args: {
+ list: MutableArray<{ key: string; value: string }>;
+ prefix: string;
+ onNewElement: (index: number) => void;
+ onDeleteElement: (index: number) => void;
+ };
+ // Any blocks yielded by the component
+ Blocks: {
+ default: [];
+ };
+ // The element to which `...attributes` is applied in the component template
+ Element: null;
+}
+
+export default class UtilMapEdit extends Component {
+ @action addElement() {
+ MutableArray.apply(this.args.list);
+ this.args.list.pushObject({ key: '', value: '' });
+ if (this.args.onNewElement)
+ this.args.onNewElement(this.args.list.length - 1);
+ }
+
+ @action removeElement(index: number) {
+ MutableArray.apply(this.args.list);
+ //let index = this.args.list.find((elem) => elem == content)
+ //let index = this.listCopy.findIndex((d) => d == content)
+ this.args.list.removeAt(index);
+ if (this.args.onDeleteElement) this.args.onDeleteElement(index);
+ }
+}
diff --git a/frontend-reactive/app/components/util/one-of-array.hbs b/frontend-reactive/app/components/util/one-of-array.hbs
new file mode 100644
index 0000000..73ebbf8
--- /dev/null
+++ b/frontend-reactive/app/components/util/one-of-array.hbs
@@ -0,0 +1,12 @@
+
+ {{#each @elements as |element|}}
+
+ {{element}}
+
+ {{/each}}
+
\ No newline at end of file
diff --git a/frontend-reactive/tests/integration/components/util/map-edit-test.ts b/frontend-reactive/tests/integration/components/util/map-edit-test.ts
new file mode 100644
index 0000000..5ed7733
--- /dev/null
+++ b/frontend-reactive/tests/integration/components/util/map-edit-test.ts
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'frontend-reactive/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | util/map-edit', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs``);
+
+ assert.dom().hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom().hasText('template block text');
+ });
+});
diff --git a/frontend-reactive/tests/integration/components/util/one-of-array-test.ts b/frontend-reactive/tests/integration/components/util/one-of-array-test.ts
new file mode 100644
index 0000000..d13b48a
--- /dev/null
+++ b/frontend-reactive/tests/integration/components/util/one-of-array-test.ts
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'frontend-reactive/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | util/one-of-array', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs``);
+
+ assert.dom().hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom().hasText('template block text');
+ });
+});